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.
9 #include <sys/resource.h>
10 #include <sys/types.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
29 std::string
TestFailedMessage(const std::string
& msg
) {
30 return msg
.empty() ? std::string() : "Actual test failure: " + msg
;
33 int GetSubProcessTimeoutTimeInSeconds() {
34 // Previously 10s, but that timed out (just) on Chromecast.
38 // Returns the number of threads of the current process or -1.
40 struct stat task_stat
;
41 int task_d
= stat("/proc/self/task", &task_stat
);
42 // task_stat.st_nlink should be the number of tasks + 2 (accounting for
44 if (task_d
!= 0 || task_stat
.st_nlink
< 3)
46 const int num_threads
= task_stat
.st_nlink
- 2;
55 #if defined(OS_ANDROID)
62 bool IsArchitectureArm() {
63 #if defined(ARCH_CPU_ARM_FAMILY)
70 // TODO(jln): figure out why base/.../dynamic_annotations.h's
71 // RunningOnValgrind() cannot link.
72 bool IsRunningOnValgrind() { return RUNNING_ON_VALGRIND
; }
74 static const int kExpectedValue
= 42;
75 static const int kIgnoreThisTest
= 43;
76 static const int kExitWithAssertionFailure
= 1;
77 #if !defined(OS_NACL_NONSFI)
78 static const int kExitForTimeout
= 2;
81 #if defined(SANDBOX_USES_BASE_TEST_SUITE)
82 // This is due to StackDumpSignalHandler() performing _exit(1).
83 // TODO(jln): get rid of the collision with kExitWithAssertionFailure.
84 const int kExitAfterSIGSEGV
= 1;
87 // PNaCl toolchain's signal ABIs are incompatible with Linux's.
88 // So, for simplicity, just drop the "timeout" feature from unittest framework
89 // with relying on the buildbot's timeout feature.
90 #if !defined(OS_NACL_NONSFI)
91 static void SigAlrmHandler(int) {
92 const char failure_message
[] = "Timeout reached!\n";
93 // Make sure that we never block here.
94 if (!fcntl(2, F_SETFL
, O_NONBLOCK
)) {
95 ignore_result(write(2, failure_message
, sizeof(failure_message
) - 1));
97 _exit(kExitForTimeout
);
100 // Set a timeout with a handler that will automatically fail the
102 static void SetProcessTimeout(int time_in_seconds
) {
103 struct sigaction act
= {};
104 act
.sa_handler
= SigAlrmHandler
;
105 SANDBOX_ASSERT(sigemptyset(&act
.sa_mask
) == 0);
108 struct sigaction old_act
;
109 SANDBOX_ASSERT(sigaction(SIGALRM
, &act
, &old_act
) == 0);
111 // We don't implemenet signal chaining, so make sure that nothing else
112 // is expecting to handle SIGALRM.
113 SANDBOX_ASSERT((old_act
.sa_flags
& SA_SIGINFO
) == 0);
114 SANDBOX_ASSERT(old_act
.sa_handler
== SIG_DFL
);
115 sigset_t sigalrm_set
;
116 SANDBOX_ASSERT(sigemptyset(&sigalrm_set
) == 0);
117 SANDBOX_ASSERT(sigaddset(&sigalrm_set
, SIGALRM
) == 0);
118 SANDBOX_ASSERT(sigprocmask(SIG_UNBLOCK
, &sigalrm_set
, NULL
) == 0);
119 SANDBOX_ASSERT(alarm(time_in_seconds
) == 0); // There should be no previous
122 #endif // !defined(OS_NACL_NONSFI)
124 // Runs a test in a sub-process. This is necessary for most of the code
125 // in the BPF sandbox, as it potentially makes global state changes and as
126 // it also tends to raise fatal errors, if the code has been used in an
128 void UnitTests::RunTestInProcess(SandboxTestRunner
* test_runner
,
130 const void* death_aux
) {
132 // We need to fork(), so we can't be multi-threaded, as threads could hold
134 int num_threads
= CountThreads();
135 #if !defined(THREAD_SANITIZER)
136 const int kNumExpectedThreads
= 1;
138 // Under TSAN, there is a special helper thread. It should be completely
139 // invisible to our testing, so we ignore it. It should be ok to fork()
140 // with this thread. It's currently buggy, but it's the best we can do until
141 // there is a way to delay the start of the thread
142 // (https://code.google.com/p/thread-sanitizer/issues/detail?id=19).
143 const int kNumExpectedThreads
= 2;
146 // The kernel is at liberty to wake a thread id futex before updating /proc.
147 // If another test running in the same process has stopped a thread, it may
148 // appear as still running in /proc.
149 // We poll /proc, with an exponential back-off. At most, we'll sleep around
150 // 2^iterations nanoseconds in nanosleep().
151 for (unsigned int iteration
= 0; iteration
< 30; iteration
++) {
152 struct timespec ts
= {0, 1L << iteration
/* nanoseconds */};
153 PCHECK(0 == HANDLE_EINTR(nanosleep(&ts
, &ts
)));
154 num_threads
= CountThreads();
155 if (kNumExpectedThreads
== num_threads
)
159 ASSERT_EQ(kNumExpectedThreads
, num_threads
)
160 << "Running sandbox tests with multiple threads "
161 << "is not supported and will make the tests flaky.";
163 ASSERT_EQ(0, pipe(fds
));
164 // Check that our pipe is not on one of the standard file descriptor.
165 SANDBOX_ASSERT(fds
[0] > 2 && fds
[1] > 2);
168 ASSERT_LE(0, (pid
= fork()));
171 // Redirect stderr to our pipe. This way, we can capture all error
172 // messages, if we decide we want to do so in our tests.
173 SANDBOX_ASSERT(dup2(fds
[1], 2) == 2);
174 SANDBOX_ASSERT(!close(fds
[0]));
175 SANDBOX_ASSERT(!close(fds
[1]));
177 // Don't set a timeout if running on Valgrind, since it's generally much
179 if (!IsRunningOnValgrind()) {
180 #if !defined(OS_NACL_NONSFI)
181 SetProcessTimeout(GetSubProcessTimeoutTimeInSeconds());
185 // Disable core files. They are not very useful for our individual test
187 struct rlimit no_core
= {0};
188 setrlimit(RLIMIT_CORE
, &no_core
);
191 if (test_runner
->ShouldCheckForLeaks()) {
192 #if defined(LEAK_SANITIZER)
193 __lsan_do_leak_check();
196 _exit(kExpectedValue
);
200 std::vector
<char> msg_buf
;
203 // Make sure read() will never block as we'll use poll() to
204 // block with a timeout instead.
205 const int fcntl_ret
= fcntl(fds
[0], F_SETFL
, O_NONBLOCK
);
206 ASSERT_EQ(0, fcntl_ret
);
207 struct pollfd poll_fd
= {fds
[0], POLLIN
| POLLRDHUP
, 0};
210 // We prefer the SIGALRM timeout to trigger in the child than this timeout
211 // so we double the common value here.
212 int poll_timeout
= GetSubProcessTimeoutTimeInSeconds() * 2 * 1000;
213 while ((poll_ret
= poll(&poll_fd
, 1, poll_timeout
) > 0)) {
214 const size_t kCapacity
= 256;
215 const size_t len
= msg_buf
.size();
216 msg_buf
.resize(len
+ kCapacity
);
217 rc
= HANDLE_EINTR(read(fds
[0], &msg_buf
[len
], kCapacity
));
218 msg_buf
.resize(len
+ std::max(rc
, static_cast<ssize_t
>(0)));
222 ASSERT_NE(poll_ret
, -1) << "poll() failed";
223 ASSERT_NE(poll_ret
, 0) << "Timeout while reading child state";
225 std::string
msg(msg_buf
.begin(), msg_buf
.end());
228 int waitpid_returned
= HANDLE_EINTR(waitpid(pid
, &status
, 0));
229 ASSERT_EQ(pid
, waitpid_returned
) << TestFailedMessage(msg
);
231 // At run-time, we sometimes decide that a test shouldn't actually
232 // run (e.g. when testing sandbox features on a kernel that doesn't
233 // have sandboxing support). When that happens, don't attempt to
234 // call the "death" function, as it might be looking for a
235 // death-test condition that would never have triggered.
236 if (!WIFEXITED(status
) || WEXITSTATUS(status
) != kIgnoreThisTest
||
238 // We use gtest's ASSERT_XXX() macros instead of the DeathCheck
239 // functions. This means, on failure, "return" is called. This
240 // only works correctly, if the call of the "death" callback is
241 // the very last thing in our function.
242 death(status
, msg
, death_aux
);
246 void UnitTests::DeathSuccess(int status
, const std::string
& msg
, const void*) {
247 std::string
details(TestFailedMessage(msg
));
249 bool subprocess_terminated_normally
= WIFEXITED(status
);
250 ASSERT_TRUE(subprocess_terminated_normally
) << details
;
251 int subprocess_exit_status
= WEXITSTATUS(status
);
252 ASSERT_EQ(kExpectedValue
, subprocess_exit_status
) << details
;
253 bool subprocess_exited_but_printed_messages
= !msg
.empty();
254 EXPECT_FALSE(subprocess_exited_but_printed_messages
) << details
;
257 void UnitTests::DeathSuccessAllowNoise(int status
,
258 const std::string
& msg
,
260 std::string
details(TestFailedMessage(msg
));
262 bool subprocess_terminated_normally
= WIFEXITED(status
);
263 ASSERT_TRUE(subprocess_terminated_normally
) << details
;
264 int subprocess_exit_status
= WEXITSTATUS(status
);
265 ASSERT_EQ(kExpectedValue
, subprocess_exit_status
) << details
;
268 void UnitTests::DeathMessage(int status
,
269 const std::string
& msg
,
271 std::string
details(TestFailedMessage(msg
));
272 const char* expected_msg
= static_cast<const char*>(aux
);
274 bool subprocess_terminated_normally
= WIFEXITED(status
);
275 ASSERT_TRUE(subprocess_terminated_normally
) << "Exit status: " << status
277 int subprocess_exit_status
= WEXITSTATUS(status
);
278 ASSERT_EQ(1, subprocess_exit_status
) << details
;
280 bool subprocess_exited_without_matching_message
=
281 msg
.find(expected_msg
) == std::string::npos
;
283 // In official builds CHECK messages are dropped, so look for SIGABRT.
284 // See https://code.google.com/p/chromium/issues/detail?id=437312
285 #if defined(OFFICIAL_BUILD) && defined(NDEBUG) && !defined(OS_ANDROID)
286 if (subprocess_exited_without_matching_message
) {
287 static const char kSigAbortMessage
[] = "Received signal 6";
288 subprocess_exited_without_matching_message
=
289 msg
.find(kSigAbortMessage
) == std::string::npos
;
292 EXPECT_FALSE(subprocess_exited_without_matching_message
) << details
;
295 void UnitTests::DeathSEGVMessage(int status
,
296 const std::string
& msg
,
298 std::string
details(TestFailedMessage(msg
));
299 const char* expected_msg
= static_cast<const char*>(aux
);
301 #if !defined(SANDBOX_USES_BASE_TEST_SUITE)
302 const bool subprocess_got_sigsegv
=
303 WIFSIGNALED(status
) && (SIGSEGV
== WTERMSIG(status
));
305 // This hack is required when a signal handler is installed
306 // for SEGV that will _exit(1).
307 const bool subprocess_got_sigsegv
=
308 WIFEXITED(status
) && (kExitAfterSIGSEGV
== WEXITSTATUS(status
));
311 ASSERT_TRUE(subprocess_got_sigsegv
) << "Exit status: " << status
314 bool subprocess_exited_without_matching_message
=
315 msg
.find(expected_msg
) == std::string::npos
;
316 EXPECT_FALSE(subprocess_exited_without_matching_message
) << details
;
319 void UnitTests::DeathExitCode(int status
,
320 const std::string
& msg
,
322 int expected_exit_code
= static_cast<int>(reinterpret_cast<intptr_t>(aux
));
323 std::string
details(TestFailedMessage(msg
));
325 bool subprocess_terminated_normally
= WIFEXITED(status
);
326 ASSERT_TRUE(subprocess_terminated_normally
) << details
;
327 int subprocess_exit_status
= WEXITSTATUS(status
);
328 ASSERT_EQ(expected_exit_code
, subprocess_exit_status
) << details
;
331 void UnitTests::DeathBySignal(int status
,
332 const std::string
& msg
,
334 int expected_signo
= static_cast<int>(reinterpret_cast<intptr_t>(aux
));
335 std::string
details(TestFailedMessage(msg
));
337 bool subprocess_terminated_by_signal
= WIFSIGNALED(status
);
338 ASSERT_TRUE(subprocess_terminated_by_signal
) << details
;
339 int subprocess_signal_number
= WTERMSIG(status
);
340 ASSERT_EQ(expected_signo
, subprocess_signal_number
) << details
;
343 void UnitTests::AssertionFailure(const char* expr
, const char* file
, int line
) {
344 fprintf(stderr
, "%s:%d:%s", file
, line
, expr
);
346 _exit(kExitWithAssertionFailure
);
349 void UnitTests::IgnoreThisTest() {
351 _exit(kIgnoreThisTest
);