Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(681)

Side by Side Diff: sandbox/linux/tests/unit_tests.cc

Issue 11411254: SECCOMP-BPF: Added supported for inspection system call arguments from BPF filters. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed comments and fixed death tests Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stdio.h> 5 #include <stdio.h>
6 #include <sys/resource.h> 6 #include <sys/resource.h>
7 #include <sys/time.h> 7 #include <sys/time.h>
8 8
9 #include "base/file_util.h" 9 #include "base/file_util.h"
10 #include "sandbox/linux/tests/unit_tests.h" 10 #include "sandbox/linux/tests/unit_tests.h"
11 11
12 namespace {
13 std::string TestFailedMessage(const std::string& msg) {
14 return msg.empty() ? "" : "Actual test failure: " + msg;
15 }
16 }
17
12 namespace sandbox { 18 namespace sandbox {
13 19
14 static const int kExpectedValue = 42; 20 static const int kExpectedValue = 42;
21 static const int kIgnoreThisTest = 43;
22 static const int kExitWithAssertionFailure = 1;
15 23
16 void UnitTests::RunTestInProcess(UnitTests::Test test, void *arg) { 24 void UnitTests::RunTestInProcess(UnitTests::Test test, void *arg,
25 DeathCheck death, const void *death_aux) {
17 // Runs a test in a sub-process. This is necessary for most of the code 26 // Runs a test in a sub-process. This is necessary for most of the code
18 // in the BPF sandbox, as it potentially makes global state changes and as 27 // in the BPF sandbox, as it potentially makes global state changes and as
19 // it also tends to raise fatal errors, if the code has been used in an 28 // it also tends to raise fatal errors, if the code has been used in an
20 // insecure manner. 29 // insecure manner.
21 int fds[2]; 30 int fds[2];
22 ASSERT_EQ(0, pipe(fds)); 31 ASSERT_EQ(0, pipe(fds));
23 32
24 pid_t pid; 33 pid_t pid;
25 ASSERT_LE(0, (pid = fork())); 34 ASSERT_LE(0, (pid = fork()));
26 if (!pid) { 35 if (!pid) {
27 // In child process 36 // In child process
28 // Redirect stderr to our pipe. This way, we can capture all error 37 // Redirect stderr to our pipe. This way, we can capture all error
29 // messages, if we decide we want to do so in our tests. 38 // messages, if we decide we want to do so in our tests.
30 SANDBOX_ASSERT(dup2(fds[1], 2) == 2); 39 SANDBOX_ASSERT(dup2(fds[1], 2) == 2);
31 SANDBOX_ASSERT(!close(fds[0])); 40 SANDBOX_ASSERT(!close(fds[0]));
32 SANDBOX_ASSERT(!close(fds[1])); 41 SANDBOX_ASSERT(!close(fds[1]));
33 42
34 // Disable core files. They are not very useful for our individual test 43 // Disable core files. They are not very useful for our individual test
35 // cases. 44 // cases.
36 struct rlimit no_core = { 0 }; 45 struct rlimit no_core = { 0 };
37 setrlimit(RLIMIT_CORE, &no_core); 46 setrlimit(RLIMIT_CORE, &no_core);
38 47
39 test(arg); 48 test(arg);
40 _exit(kExpectedValue); 49 _exit(kExpectedValue);
41 } 50 }
42 51
43 (void)HANDLE_EINTR(close(fds[1])); 52 (void)HANDLE_EINTR(close(fds[1]));
44 std::vector<char> msg; 53 std::vector<char> msg_buf;
45 ssize_t rc; 54 ssize_t rc;
46 do { 55 do {
47 const unsigned int kCapacity = 256; 56 const unsigned int kCapacity = 256;
48 size_t len = msg.size(); 57 size_t len = msg_buf.size();
49 msg.resize(len + kCapacity); 58 msg_buf.resize(len + kCapacity);
50 rc = HANDLE_EINTR(read(fds[0], &msg[len], kCapacity)); 59 rc = HANDLE_EINTR(read(fds[0], &msg_buf[len], kCapacity));
51 msg.resize(len + std::max(rc, static_cast<ssize_t>(0))); 60 msg_buf.resize(len + std::max(rc, static_cast<ssize_t>(0)));
52 } while (rc > 0); 61 } while (rc > 0);
53 std::string details;
54 if (!msg.empty()) {
55 details = "Actual test failure: " + std::string(msg.begin(), msg.end());
56 }
57 (void)HANDLE_EINTR(close(fds[0])); 62 (void)HANDLE_EINTR(close(fds[0]));
63 std::string msg(msg_buf.begin(), msg_buf.end());
58 64
59 int status = 0; 65 int status = 0;
60 int waitpid_returned = HANDLE_EINTR(waitpid(pid, &status, 0)); 66 int waitpid_returned = HANDLE_EINTR(waitpid(pid, &status, 0));
61 ASSERT_EQ(pid, waitpid_returned) << details; 67 ASSERT_EQ(pid, waitpid_returned) << TestFailedMessage(msg);
68
69 // At run-time, we sometimes decide that a test shouldn't actually
70 // run (e.g. when testing sandbox features on a kernel that doesn't
71 // have sandboxing support). When that happens, don't attempt to
72 // call the "death" function, as it might be looking for a
73 // death-test condition that would never have triggered.
74 if (!WIFEXITED(status) || WEXITSTATUS(status) != kIgnoreThisTest ||
75 !msg.empty()) {
76 // We use gtest's ASSERT_XXX() macros instead of the DeathCheck
77 // functions. This means, on failure, "return" is called. This
78 // only works correctly, if the call of the "death" callback is
79 // the very last thing in our function.
80 death(status, msg, death_aux);
81 }
82 }
83
84 void UnitTests::DeathSuccess(int status, const std::string& msg,
85 const void *) {
86 std::string details(TestFailedMessage(msg));
87
62 bool subprocess_terminated_normally = WIFEXITED(status); 88 bool subprocess_terminated_normally = WIFEXITED(status);
63 ASSERT_TRUE(subprocess_terminated_normally) << details; 89 ASSERT_TRUE(subprocess_terminated_normally) << details;
64 int subprocess_exit_status = WEXITSTATUS(status); 90 int subprocess_exit_status = WEXITSTATUS(status);
65 ASSERT_EQ(kExpectedValue, subprocess_exit_status) << details; 91 ASSERT_EQ(kExpectedValue, subprocess_exit_status) << details;
66 bool subprocess_exited_but_printed_messages = !msg.empty(); 92 bool subprocess_exited_but_printed_messages = !msg.empty();
67 EXPECT_FALSE(subprocess_exited_but_printed_messages) << details; 93 EXPECT_FALSE(subprocess_exited_but_printed_messages) << details;
68 } 94 }
69 95
96 void UnitTests::DeathMessage(int status, const std::string& msg,
97 const void *aux) {
98 std::string details(TestFailedMessage(msg));
99 const char *expected_msg = static_cast<const char *>(aux);
100
101 bool subprocess_terminated_normally = WIFEXITED(status);
102 ASSERT_TRUE(subprocess_terminated_normally) << details;
103 int subprocess_exit_status = WEXITSTATUS(status);
104 ASSERT_EQ(kExitWithAssertionFailure, subprocess_exit_status) << details;
105 bool subprocess_exited_without_matching_message =
106 msg.find(expected_msg) == std::string::npos;
107 EXPECT_FALSE(subprocess_exited_without_matching_message) << details;
108 }
109
110 void UnitTests::DeathExitCode(int status, const std::string& msg,
111 const void *aux) {
112 int expected_exit_code = static_cast<int>(reinterpret_cast<intptr_t>(aux));
113 std::string details(TestFailedMessage(msg));
114
115 bool subprocess_terminated_normally = WIFEXITED(status);
116 ASSERT_TRUE(subprocess_terminated_normally) << details;
117 int subprocess_exit_status = WEXITSTATUS(status);
118 ASSERT_EQ(subprocess_exit_status, expected_exit_code) << details;
119 }
120
121 void UnitTests::DeathBySignal(int status, const std::string& msg,
122 const void *aux) {
123 int expected_signo = static_cast<int>(reinterpret_cast<intptr_t>(aux));
124 std::string details(TestFailedMessage(msg));
125
126 bool subprocess_terminated_by_signal = WIFSIGNALED(status);
127 ASSERT_TRUE(subprocess_terminated_by_signal) << details;
128 int subprocess_signal_number = WTERMSIG(status);
129 ASSERT_EQ(subprocess_signal_number, expected_signo) << details;
130 }
131
70 void UnitTests::AssertionFailure(const char *expr, const char *file, 132 void UnitTests::AssertionFailure(const char *expr, const char *file,
71 int line) { 133 int line) {
72 fprintf(stderr, "%s:%d:%s", file, line, expr); 134 fprintf(stderr, "%s:%d:%s", file, line, expr);
73 fflush(stderr); 135 fflush(stderr);
74 _exit(1); 136 _exit(kExitWithAssertionFailure);
137 }
138
139 void UnitTests::IgnoreThisTest() {
140 fflush(stderr);
141 _exit(kIgnoreThisTest);
75 } 142 }
76 143
77 } // namespace 144 } // namespace
OLDNEW
« sandbox/linux/tests/unit_tests.h ('K') | « sandbox/linux/tests/unit_tests.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698