• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <fcntl.h>
18 #include <signal.h>
19 #include <stdint.h>
20 #include <sys/prctl.h>
21 #include <sys/stat.h>
22 #include <sys/types.h>
23 #include <sys/wait.h>
24 #include <unistd.h>
25 
26 #include <chrono>
27 #include <iostream>
28 #include <string>
29 
30 #include <android-base/properties.h>
31 #include <gtest/gtest.h>
32 #include <log/log_time.h>  // for MS_PER_SEC and US_PER_SEC
33 
34 #include "llkd.h"
35 
36 using namespace std::chrono;
37 using namespace std::chrono_literals;
38 
39 namespace {
40 
GetUintProperty(const std::string & key,milliseconds def)41 milliseconds GetUintProperty(const std::string& key, milliseconds def) {
42     return milliseconds(android::base::GetUintProperty(key, static_cast<uint64_t>(def.count()),
43                                                        static_cast<uint64_t>(def.max().count())));
44 }
45 
GetUintProperty(const std::string & key,seconds def)46 seconds GetUintProperty(const std::string& key, seconds def) {
47     return seconds(android::base::GetUintProperty(key, static_cast<uint64_t>(def.count()),
48                                                   static_cast<uint64_t>(def.max().count())));
49 }
50 
51 // GTEST_LOG_(WARNING) output is fugly, this has much less noise
52 // ToDo: look into fixing googletest to produce output that matches style of
53 //       all the other status messages, and can switch off __line__ and
54 //       __function__ noise
55 #define GTEST_LOG_WARNING std::cerr << "[ WARNING  ] "
56 #define GTEST_LOG_INFO std::cerr << "[   INFO   ] "
57 
58 // Properties is _not_ a high performance ABI!
rest()59 void rest() {
60     usleep(200000);
61 }
62 
execute(const char * command)63 void execute(const char* command) {
64     if (getuid() || system(command)) {
65         system((std::string("su root ") + command).c_str());
66     }
67 }
68 
llkdSleepPeriod(char state)69 seconds llkdSleepPeriod(char state) {
70     auto default_eng = android::base::GetProperty(LLK_ENABLE_PROPERTY, "eng") == "eng";
71     auto default_enable = LLK_ENABLE_DEFAULT;
72     default_enable = android::base::GetBoolProperty(LLK_ENABLE_PROPERTY, default_enable);
73     if (default_eng) {
74         GTEST_LOG_INFO << LLK_ENABLE_PROPERTY " defaults to "
75                        << (default_enable ? "true" : "false") << "\n";
76     }
77     // Hail Mary hope is unconfigured.
78     if ((GetUintProperty(LLK_TIMEOUT_MS_PROPERTY, LLK_TIMEOUT_MS_DEFAULT) !=
79          duration_cast<milliseconds>(120s)) ||
80         (GetUintProperty(LLK_CHECK_MS_PROPERTY,
81                          LLK_TIMEOUT_MS_DEFAULT / LLK_CHECKS_PER_TIMEOUT_DEFAULT) !=
82          duration_cast<milliseconds>(10s))) {
83         execute("stop llkd-0");
84         execute("stop llkd-1");
85         rest();
86         std::string setprop("setprop ");
87         // Manually check that SyS_openat is _added_ to the list when restarted
88         // 4.19+ kernels report __arm64_sys_openat b/147486902
89         execute((setprop + LLK_CHECK_STACK_PROPERTY + " ,SyS_openat,__arm64_sys_openat").c_str());
90         rest();
91         execute((setprop + LLK_ENABLE_WRITEABLE_PROPERTY + " false").c_str());
92         rest();
93         execute((setprop + LLK_TIMEOUT_MS_PROPERTY + " 120000").c_str());
94         rest();
95         execute((setprop + KHT_TIMEOUT_PROPERTY + " 130").c_str());
96         rest();
97         execute((setprop + LLK_CHECK_MS_PROPERTY + " 10000").c_str());
98         rest();
99         if (!default_enable) {
100             execute((setprop + LLK_ENABLE_PROPERTY + " true").c_str());
101             rest();
102         }
103         execute((setprop + LLK_ENABLE_WRITEABLE_PROPERTY + " true").c_str());
104         rest();
105     }
106     default_enable = LLK_ENABLE_DEFAULT;
107     default_enable = android::base::GetBoolProperty(LLK_ENABLE_PROPERTY, default_enable);
108     if (default_enable) {
109         execute("start llkd-1");
110         rest();
111         GTEST_LOG_INFO << "llkd enabled\n";
112     } else {
113         GTEST_LOG_WARNING << "llkd disabled\n";
114     }
115 
116     /* KISS follows llk_init() */
117     milliseconds llkTimeoutMs = LLK_TIMEOUT_MS_DEFAULT;
118     seconds khtTimeout = duration_cast<seconds>(
119         llkTimeoutMs * (1 + LLK_CHECKS_PER_TIMEOUT_DEFAULT) / LLK_CHECKS_PER_TIMEOUT_DEFAULT);
120     khtTimeout = GetUintProperty(KHT_TIMEOUT_PROPERTY, khtTimeout);
121     llkTimeoutMs =
122         khtTimeout * LLK_CHECKS_PER_TIMEOUT_DEFAULT / (1 + LLK_CHECKS_PER_TIMEOUT_DEFAULT);
123     llkTimeoutMs = GetUintProperty(LLK_TIMEOUT_MS_PROPERTY, llkTimeoutMs);
124     if (llkTimeoutMs < LLK_TIMEOUT_MS_MINIMUM) {
125         llkTimeoutMs = LLK_TIMEOUT_MS_MINIMUM;
126     }
127     milliseconds llkCheckMs = llkTimeoutMs / LLK_CHECKS_PER_TIMEOUT_DEFAULT;
128     auto timeout = GetUintProperty((state == 'Z') ? LLK_Z_TIMEOUT_MS_PROPERTY
129                                                   : (state == 'S') ? LLK_STACK_TIMEOUT_MS_PROPERTY
130                                                                    : LLK_D_TIMEOUT_MS_PROPERTY,
131                                    llkTimeoutMs);
132     if (timeout < LLK_TIMEOUT_MS_MINIMUM) {
133         timeout = LLK_TIMEOUT_MS_MINIMUM;
134     }
135 
136     if (llkCheckMs > timeout) {
137         llkCheckMs = timeout;
138     }
139     llkCheckMs = GetUintProperty(LLK_CHECK_MS_PROPERTY, llkCheckMs);
140     timeout += llkCheckMs;
141     auto sec = duration_cast<seconds>(timeout);
142     if (sec == 0s) {
143         ++sec;
144     } else if (sec > 59s) {
145         GTEST_LOG_WARNING << "llkd is configured for about " << duration_cast<minutes>(sec).count()
146                           << " minutes to react\n";
147     }
148 
149     // 33% margin for the test to naturally timeout waiting for llkd to respond
150     return (sec * 4 + 2s) / 3;
151 }
152 
waitForPid(pid_t child_pid)153 inline void waitForPid(pid_t child_pid) {
154     int wstatus;
155     ASSERT_LE(0, waitpid(child_pid, &wstatus, 0));
156     EXPECT_FALSE(WIFEXITED(wstatus)) << "[   INFO   ] exit=" << WEXITSTATUS(wstatus);
157     ASSERT_TRUE(WIFSIGNALED(wstatus));
158     ASSERT_EQ(WTERMSIG(wstatus), SIGKILL);
159 }
160 
checkKill(const char * reason)161 bool checkKill(const char* reason) {
162     if (android::base::GetBoolProperty(LLK_KILLTEST_PROPERTY, LLK_KILLTEST_DEFAULT)) {
163         return false;
164     }
165     auto bootreason = android::base::GetProperty("sys.boot.reason", "nothing");
166     if (bootreason == reason) {
167         GTEST_LOG_INFO << "Expected test result confirmed " << reason << "\n";
168         return true;
169     }
170     GTEST_LOG_WARNING << "Expected test result is " << reason << "\n";
171 
172     // apct adjustment if needed (set LLK_KILLTEST_PROPERTY to "off" to allow test)
173     //
174     // if (android::base::GetProperty(LLK_KILLTEST_PROPERTY, "") == "false") {
175     //     GTEST_LOG_WARNING << "Bypassing test\n";
176     //     return true;
177     // }
178 
179     return false;
180 }
181 
182 }  // namespace
183 
184 // The tests that use this helper are to simulate processes stuck in 'D'
185 // state that are experiencing forward scheduled progress. As such the
186 // expectation is that llkd will _not_ perform any mitigations. The sleepfor
187 // argument helps us set the amount of forward scheduler progress.
llkd_driver_ABA(const microseconds sleepfor)188 static void llkd_driver_ABA(const microseconds sleepfor) {
189     const auto period = llkdSleepPeriod('D');
190     if (period <= sleepfor) {
191         GTEST_LOG_WARNING << "llkd configuration too short for "
192                           << duration_cast<milliseconds>(sleepfor).count() << "ms work cycle\n";
193         return;
194     }
195 
196     auto child_pid = fork();
197     ASSERT_LE(0, child_pid);
198     int wstatus;
199     if (!child_pid) {
200         auto ratio = period / sleepfor;
201         ASSERT_LT(0, ratio);
202         // vfork() parent is uninterruptable D state waiting for child to exec()
203         while (--ratio > 0) {
204             auto driver_pid = vfork();
205             ASSERT_LE(0, driver_pid);
206             if (driver_pid) {  // parent
207                 waitpid(driver_pid, &wstatus, 0);
208                 if (!WIFEXITED(wstatus)) {
209                     exit(42);
210                 }
211                 if (WEXITSTATUS(wstatus) != 42) {
212                     exit(42);
213                 }
214             } else {
215                 usleep(sleepfor.count());
216                 exit(42);
217             }
218         }
219         exit(0);
220     }
221     ASSERT_LE(0, waitpid(child_pid, &wstatus, 0));
222     EXPECT_TRUE(WIFEXITED(wstatus));
223     if (WIFEXITED(wstatus)) {
224         EXPECT_EQ(0, WEXITSTATUS(wstatus));
225     }
226     ASSERT_FALSE(WIFSIGNALED(wstatus)) << "[   INFO   ] signo=" << WTERMSIG(wstatus);
227 }
228 
TEST(llkd,driver_ABA_fast)229 TEST(llkd, driver_ABA_fast) {
230     llkd_driver_ABA(5ms);
231 }
232 
TEST(llkd,driver_ABA_slow)233 TEST(llkd, driver_ABA_slow) {
234     llkd_driver_ABA(1s);
235 }
236 
TEST(llkd,driver_ABA_glacial)237 TEST(llkd, driver_ABA_glacial) {
238     llkd_driver_ABA(1min);
239 }
240 
241 // Following tests must be last in this file to capture possible errant
242 // kernel_panic mitigation failure.
243 
244 // The following tests simulate processes stick in 'Z' or 'D' state with
245 // no forward scheduling progress, but interruptible. As such the expectation
246 // is that llkd will perform kill mitigation and not progress to kernel_panic.
247 
TEST(llkd,zombie)248 TEST(llkd, zombie) {
249     if (checkKill("kernel_panic,sysrq,livelock,zombie")) {
250         return;
251     }
252 
253     const auto period = llkdSleepPeriod('Z');
254 
255     /* Create a Persistent Zombie Process */
256     pid_t child_pid = fork();
257     ASSERT_LE(0, child_pid);
258     if (!child_pid) {
259         auto zombie_pid = fork();
260         ASSERT_LE(0, zombie_pid);
261         if (!zombie_pid) {
262             sleep(1);
263             exit(0);
264         }
265         sleep(period.count());
266         exit(42);
267     }
268 
269     waitForPid(child_pid);
270 }
271 
TEST(llkd,driver)272 TEST(llkd, driver) {
273     if (checkKill("kernel_panic,sysrq,livelock,driver")) {
274         return;
275     }
276 
277     const auto period = llkdSleepPeriod('D');
278 
279     /* Create a Persistent Device Process */
280     auto child_pid = fork();
281     ASSERT_LE(0, child_pid);
282     if (!child_pid) {
283         // vfork() parent is uninterruptable D state waiting for child to exec()
284         auto driver_pid = vfork();
285         ASSERT_LE(0, driver_pid);
286         sleep(period.count());
287         exit(driver_pid ? 42 : 0);
288     }
289 
290     waitForPid(child_pid);
291 }
292 
TEST(llkd,sleep)293 TEST(llkd, sleep) {
294     if (checkKill("kernel_panic,sysrq,livelock,sleeping")) {
295         return;
296     }
297     if (!android::base::GetBoolProperty("ro.debuggable", false)) {
298         GTEST_LOG_WARNING << "Features not available on user builds\n";
299     }
300 
301     const auto period = llkdSleepPeriod('S');
302 
303     /* Create a Persistent SyS_openat for single-ended pipe */
304     static constexpr char stack_pipe_file[] = "/dev/stack_pipe_file";
305     unlink(stack_pipe_file);
306     auto pipe_ret = mknod(stack_pipe_file, S_IFIFO | 0666, 0);
307     ASSERT_LE(0, pipe_ret);
308 
309     auto child_pid = fork();
310     ASSERT_LE(0, child_pid);
311     if (!child_pid) {
312         child_pid = fork();
313         ASSERT_LE(0, child_pid);
314         if (!child_pid) {
315             sleep(period.count());
316             auto fd = open(stack_pipe_file, O_RDONLY | O_CLOEXEC);
317             close(fd);
318             exit(0);
319         } else {
320             auto fd = open(stack_pipe_file, O_WRONLY | O_CLOEXEC);
321             close(fd);
322             exit(42);
323         }
324     }
325 
326     waitForPid(child_pid);
327 
328     unlink(stack_pipe_file);
329 }
330 
331 // b/120983740
TEST(llkd,adbd_and_setsid)332 TEST(llkd, adbd_and_setsid) {
333     if (checkKill("kernel_panic,sysrq,livelock,zombie")) {
334         return;
335     }
336     const auto period = llkdSleepPeriod('S');
337 
338     // expect llkd.zombie to trigger, but not for adbd&[setsid]
339     // Create a Persistent Zombie setsid Process
340     pid_t child_pid = fork();
341     ASSERT_LE(0, child_pid);
342     if (!child_pid) {
343         prctl(PR_SET_NAME, "adbd");
344         auto zombie_pid = fork();
345         ASSERT_LE(0, zombie_pid);
346         if (!zombie_pid) {
347             prctl(PR_SET_NAME, "setsid");
348             sleep(1);
349             exit(0);
350         }
351         sleep(period.count());
352         exit(42);
353     }
354 
355     // Reverse of waitForPid, do _not_ expect kill
356     int wstatus;
357     ASSERT_LE(0, waitpid(child_pid, &wstatus, 0));
358     EXPECT_TRUE(WIFEXITED(wstatus));
359     if (WIFEXITED(wstatus)) {
360         EXPECT_EQ(42, WEXITSTATUS(wstatus));
361     }
362     ASSERT_FALSE(WIFSIGNALED(wstatus)) << "[   INFO   ] signo=" << WTERMSIG(wstatus);
363 }
364