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