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