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