1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <fcntl.h> 6 #include <poll.h> 7 #include <signal.h> 8 #include <stdio.h> 9 #include <sys/resource.h> 10 #include <sys/time.h> 11 #include <time.h> 12 #include <unistd.h> 13 14 #include "base/debug/leak_annotations.h" 15 #include "base/files/file_util.h" 16 #include "base/posix/eintr_wrapper.h" 17 #include "base/third_party/valgrind/valgrind.h" 18 #include "build/build_config.h" 19 #include "sandbox/linux/tests/unit_tests.h" 20 21 namespace { 22 std::string TestFailedMessage(const std::string& msg) { 23 return msg.empty() ? std::string() : "Actual test failure: " + msg; 24 } 25 26 int GetSubProcessTimeoutTimeInSeconds() { 27 // 10s ought to be enough for anybody. 28 return 10; 29 } 30 31 // Returns the number of threads of the current process or -1. 32 int CountThreads() { 33 struct stat task_stat; 34 int task_d = stat("/proc/self/task", &task_stat); 35 // task_stat.st_nlink should be the number of tasks + 2 (accounting for 36 // "." and "..". 37 if (task_d != 0 || task_stat.st_nlink < 3) 38 return -1; 39 const int num_threads = task_stat.st_nlink - 2; 40 return num_threads; 41 } 42 43 } // namespace 44 45 namespace sandbox { 46 47 bool IsAndroid() { 48 #if defined(OS_ANDROID) 49 return true; 50 #else 51 return false; 52 #endif 53 } 54 55 bool IsArchitectureArm() { 56 #if defined(ARCH_CPU_ARM_FAMILY) 57 return true; 58 #else 59 return false; 60 #endif 61 } 62 63 // TODO(jln): figure out why base/.../dynamic_annotations.h's 64 // RunningOnValgrind() cannot link. 65 bool IsRunningOnValgrind() { return RUNNING_ON_VALGRIND; } 66 67 static const int kExpectedValue = 42; 68 static const int kIgnoreThisTest = 43; 69 static const int kExitWithAssertionFailure = 1; 70 static const int kExitForTimeout = 2; 71 72 #if !defined(OS_ANDROID) 73 // This is due to StackDumpSignalHandler() performing _exit(1). 74 // TODO(jln): get rid of the collision with kExitWithAssertionFailure. 75 const int kExitAfterSIGSEGV = 1; 76 #endif 77 78 static void SigAlrmHandler(int) { 79 const char failure_message[] = "Timeout reached!\n"; 80 // Make sure that we never block here. 81 if (!fcntl(2, F_SETFL, O_NONBLOCK)) { 82 ignore_result(write(2, failure_message, sizeof(failure_message) - 1)); 83 } 84 _exit(kExitForTimeout); 85 } 86 87 // Set a timeout with a handler that will automatically fail the 88 // test. 89 static void SetProcessTimeout(int time_in_seconds) { 90 struct sigaction act = {}; 91 act.sa_handler = SigAlrmHandler; 92 SANDBOX_ASSERT(sigemptyset(&act.sa_mask) == 0); 93 act.sa_flags = 0; 94 95 struct sigaction old_act; 96 SANDBOX_ASSERT(sigaction(SIGALRM, &act, &old_act) == 0); 97 98 // We don't implemenet signal chaining, so make sure that nothing else 99 // is expecting to handle SIGALRM. 100 SANDBOX_ASSERT((old_act.sa_flags & SA_SIGINFO) == 0); 101 SANDBOX_ASSERT(old_act.sa_handler == SIG_DFL); 102 sigset_t sigalrm_set; 103 SANDBOX_ASSERT(sigemptyset(&sigalrm_set) == 0); 104 SANDBOX_ASSERT(sigaddset(&sigalrm_set, SIGALRM) == 0); 105 SANDBOX_ASSERT(sigprocmask(SIG_UNBLOCK, &sigalrm_set, NULL) == 0); 106 SANDBOX_ASSERT(alarm(time_in_seconds) == 0); // There should be no previous 107 // alarm. 108 } 109 110 // Runs a test in a sub-process. This is necessary for most of the code 111 // in the BPF sandbox, as it potentially makes global state changes and as 112 // it also tends to raise fatal errors, if the code has been used in an 113 // insecure manner. 114 void UnitTests::RunTestInProcess(SandboxTestRunner* test_runner, 115 DeathCheck death, 116 const void* death_aux) { 117 CHECK(test_runner); 118 // We need to fork(), so we can't be multi-threaded, as threads could hold 119 // locks. 120 int num_threads = CountThreads(); 121 #if !defined(THREAD_SANITIZER) 122 const int kNumExpectedThreads = 1; 123 #else 124 // Under TSAN, there is a special helper thread. It should be completely 125 // invisible to our testing, so we ignore it. It should be ok to fork() 126 // with this thread. It's currently buggy, but it's the best we can do until 127 // there is a way to delay the start of the thread 128 // (https://code.google.com/p/thread-sanitizer/issues/detail?id=19). 129 const int kNumExpectedThreads = 2; 130 #endif 131 132 // The kernel is at liberty to wake a thread id futex before updating /proc. 133 // If another test running in the same process has stopped a thread, it may 134 // appear as still running in /proc. 135 // We poll /proc, with an exponential back-off. At most, we'll sleep around 136 // 2^iterations nanoseconds in nanosleep(). 137 for (unsigned int iteration = 0; iteration < 30; iteration++) { 138 struct timespec ts = {0, 1L << iteration /* nanoseconds */}; 139 PCHECK(0 == HANDLE_EINTR(nanosleep(&ts, &ts))); 140 num_threads = CountThreads(); 141 if (kNumExpectedThreads == num_threads) 142 break; 143 } 144 145 ASSERT_EQ(kNumExpectedThreads, num_threads) 146 << "Running sandbox tests with multiple threads " 147 << "is not supported and will make the tests flaky."; 148 int fds[2]; 149 ASSERT_EQ(0, pipe(fds)); 150 // Check that our pipe is not on one of the standard file descriptor. 151 SANDBOX_ASSERT(fds[0] > 2 && fds[1] > 2); 152 153 pid_t pid; 154 ASSERT_LE(0, (pid = fork())); 155 if (!pid) { 156 // In child process 157 // Redirect stderr to our pipe. This way, we can capture all error 158 // messages, if we decide we want to do so in our tests. 159 SANDBOX_ASSERT(dup2(fds[1], 2) == 2); 160 SANDBOX_ASSERT(!close(fds[0])); 161 SANDBOX_ASSERT(!close(fds[1])); 162 163 // Don't set a timeout if running on Valgrind, since it's generally much 164 // slower. 165 if (!IsRunningOnValgrind()) { 166 SetProcessTimeout(GetSubProcessTimeoutTimeInSeconds()); 167 } 168 169 // Disable core files. They are not very useful for our individual test 170 // cases. 171 struct rlimit no_core = {0}; 172 setrlimit(RLIMIT_CORE, &no_core); 173 174 test_runner->Run(); 175 if (test_runner->ShouldCheckForLeaks()) { 176 #if defined(LEAK_SANITIZER) 177 __lsan_do_leak_check(); 178 #endif 179 } 180 _exit(kExpectedValue); 181 } 182 183 close(fds[1]); 184 std::vector<char> msg_buf; 185 ssize_t rc; 186 187 // Make sure read() will never block as we'll use poll() to 188 // block with a timeout instead. 189 const int fcntl_ret = fcntl(fds[0], F_SETFL, O_NONBLOCK); 190 ASSERT_EQ(0, fcntl_ret); 191 struct pollfd poll_fd = {fds[0], POLLIN | POLLRDHUP, 0}; 192 193 int poll_ret; 194 // We prefer the SIGALRM timeout to trigger in the child than this timeout 195 // so we double the common value here. 196 int poll_timeout = GetSubProcessTimeoutTimeInSeconds() * 2 * 1000; 197 while ((poll_ret = poll(&poll_fd, 1, poll_timeout) > 0)) { 198 const size_t kCapacity = 256; 199 const size_t len = msg_buf.size(); 200 msg_buf.resize(len + kCapacity); 201 rc = HANDLE_EINTR(read(fds[0], &msg_buf[len], kCapacity)); 202 msg_buf.resize(len + std::max(rc, static_cast<ssize_t>(0))); 203 if (rc <= 0) 204 break; 205 } 206 ASSERT_NE(poll_ret, -1) << "poll() failed"; 207 ASSERT_NE(poll_ret, 0) << "Timeout while reading child state"; 208 close(fds[0]); 209 std::string msg(msg_buf.begin(), msg_buf.end()); 210 211 int status = 0; 212 int waitpid_returned = HANDLE_EINTR(waitpid(pid, &status, 0)); 213 ASSERT_EQ(pid, waitpid_returned) << TestFailedMessage(msg); 214 215 // At run-time, we sometimes decide that a test shouldn't actually 216 // run (e.g. when testing sandbox features on a kernel that doesn't 217 // have sandboxing support). When that happens, don't attempt to 218 // call the "death" function, as it might be looking for a 219 // death-test condition that would never have triggered. 220 if (!WIFEXITED(status) || WEXITSTATUS(status) != kIgnoreThisTest || 221 !msg.empty()) { 222 // We use gtest's ASSERT_XXX() macros instead of the DeathCheck 223 // functions. This means, on failure, "return" is called. This 224 // only works correctly, if the call of the "death" callback is 225 // the very last thing in our function. 226 death(status, msg, death_aux); 227 } 228 } 229 230 void UnitTests::DeathSuccess(int status, const std::string& msg, const void*) { 231 std::string details(TestFailedMessage(msg)); 232 233 bool subprocess_terminated_normally = WIFEXITED(status); 234 ASSERT_TRUE(subprocess_terminated_normally) << details; 235 int subprocess_exit_status = WEXITSTATUS(status); 236 ASSERT_EQ(kExpectedValue, subprocess_exit_status) << details; 237 bool subprocess_exited_but_printed_messages = !msg.empty(); 238 EXPECT_FALSE(subprocess_exited_but_printed_messages) << details; 239 } 240 241 void UnitTests::DeathSuccessAllowNoise(int status, 242 const std::string& msg, 243 const void*) { 244 std::string details(TestFailedMessage(msg)); 245 246 bool subprocess_terminated_normally = WIFEXITED(status); 247 ASSERT_TRUE(subprocess_terminated_normally) << details; 248 int subprocess_exit_status = WEXITSTATUS(status); 249 ASSERT_EQ(kExpectedValue, subprocess_exit_status) << details; 250 } 251 252 void UnitTests::DeathMessage(int status, 253 const std::string& msg, 254 const void* aux) { 255 std::string details(TestFailedMessage(msg)); 256 const char* expected_msg = static_cast<const char*>(aux); 257 258 bool subprocess_terminated_normally = WIFEXITED(status); 259 ASSERT_TRUE(subprocess_terminated_normally) << "Exit status: " << status 260 << " " << details; 261 int subprocess_exit_status = WEXITSTATUS(status); 262 ASSERT_EQ(1, subprocess_exit_status) << details; 263 264 bool subprocess_exited_without_matching_message = 265 msg.find(expected_msg) == std::string::npos; 266 EXPECT_FALSE(subprocess_exited_without_matching_message) << details; 267 } 268 269 void UnitTests::DeathSEGVMessage(int status, 270 const std::string& msg, 271 const void* aux) { 272 std::string details(TestFailedMessage(msg)); 273 const char* expected_msg = static_cast<const char*>(aux); 274 275 #if defined(OS_ANDROID) 276 const bool subprocess_got_sigsegv = 277 WIFSIGNALED(status) && (SIGSEGV == WTERMSIG(status)); 278 #else 279 const bool subprocess_got_sigsegv = 280 WIFEXITED(status) && (kExitAfterSIGSEGV == WEXITSTATUS(status)); 281 #endif 282 283 ASSERT_TRUE(subprocess_got_sigsegv) << "Exit status: " << status 284 << " " << details; 285 286 bool subprocess_exited_without_matching_message = 287 msg.find(expected_msg) == std::string::npos; 288 EXPECT_FALSE(subprocess_exited_without_matching_message) << details; 289 } 290 291 void UnitTests::DeathExitCode(int status, 292 const std::string& msg, 293 const void* aux) { 294 int expected_exit_code = static_cast<int>(reinterpret_cast<intptr_t>(aux)); 295 std::string details(TestFailedMessage(msg)); 296 297 bool subprocess_terminated_normally = WIFEXITED(status); 298 ASSERT_TRUE(subprocess_terminated_normally) << details; 299 int subprocess_exit_status = WEXITSTATUS(status); 300 ASSERT_EQ(expected_exit_code, subprocess_exit_status) << details; 301 } 302 303 void UnitTests::DeathBySignal(int status, 304 const std::string& msg, 305 const void* aux) { 306 int expected_signo = static_cast<int>(reinterpret_cast<intptr_t>(aux)); 307 std::string details(TestFailedMessage(msg)); 308 309 bool subprocess_terminated_by_signal = WIFSIGNALED(status); 310 ASSERT_TRUE(subprocess_terminated_by_signal) << details; 311 int subprocess_signal_number = WTERMSIG(status); 312 ASSERT_EQ(expected_signo, subprocess_signal_number) << details; 313 } 314 315 void UnitTests::AssertionFailure(const char* expr, const char* file, int line) { 316 fprintf(stderr, "%s:%d:%s", file, line, expr); 317 fflush(stderr); 318 _exit(kExitWithAssertionFailure); 319 } 320 321 void UnitTests::IgnoreThisTest() { 322 fflush(stderr); 323 _exit(kIgnoreThisTest); 324 } 325 326 } // namespace 327