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>
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"
19 std::string
TestFailedMessage(const std::string
& msg
) {
20 return msg
.empty() ? std::string() : "Actual test failure: " + msg
;
23 int GetSubProcessTimeoutTimeInSeconds() {
24 // 10s ought to be enough for anybody.
28 // Returns the number of threads of the current process or -1.
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
34 if (task_d
!= 0 || task_stat
.st_nlink
< 3)
36 const int num_threads
= task_stat
.st_nlink
- 2;
45 #if defined(OS_ANDROID)
52 bool IsArchitectureArm() {
53 #if defined(ARCH_CPU_ARM_FAMILY)
60 // TODO(jln): figure out why base/.../dynamic_annotations.h's
61 // RunningOnValgrind() cannot link.
62 bool IsRunningOnValgrind() { return RUNNING_ON_VALGRIND
; }
64 static const int kExpectedValue
= 42;
65 static const int kIgnoreThisTest
= 43;
66 static const int kExitWithAssertionFailure
= 1;
67 static const int kExitForTimeout
= 2;
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));
75 _exit(kExitForTimeout
);
78 // Set a timeout with a handler that will automatically fail the
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);
86 struct sigaction old_act
;
87 SANDBOX_ASSERT(sigaction(SIGALRM
, &act
, &old_act
) == 0);
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
);
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
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
105 void UnitTests::RunTestInProcess(UnitTests::Test test
,
108 const void* death_aux
) {
109 // We need to fork(), so we can't be multi-threaded, as threads could hold
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).
120 ASSERT_EQ(1, num_threads
) << "Running sandbox tests with multiple threads "
121 << "is not supported and will make the tests "
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);
129 ASSERT_LE(0, (pid
= fork()));
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]));
138 // Don't set a timeout if running on Valgrind, since it's generally much
140 if (!IsRunningOnValgrind()) {
141 SetProcessTimeout(GetSubProcessTimeoutTimeInSeconds());
144 // Disable core files. They are not very useful for our individual test
146 struct rlimit no_core
= {0};
147 setrlimit(RLIMIT_CORE
, &no_core
);
150 _exit(kExpectedValue
);
154 std::vector
<char> msg_buf
;
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};
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)));
176 ASSERT_NE(poll_ret
, -1) << "poll() failed";
177 ASSERT_NE(poll_ret
, 0) << "Timeout while reading child state";
179 std::string
msg(msg_buf
.begin(), msg_buf
.end());
182 int waitpid_returned
= HANDLE_EINTR(waitpid(pid
, &status
, 0));
183 ASSERT_EQ(pid
, waitpid_returned
) << TestFailedMessage(msg
);
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
||
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
);
200 void UnitTests::DeathSuccess(int status
, const std::string
& msg
, const void*) {
201 std::string
details(TestFailedMessage(msg
));
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
;
211 void UnitTests::DeathMessage(int status
,
212 const std::string
& msg
,
214 std::string
details(TestFailedMessage(msg
));
215 const char* expected_msg
= static_cast<const char*>(aux
);
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
;
226 void UnitTests::DeathExitCode(int status
,
227 const std::string
& msg
,
229 int expected_exit_code
= static_cast<int>(reinterpret_cast<intptr_t>(aux
));
230 std::string
details(TestFailedMessage(msg
));
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
;
238 void UnitTests::DeathBySignal(int status
,
239 const std::string
& msg
,
241 int expected_signo
= static_cast<int>(reinterpret_cast<intptr_t>(aux
));
242 std::string
details(TestFailedMessage(msg
));
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
;
250 void UnitTests::AssertionFailure(const char* expr
, const char* file
, int line
) {
251 fprintf(stderr
, "%s:%d:%s", file
, line
, expr
);
253 _exit(kExitWithAssertionFailure
);
256 void UnitTests::IgnoreThisTest() {
258 _exit(kIgnoreThisTest
);