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

Side by Side Diff: sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc

Issue 101773003: Linux sandbox: cleanup sandbox-bpf naming. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address namespace sandbox nits. Created 7 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
« no previous file with comments | « sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h ('k') | sandbox/linux/seccomp-bpf/syscall.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <errno.h> 5 #include <errno.h>
6 #include <pthread.h> 6 #include <pthread.h>
7 #include <sched.h> 7 #include <sched.h>
8 #include <sys/prctl.h> 8 #include <sys/prctl.h>
9 #include <sys/syscall.h> 9 #include <sys/syscall.h>
10 #include <sys/time.h> 10 #include <sys/time.h>
(...skipping 22 matching lines...) Expand all
33 33
34 // Workaround for Android's prctl.h file. 34 // Workaround for Android's prctl.h file.
35 #ifndef PR_GET_ENDIAN 35 #ifndef PR_GET_ENDIAN
36 #define PR_GET_ENDIAN 19 36 #define PR_GET_ENDIAN 19
37 #endif 37 #endif
38 #ifndef PR_CAPBSET_READ 38 #ifndef PR_CAPBSET_READ
39 #define PR_CAPBSET_READ 23 39 #define PR_CAPBSET_READ 23
40 #define PR_CAPBSET_DROP 24 40 #define PR_CAPBSET_DROP 24
41 #endif 41 #endif
42 42
43 using namespace playground2; 43 namespace sandbox {
44 using sandbox::BrokerProcess;
45 44
46 namespace { 45 namespace {
47 46
48 const int kExpectedReturnValue = 42; 47 const int kExpectedReturnValue = 42;
49 const char kSandboxDebuggingEnv[] = "CHROME_SANDBOX_DEBUGGING"; 48 const char kSandboxDebuggingEnv[] = "CHROME_SANDBOX_DEBUGGING";
50 49
51 // This test should execute no matter whether we have kernel support. So, 50 // This test should execute no matter whether we have kernel support. So,
52 // we make it a TEST() instead of a BPF_TEST(). 51 // we make it a TEST() instead of a BPF_TEST().
53 TEST(SandboxBpf, CallSupports) { 52 TEST(SandboxBPF, CallSupports) {
54 // We check that we don't crash, but it's ok if the kernel doesn't 53 // We check that we don't crash, but it's ok if the kernel doesn't
55 // support it. 54 // support it.
56 bool seccomp_bpf_supported = 55 bool seccomp_bpf_supported =
57 Sandbox::SupportsSeccompSandbox(-1) == Sandbox::STATUS_AVAILABLE; 56 SandboxBPF::SupportsSeccompSandbox(-1) == SandboxBPF::STATUS_AVAILABLE;
58 // We want to log whether or not seccomp BPF is actually supported 57 // We want to log whether or not seccomp BPF is actually supported
59 // since actual test coverage depends on it. 58 // since actual test coverage depends on it.
60 RecordProperty("SeccompBPFSupported", 59 RecordProperty("SeccompBPFSupported",
61 seccomp_bpf_supported ? "true." : "false."); 60 seccomp_bpf_supported ? "true." : "false.");
62 std::cout << "Seccomp BPF supported: " 61 std::cout << "Seccomp BPF supported: "
63 << (seccomp_bpf_supported ? "true." : "false.") << "\n"; 62 << (seccomp_bpf_supported ? "true." : "false.") << "\n";
64 RecordProperty("PointerSize", sizeof(void*)); 63 RecordProperty("PointerSize", sizeof(void*));
65 std::cout << "Pointer size: " << sizeof(void*) << "\n"; 64 std::cout << "Pointer size: " << sizeof(void*) << "\n";
66 } 65 }
67 66
68 SANDBOX_TEST(SandboxBpf, CallSupportsTwice) { 67 SANDBOX_TEST(SandboxBPF, CallSupportsTwice) {
69 Sandbox::SupportsSeccompSandbox(-1); 68 SandboxBPF::SupportsSeccompSandbox(-1);
70 Sandbox::SupportsSeccompSandbox(-1); 69 SandboxBPF::SupportsSeccompSandbox(-1);
71 } 70 }
72 71
73 // BPF_TEST does a lot of the boiler-plate code around setting up a 72 // BPF_TEST does a lot of the boiler-plate code around setting up a
74 // policy and optional passing data between the caller, the policy and 73 // policy and optional passing data between the caller, the policy and
75 // any Trap() handlers. This is great for writing short and concise tests, 74 // any Trap() handlers. This is great for writing short and concise tests,
76 // and it helps us accidentally forgetting any of the crucial steps in 75 // and it helps us accidentally forgetting any of the crucial steps in
77 // setting up the sandbox. But it wouldn't hurt to have at least one test 76 // setting up the sandbox. But it wouldn't hurt to have at least one test
78 // that explicitly walks through all these steps. 77 // that explicitly walks through all these steps.
79 78
80 intptr_t FakeGetPid(const struct arch_seccomp_data& args, void* aux) { 79 intptr_t FakeGetPid(const struct arch_seccomp_data& args, void* aux) {
81 BPF_ASSERT(aux); 80 BPF_ASSERT(aux);
82 pid_t* pid_ptr = static_cast<pid_t*>(aux); 81 pid_t* pid_ptr = static_cast<pid_t*>(aux);
83 return (*pid_ptr)++; 82 return (*pid_ptr)++;
84 } 83 }
85 84
86 ErrorCode VerboseAPITestingPolicy(Sandbox* sandbox, int sysno, void* aux) { 85 ErrorCode VerboseAPITestingPolicy(SandboxBPF* sandbox, int sysno, void* aux) {
87 if (!Sandbox::IsValidSyscallNumber(sysno)) { 86 if (!SandboxBPF::IsValidSyscallNumber(sysno)) {
88 return ErrorCode(ENOSYS); 87 return ErrorCode(ENOSYS);
89 } else if (sysno == __NR_getpid) { 88 } else if (sysno == __NR_getpid) {
90 return sandbox->Trap(FakeGetPid, aux); 89 return sandbox->Trap(FakeGetPid, aux);
91 } else { 90 } else {
92 return ErrorCode(ErrorCode::ERR_ALLOWED); 91 return ErrorCode(ErrorCode::ERR_ALLOWED);
93 } 92 }
94 } 93 }
95 94
96 SANDBOX_TEST(SandboxBpf, DISABLE_ON_TSAN(VerboseAPITesting)) { 95 SANDBOX_TEST(SandboxBPF, DISABLE_ON_TSAN(VerboseAPITesting)) {
97 if (Sandbox::SupportsSeccompSandbox(-1) == 96 if (SandboxBPF::SupportsSeccompSandbox(-1) ==
98 playground2::Sandbox::STATUS_AVAILABLE) { 97 sandbox::SandboxBPF::STATUS_AVAILABLE) {
99 pid_t test_var = 0; 98 pid_t test_var = 0;
100 Sandbox sandbox; 99 SandboxBPF sandbox;
101 sandbox.SetSandboxPolicyDeprecated(VerboseAPITestingPolicy, &test_var); 100 sandbox.SetSandboxPolicyDeprecated(VerboseAPITestingPolicy, &test_var);
102 sandbox.StartSandbox(); 101 sandbox.StartSandbox();
103 102
104 BPF_ASSERT(test_var == 0); 103 BPF_ASSERT(test_var == 0);
105 BPF_ASSERT(syscall(__NR_getpid) == 0); 104 BPF_ASSERT(syscall(__NR_getpid) == 0);
106 BPF_ASSERT(test_var == 1); 105 BPF_ASSERT(test_var == 1);
107 BPF_ASSERT(syscall(__NR_getpid) == 1); 106 BPF_ASSERT(syscall(__NR_getpid) == 1);
108 BPF_ASSERT(test_var == 2); 107 BPF_ASSERT(test_var == 2);
109 108
110 // N.B.: Any future call to getpid() would corrupt the stack. 109 // N.B.: Any future call to getpid() would corrupt the stack.
111 // This is OK. The SANDBOX_TEST() macro is guaranteed to 110 // This is OK. The SANDBOX_TEST() macro is guaranteed to
112 // only ever call _exit() after the test completes. 111 // only ever call _exit() after the test completes.
113 } 112 }
114 } 113 }
115 114
116 // A simple blacklist test 115 // A simple blacklist test
117 116
118 ErrorCode BlacklistNanosleepPolicy(Sandbox*, int sysno, void*) { 117 ErrorCode BlacklistNanosleepPolicy(SandboxBPF*, int sysno, void*) {
119 if (!Sandbox::IsValidSyscallNumber(sysno)) { 118 if (!SandboxBPF::IsValidSyscallNumber(sysno)) {
120 // FIXME: we should really not have to do that in a trivial policy 119 // FIXME: we should really not have to do that in a trivial policy
121 return ErrorCode(ENOSYS); 120 return ErrorCode(ENOSYS);
122 } 121 }
123 122
124 switch (sysno) { 123 switch (sysno) {
125 case __NR_nanosleep: 124 case __NR_nanosleep:
126 return ErrorCode(EACCES); 125 return ErrorCode(EACCES);
127 default: 126 default:
128 return ErrorCode(ErrorCode::ERR_ALLOWED); 127 return ErrorCode(ErrorCode::ERR_ALLOWED);
129 } 128 }
130 } 129 }
131 130
132 BPF_TEST(SandboxBpf, ApplyBasicBlacklistPolicy, BlacklistNanosleepPolicy) { 131 BPF_TEST(SandboxBPF, ApplyBasicBlacklistPolicy, BlacklistNanosleepPolicy) {
133 // nanosleep() should be denied 132 // nanosleep() should be denied
134 const struct timespec ts = {0, 0}; 133 const struct timespec ts = {0, 0};
135 errno = 0; 134 errno = 0;
136 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); 135 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1);
137 BPF_ASSERT(errno == EACCES); 136 BPF_ASSERT(errno == EACCES);
138 } 137 }
139 138
140 // Now do a simple whitelist test 139 // Now do a simple whitelist test
141 140
142 ErrorCode WhitelistGetpidPolicy(Sandbox*, int sysno, void*) { 141 ErrorCode WhitelistGetpidPolicy(SandboxBPF*, int sysno, void*) {
143 switch (sysno) { 142 switch (sysno) {
144 case __NR_getpid: 143 case __NR_getpid:
145 case __NR_exit_group: 144 case __NR_exit_group:
146 return ErrorCode(ErrorCode::ERR_ALLOWED); 145 return ErrorCode(ErrorCode::ERR_ALLOWED);
147 default: 146 default:
148 return ErrorCode(ENOMEM); 147 return ErrorCode(ENOMEM);
149 } 148 }
150 } 149 }
151 150
152 BPF_TEST(SandboxBpf, ApplyBasicWhitelistPolicy, WhitelistGetpidPolicy) { 151 BPF_TEST(SandboxBPF, ApplyBasicWhitelistPolicy, WhitelistGetpidPolicy) {
153 // getpid() should be allowed 152 // getpid() should be allowed
154 errno = 0; 153 errno = 0;
155 BPF_ASSERT(syscall(__NR_getpid) > 0); 154 BPF_ASSERT(syscall(__NR_getpid) > 0);
156 BPF_ASSERT(errno == 0); 155 BPF_ASSERT(errno == 0);
157 156
158 // getpgid() should be denied 157 // getpgid() should be denied
159 BPF_ASSERT(getpgid(0) == -1); 158 BPF_ASSERT(getpgid(0) == -1);
160 BPF_ASSERT(errno == ENOMEM); 159 BPF_ASSERT(errno == ENOMEM);
161 } 160 }
162 161
163 // A simple blacklist policy, with a SIGSYS handler 162 // A simple blacklist policy, with a SIGSYS handler
164 163
165 intptr_t EnomemHandler(const struct arch_seccomp_data& args, void* aux) { 164 intptr_t EnomemHandler(const struct arch_seccomp_data& args, void* aux) {
166 // We also check that the auxiliary data is correct 165 // We also check that the auxiliary data is correct
167 SANDBOX_ASSERT(aux); 166 SANDBOX_ASSERT(aux);
168 *(static_cast<int*>(aux)) = kExpectedReturnValue; 167 *(static_cast<int*>(aux)) = kExpectedReturnValue;
169 return -ENOMEM; 168 return -ENOMEM;
170 } 169 }
171 170
172 ErrorCode BlacklistNanosleepPolicySigsys(Sandbox* sandbox, 171 ErrorCode BlacklistNanosleepPolicySigsys(SandboxBPF* sandbox,
173 int sysno, 172 int sysno,
174 void* aux) { 173 void* aux) {
175 if (!Sandbox::IsValidSyscallNumber(sysno)) { 174 if (!SandboxBPF::IsValidSyscallNumber(sysno)) {
176 // FIXME: we should really not have to do that in a trivial policy 175 // FIXME: we should really not have to do that in a trivial policy
177 return ErrorCode(ENOSYS); 176 return ErrorCode(ENOSYS);
178 } 177 }
179 178
180 switch (sysno) { 179 switch (sysno) {
181 case __NR_nanosleep: 180 case __NR_nanosleep:
182 return sandbox->Trap(EnomemHandler, aux); 181 return sandbox->Trap(EnomemHandler, aux);
183 default: 182 default:
184 return ErrorCode(ErrorCode::ERR_ALLOWED); 183 return ErrorCode(ErrorCode::ERR_ALLOWED);
185 } 184 }
186 } 185 }
187 186
188 BPF_TEST(SandboxBpf, 187 BPF_TEST(SandboxBPF,
189 BasicBlacklistWithSigsys, 188 BasicBlacklistWithSigsys,
190 BlacklistNanosleepPolicySigsys, 189 BlacklistNanosleepPolicySigsys,
191 int /* BPF_AUX */) { 190 int /* BPF_AUX */) {
192 // getpid() should work properly 191 // getpid() should work properly
193 errno = 0; 192 errno = 0;
194 BPF_ASSERT(syscall(__NR_getpid) > 0); 193 BPF_ASSERT(syscall(__NR_getpid) > 0);
195 BPF_ASSERT(errno == 0); 194 BPF_ASSERT(errno == 0);
196 195
197 // Our Auxiliary Data, should be reset by the signal handler 196 // Our Auxiliary Data, should be reset by the signal handler
198 BPF_AUX = -1; 197 BPF_AUX = -1;
199 const struct timespec ts = {0, 0}; 198 const struct timespec ts = {0, 0};
200 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); 199 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1);
201 BPF_ASSERT(errno == ENOMEM); 200 BPF_ASSERT(errno == ENOMEM);
202 201
203 // We expect the signal handler to modify AuxData 202 // We expect the signal handler to modify AuxData
204 BPF_ASSERT(BPF_AUX == kExpectedReturnValue); 203 BPF_ASSERT(BPF_AUX == kExpectedReturnValue);
205 } 204 }
206 205
207 // A simple test that verifies we can return arbitrary errno values. 206 // A simple test that verifies we can return arbitrary errno values.
208 207
209 ErrorCode ErrnoTestPolicy(Sandbox*, int sysno, void*) { 208 ErrorCode ErrnoTestPolicy(SandboxBPF*, int sysno, void*) {
210 if (!Sandbox::IsValidSyscallNumber(sysno)) { 209 if (!SandboxBPF::IsValidSyscallNumber(sysno)) {
211 // FIXME: we should really not have to do that in a trivial policy 210 // FIXME: we should really not have to do that in a trivial policy
212 return ErrorCode(ENOSYS); 211 return ErrorCode(ENOSYS);
213 } 212 }
214 213
215 switch (sysno) { 214 switch (sysno) {
216 case __NR_dup2: 215 case __NR_dup2:
217 // Pretend that dup2() worked, but don't actually do anything. 216 // Pretend that dup2() worked, but don't actually do anything.
218 return ErrorCode(0); 217 return ErrorCode(0);
219 case __NR_setuid: 218 case __NR_setuid:
220 #if defined(__NR_setuid32) 219 #if defined(__NR_setuid32)
221 case __NR_setuid32: 220 case __NR_setuid32:
222 #endif 221 #endif
223 // Return errno = 1. 222 // Return errno = 1.
224 return ErrorCode(1); 223 return ErrorCode(1);
225 case __NR_setgid: 224 case __NR_setgid:
226 #if defined(__NR_setgid32) 225 #if defined(__NR_setgid32)
227 case __NR_setgid32: 226 case __NR_setgid32:
228 #endif 227 #endif
229 // Return maximum errno value (typically 4095). 228 // Return maximum errno value (typically 4095).
230 return ErrorCode(ErrorCode::ERR_MAX_ERRNO); 229 return ErrorCode(ErrorCode::ERR_MAX_ERRNO);
231 case __NR_uname: 230 case __NR_uname:
232 // Return errno = 42; 231 // Return errno = 42;
233 return ErrorCode(42); 232 return ErrorCode(42);
234 default: 233 default:
235 return ErrorCode(ErrorCode::ERR_ALLOWED); 234 return ErrorCode(ErrorCode::ERR_ALLOWED);
236 } 235 }
237 } 236 }
238 237
239 BPF_TEST(SandboxBpf, ErrnoTest, ErrnoTestPolicy) { 238 BPF_TEST(SandboxBPF, ErrnoTest, ErrnoTestPolicy) {
240 // Verify that dup2() returns success, but doesn't actually run. 239 // Verify that dup2() returns success, but doesn't actually run.
241 int fds[4]; 240 int fds[4];
242 BPF_ASSERT(pipe(fds) == 0); 241 BPF_ASSERT(pipe(fds) == 0);
243 BPF_ASSERT(pipe(fds + 2) == 0); 242 BPF_ASSERT(pipe(fds + 2) == 0);
244 BPF_ASSERT(dup2(fds[2], fds[0]) == 0); 243 BPF_ASSERT(dup2(fds[2], fds[0]) == 0);
245 char buf[1] = {}; 244 char buf[1] = {};
246 BPF_ASSERT(write(fds[1], "\x55", 1) == 1); 245 BPF_ASSERT(write(fds[1], "\x55", 1) == 1);
247 BPF_ASSERT(write(fds[3], "\xAA", 1) == 1); 246 BPF_ASSERT(write(fds[3], "\xAA", 1) == 1);
248 BPF_ASSERT(read(fds[0], buf, 1) == 1); 247 BPF_ASSERT(read(fds[0], buf, 1) == 1);
249 248
(...skipping 21 matching lines...) Expand all
271 270
272 // Finally, test an errno in between the minimum and maximum. 271 // Finally, test an errno in between the minimum and maximum.
273 errno = 0; 272 errno = 0;
274 struct utsname uts_buf; 273 struct utsname uts_buf;
275 BPF_ASSERT(uname(&uts_buf) == -1); 274 BPF_ASSERT(uname(&uts_buf) == -1);
276 BPF_ASSERT(errno == 42); 275 BPF_ASSERT(errno == 42);
277 } 276 }
278 277
279 // Testing the stacking of two sandboxes 278 // Testing the stacking of two sandboxes
280 279
281 ErrorCode StackingPolicyPartOne(Sandbox* sandbox, int sysno, void*) { 280 ErrorCode StackingPolicyPartOne(SandboxBPF* sandbox, int sysno, void*) {
282 if (!Sandbox::IsValidSyscallNumber(sysno)) { 281 if (!SandboxBPF::IsValidSyscallNumber(sysno)) {
283 return ErrorCode(ENOSYS); 282 return ErrorCode(ENOSYS);
284 } 283 }
285 284
286 switch (sysno) { 285 switch (sysno) {
287 case __NR_getppid: 286 case __NR_getppid:
288 return sandbox->Cond(0, 287 return sandbox->Cond(0,
289 ErrorCode::TP_32BIT, 288 ErrorCode::TP_32BIT,
290 ErrorCode::OP_EQUAL, 289 ErrorCode::OP_EQUAL,
291 0, 290 0,
292 ErrorCode(ErrorCode::ERR_ALLOWED), 291 ErrorCode(ErrorCode::ERR_ALLOWED),
293 ErrorCode(EPERM)); 292 ErrorCode(EPERM));
294 default: 293 default:
295 return ErrorCode(ErrorCode::ERR_ALLOWED); 294 return ErrorCode(ErrorCode::ERR_ALLOWED);
296 } 295 }
297 } 296 }
298 297
299 ErrorCode StackingPolicyPartTwo(Sandbox* sandbox, int sysno, void*) { 298 ErrorCode StackingPolicyPartTwo(SandboxBPF* sandbox, int sysno, void*) {
300 if (!Sandbox::IsValidSyscallNumber(sysno)) { 299 if (!SandboxBPF::IsValidSyscallNumber(sysno)) {
301 return ErrorCode(ENOSYS); 300 return ErrorCode(ENOSYS);
302 } 301 }
303 302
304 switch (sysno) { 303 switch (sysno) {
305 case __NR_getppid: 304 case __NR_getppid:
306 return sandbox->Cond(0, 305 return sandbox->Cond(0,
307 ErrorCode::TP_32BIT, 306 ErrorCode::TP_32BIT,
308 ErrorCode::OP_EQUAL, 307 ErrorCode::OP_EQUAL,
309 0, 308 0,
310 ErrorCode(EINVAL), 309 ErrorCode(EINVAL),
311 ErrorCode(ErrorCode::ERR_ALLOWED)); 310 ErrorCode(ErrorCode::ERR_ALLOWED));
312 default: 311 default:
313 return ErrorCode(ErrorCode::ERR_ALLOWED); 312 return ErrorCode(ErrorCode::ERR_ALLOWED);
314 } 313 }
315 } 314 }
316 315
317 BPF_TEST(SandboxBpf, StackingPolicy, StackingPolicyPartOne) { 316 BPF_TEST(SandboxBPF, StackingPolicy, StackingPolicyPartOne) {
318 errno = 0; 317 errno = 0;
319 BPF_ASSERT(syscall(__NR_getppid, 0) > 0); 318 BPF_ASSERT(syscall(__NR_getppid, 0) > 0);
320 BPF_ASSERT(errno == 0); 319 BPF_ASSERT(errno == 0);
321 320
322 BPF_ASSERT(syscall(__NR_getppid, 1) == -1); 321 BPF_ASSERT(syscall(__NR_getppid, 1) == -1);
323 BPF_ASSERT(errno == EPERM); 322 BPF_ASSERT(errno == EPERM);
324 323
325 // Stack a second sandbox with its own policy. Verify that we can further 324 // Stack a second sandbox with its own policy. Verify that we can further
326 // restrict filters, but we cannot relax existing filters. 325 // restrict filters, but we cannot relax existing filters.
327 Sandbox sandbox; 326 SandboxBPF sandbox;
328 sandbox.SetSandboxPolicyDeprecated(StackingPolicyPartTwo, NULL); 327 sandbox.SetSandboxPolicyDeprecated(StackingPolicyPartTwo, NULL);
329 sandbox.StartSandbox(); 328 sandbox.StartSandbox();
330 329
331 errno = 0; 330 errno = 0;
332 BPF_ASSERT(syscall(__NR_getppid, 0) == -1); 331 BPF_ASSERT(syscall(__NR_getppid, 0) == -1);
333 BPF_ASSERT(errno == EINVAL); 332 BPF_ASSERT(errno == EINVAL);
334 333
335 BPF_ASSERT(syscall(__NR_getppid, 1) == -1); 334 BPF_ASSERT(syscall(__NR_getppid, 1) == -1);
336 BPF_ASSERT(errno == EPERM); 335 BPF_ASSERT(errno == EPERM);
337 } 336 }
338 337
339 // A more complex, but synthetic policy. This tests the correctness of the BPF 338 // A more complex, but synthetic policy. This tests the correctness of the BPF
340 // program by iterating through all syscalls and checking for an errno that 339 // program by iterating through all syscalls and checking for an errno that
341 // depends on the syscall number. Unlike the Verifier, this exercises the BPF 340 // depends on the syscall number. Unlike the Verifier, this exercises the BPF
342 // interpreter in the kernel. 341 // interpreter in the kernel.
343 342
344 // We try to make sure we exercise optimizations in the BPF compiler. We make 343 // We try to make sure we exercise optimizations in the BPF compiler. We make
345 // sure that the compiler can have an opportunity to coalesce syscalls with 344 // sure that the compiler can have an opportunity to coalesce syscalls with
346 // contiguous numbers and we also make sure that disjoint sets can return the 345 // contiguous numbers and we also make sure that disjoint sets can return the
347 // same errno. 346 // same errno.
348 int SysnoToRandomErrno(int sysno) { 347 int SysnoToRandomErrno(int sysno) {
349 // Small contiguous sets of 3 system calls return an errno equal to the 348 // Small contiguous sets of 3 system calls return an errno equal to the
350 // index of that set + 1 (so that we never return a NUL errno). 349 // index of that set + 1 (so that we never return a NUL errno).
351 return ((sysno & ~3) >> 2) % 29 + 1; 350 return ((sysno & ~3) >> 2) % 29 + 1;
352 } 351 }
353 352
354 ErrorCode SyntheticPolicy(Sandbox*, int sysno, void*) { 353 ErrorCode SyntheticPolicy(SandboxBPF*, int sysno, void*) {
355 if (!Sandbox::IsValidSyscallNumber(sysno)) { 354 if (!SandboxBPF::IsValidSyscallNumber(sysno)) {
356 // FIXME: we should really not have to do that in a trivial policy 355 // FIXME: we should really not have to do that in a trivial policy
357 return ErrorCode(ENOSYS); 356 return ErrorCode(ENOSYS);
358 } 357 }
359 358
360 // TODO(jorgelo): remove this once the new code generator lands. 359 // TODO(jorgelo): remove this once the new code generator lands.
361 #if defined(__arm__) 360 #if defined(__arm__)
362 if (sysno > static_cast<int>(MAX_PUBLIC_SYSCALL)) { 361 if (sysno > static_cast<int>(MAX_PUBLIC_SYSCALL)) {
363 return ErrorCode(ENOSYS); 362 return ErrorCode(ENOSYS);
364 } 363 }
365 #endif 364 #endif
366 365
367 if (sysno == __NR_exit_group || sysno == __NR_write) { 366 if (sysno == __NR_exit_group || sysno == __NR_write) {
368 // exit_group() is special, we really need it to work. 367 // exit_group() is special, we really need it to work.
369 // write() is needed for BPF_ASSERT() to report a useful error message. 368 // write() is needed for BPF_ASSERT() to report a useful error message.
370 return ErrorCode(ErrorCode::ERR_ALLOWED); 369 return ErrorCode(ErrorCode::ERR_ALLOWED);
371 } else { 370 } else {
372 return ErrorCode(SysnoToRandomErrno(sysno)); 371 return ErrorCode(SysnoToRandomErrno(sysno));
373 } 372 }
374 } 373 }
375 374
376 BPF_TEST(SandboxBpf, SyntheticPolicy, SyntheticPolicy) { 375 BPF_TEST(SandboxBPF, SyntheticPolicy, SyntheticPolicy) {
377 // Ensure that that kExpectedReturnValue + syscallnumber + 1 does not int 376 // Ensure that that kExpectedReturnValue + syscallnumber + 1 does not int
378 // overflow. 377 // overflow.
379 BPF_ASSERT(std::numeric_limits<int>::max() - kExpectedReturnValue - 1 >= 378 BPF_ASSERT(std::numeric_limits<int>::max() - kExpectedReturnValue - 1 >=
380 static_cast<int>(MAX_PUBLIC_SYSCALL)); 379 static_cast<int>(MAX_PUBLIC_SYSCALL));
381 380
382 for (int syscall_number = static_cast<int>(MIN_SYSCALL); 381 for (int syscall_number = static_cast<int>(MIN_SYSCALL);
383 syscall_number <= static_cast<int>(MAX_PUBLIC_SYSCALL); 382 syscall_number <= static_cast<int>(MAX_PUBLIC_SYSCALL);
384 ++syscall_number) { 383 ++syscall_number) {
385 if (syscall_number == __NR_exit_group || syscall_number == __NR_write) { 384 if (syscall_number == __NR_exit_group || syscall_number == __NR_write) {
386 // exit_group() is special 385 // exit_group() is special
(...skipping 13 matching lines...) Expand all
400 // MIN_PRIVATE_SYSCALL plus 1 (to avoid NUL errno). 399 // MIN_PRIVATE_SYSCALL plus 1 (to avoid NUL errno).
401 int ArmPrivateSysnoToErrno(int sysno) { 400 int ArmPrivateSysnoToErrno(int sysno) {
402 if (sysno >= static_cast<int>(MIN_PRIVATE_SYSCALL) && 401 if (sysno >= static_cast<int>(MIN_PRIVATE_SYSCALL) &&
403 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) { 402 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) {
404 return (sysno - MIN_PRIVATE_SYSCALL) + 1; 403 return (sysno - MIN_PRIVATE_SYSCALL) + 1;
405 } else { 404 } else {
406 return ENOSYS; 405 return ENOSYS;
407 } 406 }
408 } 407 }
409 408
410 ErrorCode ArmPrivatePolicy(Sandbox*, int sysno, void*) { 409 ErrorCode ArmPrivatePolicy(SandboxBPF*, int sysno, void*) {
411 if (!Sandbox::IsValidSyscallNumber(sysno)) { 410 if (!SandboxBPF::IsValidSyscallNumber(sysno)) {
412 // FIXME: we should really not have to do that in a trivial policy. 411 // FIXME: we should really not have to do that in a trivial policy.
413 return ErrorCode(ENOSYS); 412 return ErrorCode(ENOSYS);
414 } 413 }
415 414
416 // Start from |__ARM_NR_set_tls + 1| so as not to mess with actual 415 // Start from |__ARM_NR_set_tls + 1| so as not to mess with actual
417 // ARM private system calls. 416 // ARM private system calls.
418 if (sysno >= static_cast<int>(__ARM_NR_set_tls + 1) && 417 if (sysno >= static_cast<int>(__ARM_NR_set_tls + 1) &&
419 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) { 418 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) {
420 return ErrorCode(ArmPrivateSysnoToErrno(sysno)); 419 return ErrorCode(ArmPrivateSysnoToErrno(sysno));
421 } else { 420 } else {
422 return ErrorCode(ErrorCode::ERR_ALLOWED); 421 return ErrorCode(ErrorCode::ERR_ALLOWED);
423 } 422 }
424 } 423 }
425 424
426 BPF_TEST(SandboxBpf, ArmPrivatePolicy, ArmPrivatePolicy) { 425 BPF_TEST(SandboxBPF, ArmPrivatePolicy, ArmPrivatePolicy) {
427 for (int syscall_number = static_cast<int>(__ARM_NR_set_tls + 1); 426 for (int syscall_number = static_cast<int>(__ARM_NR_set_tls + 1);
428 syscall_number <= static_cast<int>(MAX_PRIVATE_SYSCALL); 427 syscall_number <= static_cast<int>(MAX_PRIVATE_SYSCALL);
429 ++syscall_number) { 428 ++syscall_number) {
430 errno = 0; 429 errno = 0;
431 BPF_ASSERT(syscall(syscall_number) == -1); 430 BPF_ASSERT(syscall(syscall_number) == -1);
432 BPF_ASSERT(errno == ArmPrivateSysnoToErrno(syscall_number)); 431 BPF_ASSERT(errno == ArmPrivateSysnoToErrno(syscall_number));
433 } 432 }
434 } 433 }
435 #endif // defined(__arm__) 434 #endif // defined(__arm__)
436 435
437 intptr_t CountSyscalls(const struct arch_seccomp_data& args, void* aux) { 436 intptr_t CountSyscalls(const struct arch_seccomp_data& args, void* aux) {
438 // Count all invocations of our callback function. 437 // Count all invocations of our callback function.
439 ++*reinterpret_cast<int*>(aux); 438 ++*reinterpret_cast<int*>(aux);
440 439
441 // Verify that within the callback function all filtering is temporarily 440 // Verify that within the callback function all filtering is temporarily
442 // disabled. 441 // disabled.
443 BPF_ASSERT(syscall(__NR_getpid) > 1); 442 BPF_ASSERT(syscall(__NR_getpid) > 1);
444 443
445 // Verify that we can now call the underlying system call without causing 444 // Verify that we can now call the underlying system call without causing
446 // infinite recursion. 445 // infinite recursion.
447 return Sandbox::ForwardSyscall(args); 446 return SandboxBPF::ForwardSyscall(args);
448 } 447 }
449 448
450 ErrorCode GreyListedPolicy(Sandbox* sandbox, int sysno, void* aux) { 449 ErrorCode GreyListedPolicy(SandboxBPF* sandbox, int sysno, void* aux) {
451 // The use of UnsafeTrap() causes us to print a warning message. This is 450 // The use of UnsafeTrap() causes us to print a warning message. This is
452 // generally desirable, but it results in the unittest failing, as it doesn't 451 // generally desirable, but it results in the unittest failing, as it doesn't
453 // expect any messages on "stderr". So, temporarily disable messages. The 452 // expect any messages on "stderr". So, temporarily disable messages. The
454 // BPF_TEST() is guaranteed to turn messages back on, after the policy 453 // BPF_TEST() is guaranteed to turn messages back on, after the policy
455 // function has completed. 454 // function has completed.
456 setenv(kSandboxDebuggingEnv, "t", 0); 455 setenv(kSandboxDebuggingEnv, "t", 0);
457 Die::SuppressInfoMessages(true); 456 Die::SuppressInfoMessages(true);
458 457
459 // Some system calls must always be allowed, if our policy wants to make 458 // Some system calls must always be allowed, if our policy wants to make
460 // use of UnsafeTrap() 459 // use of UnsafeTrap()
461 if (sysno == __NR_rt_sigprocmask || sysno == __NR_rt_sigreturn 460 if (sysno == __NR_rt_sigprocmask || sysno == __NR_rt_sigreturn
462 #if defined(__NR_sigprocmask) 461 #if defined(__NR_sigprocmask)
463 || 462 ||
464 sysno == __NR_sigprocmask 463 sysno == __NR_sigprocmask
465 #endif 464 #endif
466 #if defined(__NR_sigreturn) 465 #if defined(__NR_sigreturn)
467 || 466 ||
468 sysno == __NR_sigreturn 467 sysno == __NR_sigreturn
469 #endif 468 #endif
470 ) { 469 ) {
471 return ErrorCode(ErrorCode::ERR_ALLOWED); 470 return ErrorCode(ErrorCode::ERR_ALLOWED);
472 } else if (sysno == __NR_getpid) { 471 } else if (sysno == __NR_getpid) {
473 // Disallow getpid() 472 // Disallow getpid()
474 return ErrorCode(EPERM); 473 return ErrorCode(EPERM);
475 } else if (Sandbox::IsValidSyscallNumber(sysno)) { 474 } else if (SandboxBPF::IsValidSyscallNumber(sysno)) {
476 // Allow (and count) all other system calls. 475 // Allow (and count) all other system calls.
477 return sandbox->UnsafeTrap(CountSyscalls, aux); 476 return sandbox->UnsafeTrap(CountSyscalls, aux);
478 } else { 477 } else {
479 return ErrorCode(ENOSYS); 478 return ErrorCode(ENOSYS);
480 } 479 }
481 } 480 }
482 481
483 BPF_TEST(SandboxBpf, GreyListedPolicy, GreyListedPolicy, int /* BPF_AUX */) { 482 BPF_TEST(SandboxBPF, GreyListedPolicy, GreyListedPolicy, int /* BPF_AUX */) {
484 BPF_ASSERT(syscall(__NR_getpid) == -1); 483 BPF_ASSERT(syscall(__NR_getpid) == -1);
485 BPF_ASSERT(errno == EPERM); 484 BPF_ASSERT(errno == EPERM);
486 BPF_ASSERT(BPF_AUX == 0); 485 BPF_ASSERT(BPF_AUX == 0);
487 BPF_ASSERT(syscall(__NR_geteuid) == syscall(__NR_getuid)); 486 BPF_ASSERT(syscall(__NR_geteuid) == syscall(__NR_getuid));
488 BPF_ASSERT(BPF_AUX == 2); 487 BPF_ASSERT(BPF_AUX == 2);
489 char name[17] = {}; 488 char name[17] = {};
490 BPF_ASSERT(!syscall(__NR_prctl, 489 BPF_ASSERT(!syscall(__NR_prctl,
491 PR_GET_NAME, 490 PR_GET_NAME,
492 name, 491 name,
493 (void*)NULL, 492 (void*)NULL,
494 (void*)NULL, 493 (void*)NULL,
495 (void*)NULL)); 494 (void*)NULL));
496 BPF_ASSERT(BPF_AUX == 3); 495 BPF_ASSERT(BPF_AUX == 3);
497 BPF_ASSERT(*name); 496 BPF_ASSERT(*name);
498 } 497 }
499 498
500 SANDBOX_TEST(SandboxBpf, EnableUnsafeTrapsInSigSysHandler) { 499 SANDBOX_TEST(SandboxBPF, EnableUnsafeTrapsInSigSysHandler) {
501 // Disabling warning messages that could confuse our test framework. 500 // Disabling warning messages that could confuse our test framework.
502 setenv(kSandboxDebuggingEnv, "t", 0); 501 setenv(kSandboxDebuggingEnv, "t", 0);
503 Die::SuppressInfoMessages(true); 502 Die::SuppressInfoMessages(true);
504 503
505 unsetenv(kSandboxDebuggingEnv); 504 unsetenv(kSandboxDebuggingEnv);
506 SANDBOX_ASSERT(Trap::EnableUnsafeTrapsInSigSysHandler() == false); 505 SANDBOX_ASSERT(Trap::EnableUnsafeTrapsInSigSysHandler() == false);
507 setenv(kSandboxDebuggingEnv, "", 1); 506 setenv(kSandboxDebuggingEnv, "", 1);
508 SANDBOX_ASSERT(Trap::EnableUnsafeTrapsInSigSysHandler() == false); 507 SANDBOX_ASSERT(Trap::EnableUnsafeTrapsInSigSysHandler() == false);
509 setenv(kSandboxDebuggingEnv, "t", 1); 508 setenv(kSandboxDebuggingEnv, "t", 1);
510 SANDBOX_ASSERT(Trap::EnableUnsafeTrapsInSigSysHandler() == true); 509 SANDBOX_ASSERT(Trap::EnableUnsafeTrapsInSigSysHandler() == true);
511 } 510 }
512 511
513 intptr_t PrctlHandler(const struct arch_seccomp_data& args, void*) { 512 intptr_t PrctlHandler(const struct arch_seccomp_data& args, void*) {
514 if (args.args[0] == PR_CAPBSET_DROP && static_cast<int>(args.args[1]) == -1) { 513 if (args.args[0] == PR_CAPBSET_DROP && static_cast<int>(args.args[1]) == -1) {
515 // prctl(PR_CAPBSET_DROP, -1) is never valid. The kernel will always 514 // prctl(PR_CAPBSET_DROP, -1) is never valid. The kernel will always
516 // return an error. But our handler allows this call. 515 // return an error. But our handler allows this call.
517 return 0; 516 return 0;
518 } else { 517 } else {
519 return Sandbox::ForwardSyscall(args); 518 return SandboxBPF::ForwardSyscall(args);
520 } 519 }
521 } 520 }
522 521
523 ErrorCode PrctlPolicy(Sandbox* sandbox, int sysno, void* aux) { 522 ErrorCode PrctlPolicy(SandboxBPF* sandbox, int sysno, void* aux) {
524 setenv(kSandboxDebuggingEnv, "t", 0); 523 setenv(kSandboxDebuggingEnv, "t", 0);
525 Die::SuppressInfoMessages(true); 524 Die::SuppressInfoMessages(true);
526 525
527 if (sysno == __NR_prctl) { 526 if (sysno == __NR_prctl) {
528 // Handle prctl() inside an UnsafeTrap() 527 // Handle prctl() inside an UnsafeTrap()
529 return sandbox->UnsafeTrap(PrctlHandler, NULL); 528 return sandbox->UnsafeTrap(PrctlHandler, NULL);
530 } else if (Sandbox::IsValidSyscallNumber(sysno)) { 529 } else if (SandboxBPF::IsValidSyscallNumber(sysno)) {
531 // Allow all other system calls. 530 // Allow all other system calls.
532 return ErrorCode(ErrorCode::ERR_ALLOWED); 531 return ErrorCode(ErrorCode::ERR_ALLOWED);
533 } else { 532 } else {
534 return ErrorCode(ENOSYS); 533 return ErrorCode(ENOSYS);
535 } 534 }
536 } 535 }
537 536
538 BPF_TEST(SandboxBpf, ForwardSyscall, PrctlPolicy) { 537 BPF_TEST(SandboxBPF, ForwardSyscall, PrctlPolicy) {
539 // This call should never be allowed. But our policy will intercept it and 538 // This call should never be allowed. But our policy will intercept it and
540 // let it pass successfully. 539 // let it pass successfully.
541 BPF_ASSERT( 540 BPF_ASSERT(
542 !prctl(PR_CAPBSET_DROP, -1, (void*)NULL, (void*)NULL, (void*)NULL)); 541 !prctl(PR_CAPBSET_DROP, -1, (void*)NULL, (void*)NULL, (void*)NULL));
543 542
544 // Verify that the call will fail, if it makes it all the way to the kernel. 543 // Verify that the call will fail, if it makes it all the way to the kernel.
545 BPF_ASSERT( 544 BPF_ASSERT(
546 prctl(PR_CAPBSET_DROP, -2, (void*)NULL, (void*)NULL, (void*)NULL) == -1); 545 prctl(PR_CAPBSET_DROP, -2, (void*)NULL, (void*)NULL, (void*)NULL) == -1);
547 546
548 // And verify that other uses of prctl() work just fine. 547 // And verify that other uses of prctl() work just fine.
549 char name[17] = {}; 548 char name[17] = {};
550 BPF_ASSERT(!syscall(__NR_prctl, 549 BPF_ASSERT(!syscall(__NR_prctl,
551 PR_GET_NAME, 550 PR_GET_NAME,
552 name, 551 name,
553 (void*)NULL, 552 (void*)NULL,
554 (void*)NULL, 553 (void*)NULL,
555 (void*)NULL)); 554 (void*)NULL));
556 BPF_ASSERT(*name); 555 BPF_ASSERT(*name);
557 556
558 // Finally, verify that system calls other than prctl() are completely 557 // Finally, verify that system calls other than prctl() are completely
559 // unaffected by our policy. 558 // unaffected by our policy.
560 struct utsname uts = {}; 559 struct utsname uts = {};
561 BPF_ASSERT(!uname(&uts)); 560 BPF_ASSERT(!uname(&uts));
562 BPF_ASSERT(!strcmp(uts.sysname, "Linux")); 561 BPF_ASSERT(!strcmp(uts.sysname, "Linux"));
563 } 562 }
564 563
565 intptr_t AllowRedirectedSyscall(const struct arch_seccomp_data& args, void*) { 564 intptr_t AllowRedirectedSyscall(const struct arch_seccomp_data& args, void*) {
566 return Sandbox::ForwardSyscall(args); 565 return SandboxBPF::ForwardSyscall(args);
567 } 566 }
568 567
569 ErrorCode RedirectAllSyscallsPolicy(Sandbox* sandbox, int sysno, void* aux) { 568 ErrorCode RedirectAllSyscallsPolicy(SandboxBPF* sandbox, int sysno, void* aux) {
570 setenv(kSandboxDebuggingEnv, "t", 0); 569 setenv(kSandboxDebuggingEnv, "t", 0);
571 Die::SuppressInfoMessages(true); 570 Die::SuppressInfoMessages(true);
572 571
573 // Some system calls must always be allowed, if our policy wants to make 572 // Some system calls must always be allowed, if our policy wants to make
574 // use of UnsafeTrap() 573 // use of UnsafeTrap()
575 if (sysno == __NR_rt_sigprocmask || sysno == __NR_rt_sigreturn 574 if (sysno == __NR_rt_sigprocmask || sysno == __NR_rt_sigreturn
576 #if defined(__NR_sigprocmask) 575 #if defined(__NR_sigprocmask)
577 || 576 ||
578 sysno == __NR_sigprocmask 577 sysno == __NR_sigprocmask
579 #endif 578 #endif
580 #if defined(__NR_sigreturn) 579 #if defined(__NR_sigreturn)
581 || 580 ||
582 sysno == __NR_sigreturn 581 sysno == __NR_sigreturn
583 #endif 582 #endif
584 ) { 583 ) {
585 return ErrorCode(ErrorCode::ERR_ALLOWED); 584 return ErrorCode(ErrorCode::ERR_ALLOWED);
586 } else if (Sandbox::IsValidSyscallNumber(sysno)) { 585 } else if (SandboxBPF::IsValidSyscallNumber(sysno)) {
587 return sandbox->UnsafeTrap(AllowRedirectedSyscall, aux); 586 return sandbox->UnsafeTrap(AllowRedirectedSyscall, aux);
588 } else { 587 } else {
589 return ErrorCode(ENOSYS); 588 return ErrorCode(ENOSYS);
590 } 589 }
591 } 590 }
592 591
593 int bus_handler_fd_ = -1; 592 int bus_handler_fd_ = -1;
594 593
595 void SigBusHandler(int, siginfo_t* info, void* void_context) { 594 void SigBusHandler(int, siginfo_t* info, void* void_context) {
596 BPF_ASSERT(write(bus_handler_fd_, "\x55", 1) == 1); 595 BPF_ASSERT(write(bus_handler_fd_, "\x55", 1) == 1);
597 } 596 }
598 597
599 BPF_TEST(SandboxBpf, SigBus, RedirectAllSyscallsPolicy) { 598 BPF_TEST(SandboxBPF, SigBus, RedirectAllSyscallsPolicy) {
600 // We use the SIGBUS bit in the signal mask as a thread-local boolean 599 // We use the SIGBUS bit in the signal mask as a thread-local boolean
601 // value in the implementation of UnsafeTrap(). This is obviously a bit 600 // value in the implementation of UnsafeTrap(). This is obviously a bit
602 // of a hack that could conceivably interfere with code that uses SIGBUS 601 // of a hack that could conceivably interfere with code that uses SIGBUS
603 // in more traditional ways. This test verifies that basic functionality 602 // in more traditional ways. This test verifies that basic functionality
604 // of SIGBUS is not impacted, but it is certainly possibly to construe 603 // of SIGBUS is not impacted, but it is certainly possibly to construe
605 // more complex uses of signals where our use of the SIGBUS mask is not 604 // more complex uses of signals where our use of the SIGBUS mask is not
606 // 100% transparent. This is expected behavior. 605 // 100% transparent. This is expected behavior.
607 int fds[2]; 606 int fds[2];
608 BPF_ASSERT(pipe(fds) == 0); 607 BPF_ASSERT(pipe(fds) == 0);
609 bus_handler_fd_ = fds[1]; 608 bus_handler_fd_ = fds[1];
610 struct sigaction sa = {}; 609 struct sigaction sa = {};
611 sa.sa_sigaction = SigBusHandler; 610 sa.sa_sigaction = SigBusHandler;
612 sa.sa_flags = SA_SIGINFO; 611 sa.sa_flags = SA_SIGINFO;
613 BPF_ASSERT(sigaction(SIGBUS, &sa, NULL) == 0); 612 BPF_ASSERT(sigaction(SIGBUS, &sa, NULL) == 0);
614 raise(SIGBUS); 613 raise(SIGBUS);
615 char c = '\000'; 614 char c = '\000';
616 BPF_ASSERT(read(fds[0], &c, 1) == 1); 615 BPF_ASSERT(read(fds[0], &c, 1) == 1);
617 BPF_ASSERT(close(fds[0]) == 0); 616 BPF_ASSERT(close(fds[0]) == 0);
618 BPF_ASSERT(close(fds[1]) == 0); 617 BPF_ASSERT(close(fds[1]) == 0);
619 BPF_ASSERT(c == 0x55); 618 BPF_ASSERT(c == 0x55);
620 } 619 }
621 620
622 BPF_TEST(SandboxBpf, SigMask, RedirectAllSyscallsPolicy) { 621 BPF_TEST(SandboxBPF, SigMask, RedirectAllSyscallsPolicy) {
623 // Signal masks are potentially tricky to handle. For instance, if we 622 // Signal masks are potentially tricky to handle. For instance, if we
624 // ever tried to update them from inside a Trap() or UnsafeTrap() handler, 623 // ever tried to update them from inside a Trap() or UnsafeTrap() handler,
625 // the call to sigreturn() at the end of the signal handler would undo 624 // the call to sigreturn() at the end of the signal handler would undo
626 // all of our efforts. So, it makes sense to test that sigprocmask() 625 // all of our efforts. So, it makes sense to test that sigprocmask()
627 // works, even if we have a policy in place that makes use of UnsafeTrap(). 626 // works, even if we have a policy in place that makes use of UnsafeTrap().
628 // In practice, this works because we force sigprocmask() to be handled 627 // In practice, this works because we force sigprocmask() to be handled
629 // entirely in the kernel. 628 // entirely in the kernel.
630 sigset_t mask0, mask1, mask2; 629 sigset_t mask0, mask1, mask2;
631 630
632 // Call sigprocmask() to verify that SIGUSR2 wasn't blocked, if we didn't 631 // Call sigprocmask() to verify that SIGUSR2 wasn't blocked, if we didn't
633 // change the mask (it shouldn't have been, as it isn't blocked by default 632 // change the mask (it shouldn't have been, as it isn't blocked by default
634 // in POSIX). 633 // in POSIX).
635 // 634 //
636 // Use SIGUSR2 because Android seems to use SIGUSR1 for some purpose. 635 // Use SIGUSR2 because Android seems to use SIGUSR1 for some purpose.
637 sigemptyset(&mask0); 636 sigemptyset(&mask0);
638 BPF_ASSERT(!sigprocmask(SIG_BLOCK, &mask0, &mask1)); 637 BPF_ASSERT(!sigprocmask(SIG_BLOCK, &mask0, &mask1));
639 BPF_ASSERT(!sigismember(&mask1, SIGUSR2)); 638 BPF_ASSERT(!sigismember(&mask1, SIGUSR2));
640 639
641 // Try again, and this time we verify that we can block it. This 640 // Try again, and this time we verify that we can block it. This
642 // requires a second call to sigprocmask(). 641 // requires a second call to sigprocmask().
643 sigaddset(&mask0, SIGUSR2); 642 sigaddset(&mask0, SIGUSR2);
644 BPF_ASSERT(!sigprocmask(SIG_BLOCK, &mask0, NULL)); 643 BPF_ASSERT(!sigprocmask(SIG_BLOCK, &mask0, NULL));
645 BPF_ASSERT(!sigprocmask(SIG_BLOCK, NULL, &mask2)); 644 BPF_ASSERT(!sigprocmask(SIG_BLOCK, NULL, &mask2));
646 BPF_ASSERT(sigismember(&mask2, SIGUSR2)); 645 BPF_ASSERT(sigismember(&mask2, SIGUSR2));
647 } 646 }
648 647
649 BPF_TEST(SandboxBpf, UnsafeTrapWithErrno, RedirectAllSyscallsPolicy) { 648 BPF_TEST(SandboxBPF, UnsafeTrapWithErrno, RedirectAllSyscallsPolicy) {
650 // An UnsafeTrap() (or for that matter, a Trap()) has to report error 649 // An UnsafeTrap() (or for that matter, a Trap()) has to report error
651 // conditions by returning an exit code in the range -1..-4096. This 650 // conditions by returning an exit code in the range -1..-4096. This
652 // should happen automatically if using ForwardSyscall(). If the TrapFnc() 651 // should happen automatically if using ForwardSyscall(). If the TrapFnc()
653 // uses some other method to make system calls, then it is responsible 652 // uses some other method to make system calls, then it is responsible
654 // for computing the correct return code. 653 // for computing the correct return code.
655 // This test verifies that ForwardSyscall() does the correct thing. 654 // This test verifies that ForwardSyscall() does the correct thing.
656 655
657 // The glibc system wrapper will ultimately set errno for us. So, from normal 656 // The glibc system wrapper will ultimately set errno for us. So, from normal
658 // userspace, all of this should be completely transparent. 657 // userspace, all of this should be completely transparent.
659 errno = 0; 658 errno = 0;
660 BPF_ASSERT(close(-1) == -1); 659 BPF_ASSERT(close(-1) == -1);
661 BPF_ASSERT(errno == EBADF); 660 BPF_ASSERT(errno == EBADF);
662 661
663 // Explicitly avoid the glibc wrapper. This is not normally the way anybody 662 // Explicitly avoid the glibc wrapper. This is not normally the way anybody
664 // would make system calls, but it allows us to verify that we don't 663 // would make system calls, but it allows us to verify that we don't
665 // accidentally mess with errno, when we shouldn't. 664 // accidentally mess with errno, when we shouldn't.
666 errno = 0; 665 errno = 0;
667 struct arch_seccomp_data args = {}; 666 struct arch_seccomp_data args = {};
668 args.nr = __NR_close; 667 args.nr = __NR_close;
669 args.args[0] = -1; 668 args.args[0] = -1;
670 BPF_ASSERT(Sandbox::ForwardSyscall(args) == -EBADF); 669 BPF_ASSERT(SandboxBPF::ForwardSyscall(args) == -EBADF);
671 BPF_ASSERT(errno == 0); 670 BPF_ASSERT(errno == 0);
672 } 671 }
673 672
674 // Test a trap handler that makes use of a broker process to open(). 673 // Test a trap handler that makes use of a broker process to open().
675 674
676 class InitializedOpenBroker { 675 class InitializedOpenBroker {
677 public: 676 public:
678 InitializedOpenBroker() : initialized_(false) { 677 InitializedOpenBroker() : initialized_(false) {
679 std::vector<std::string> allowed_files; 678 std::vector<std::string> allowed_files;
680 allowed_files.push_back("/proc/allowed"); 679 allowed_files.push_back("/proc/allowed");
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
712 // the openat() system call. 711 // the openat() system call.
713 BPF_ASSERT(static_cast<int>(args.args[0]) == AT_FDCWD); 712 BPF_ASSERT(static_cast<int>(args.args[0]) == AT_FDCWD);
714 return broker_process->Open(reinterpret_cast<const char*>(args.args[1]), 713 return broker_process->Open(reinterpret_cast<const char*>(args.args[1]),
715 static_cast<int>(args.args[2])); 714 static_cast<int>(args.args[2]));
716 default: 715 default:
717 BPF_ASSERT(false); 716 BPF_ASSERT(false);
718 return -ENOSYS; 717 return -ENOSYS;
719 } 718 }
720 } 719 }
721 720
722 ErrorCode DenyOpenPolicy(Sandbox* sandbox, int sysno, void* aux) { 721 ErrorCode DenyOpenPolicy(SandboxBPF* sandbox, int sysno, void* aux) {
723 InitializedOpenBroker* iob = static_cast<InitializedOpenBroker*>(aux); 722 InitializedOpenBroker* iob = static_cast<InitializedOpenBroker*>(aux);
724 if (!Sandbox::IsValidSyscallNumber(sysno)) { 723 if (!SandboxBPF::IsValidSyscallNumber(sysno)) {
725 return ErrorCode(ENOSYS); 724 return ErrorCode(ENOSYS);
726 } 725 }
727 726
728 switch (sysno) { 727 switch (sysno) {
729 case __NR_access: 728 case __NR_access:
730 case __NR_open: 729 case __NR_open:
731 case __NR_openat: 730 case __NR_openat:
732 // We get a InitializedOpenBroker class, but our trap handler wants 731 // We get a InitializedOpenBroker class, but our trap handler wants
733 // the BrokerProcess object. 732 // the BrokerProcess object.
734 return ErrorCode( 733 return ErrorCode(
735 sandbox->Trap(BrokerOpenTrapHandler, iob->broker_process())); 734 sandbox->Trap(BrokerOpenTrapHandler, iob->broker_process()));
736 default: 735 default:
737 return ErrorCode(ErrorCode::ERR_ALLOWED); 736 return ErrorCode(ErrorCode::ERR_ALLOWED);
738 } 737 }
739 } 738 }
740 739
741 // We use a InitializedOpenBroker class, so that we can run unsandboxed 740 // We use a InitializedOpenBroker class, so that we can run unsandboxed
742 // code in its constructor, which is the only way to do so in a BPF_TEST. 741 // code in its constructor, which is the only way to do so in a BPF_TEST.
743 BPF_TEST(SandboxBpf, 742 BPF_TEST(SandboxBPF,
744 UseOpenBroker, 743 UseOpenBroker,
745 DenyOpenPolicy, 744 DenyOpenPolicy,
746 InitializedOpenBroker /* BPF_AUX */) { 745 InitializedOpenBroker /* BPF_AUX */) {
747 BPF_ASSERT(BPF_AUX.initialized()); 746 BPF_ASSERT(BPF_AUX.initialized());
748 BrokerProcess* broker_process = BPF_AUX.broker_process(); 747 BrokerProcess* broker_process = BPF_AUX.broker_process();
749 BPF_ASSERT(broker_process != NULL); 748 BPF_ASSERT(broker_process != NULL);
750 749
751 // First, use the broker "manually" 750 // First, use the broker "manually"
752 BPF_ASSERT(broker_process->Open("/proc/denied", O_RDONLY) == -EPERM); 751 BPF_ASSERT(broker_process->Open("/proc/denied", O_RDONLY) == -EPERM);
753 BPF_ASSERT(broker_process->Access("/proc/denied", R_OK) == -EPERM); 752 BPF_ASSERT(broker_process->Access("/proc/denied", R_OK) == -EPERM);
(...skipping 24 matching lines...) Expand all
778 777
779 // This is also white listed and does exist. 778 // This is also white listed and does exist.
780 int cpu_info_access = access("/proc/cpuinfo", R_OK); 779 int cpu_info_access = access("/proc/cpuinfo", R_OK);
781 BPF_ASSERT(cpu_info_access == 0); 780 BPF_ASSERT(cpu_info_access == 0);
782 int cpu_info_fd = open("/proc/cpuinfo", O_RDONLY); 781 int cpu_info_fd = open("/proc/cpuinfo", O_RDONLY);
783 BPF_ASSERT(cpu_info_fd >= 0); 782 BPF_ASSERT(cpu_info_fd >= 0);
784 char buf[1024]; 783 char buf[1024];
785 BPF_ASSERT(read(cpu_info_fd, buf, sizeof(buf)) > 0); 784 BPF_ASSERT(read(cpu_info_fd, buf, sizeof(buf)) > 0);
786 } 785 }
787 786
788 // Simple test demonstrating how to use Sandbox::Cond() 787 // Simple test demonstrating how to use SandboxBPF::Cond()
789 788
790 ErrorCode SimpleCondTestPolicy(Sandbox* sandbox, int sysno, void*) { 789 ErrorCode SimpleCondTestPolicy(SandboxBPF* sandbox, int sysno, void*) {
791 if (!Sandbox::IsValidSyscallNumber(sysno)) { 790 if (!SandboxBPF::IsValidSyscallNumber(sysno)) {
792 // FIXME: we should really not have to do that in a trivial policy 791 // FIXME: we should really not have to do that in a trivial policy
793 return ErrorCode(ENOSYS); 792 return ErrorCode(ENOSYS);
794 } 793 }
795 794
796 // We deliberately return unusual errno values upon failure, so that we 795 // We deliberately return unusual errno values upon failure, so that we
797 // can uniquely test for these values. In a "real" policy, you would want 796 // can uniquely test for these values. In a "real" policy, you would want
798 // to return more traditional values. 797 // to return more traditional values.
799 switch (sysno) { 798 switch (sysno) {
800 case __NR_open: 799 case __NR_open:
801 // Allow opening files for reading, but don't allow writing. 800 // Allow opening files for reading, but don't allow writing.
(...skipping 16 matching lines...) Expand all
818 ErrorCode::TP_32BIT, 817 ErrorCode::TP_32BIT,
819 ErrorCode::OP_EQUAL, 818 ErrorCode::OP_EQUAL,
820 PR_GET_DUMPABLE, 819 PR_GET_DUMPABLE,
821 ErrorCode(ErrorCode::ERR_ALLOWED), 820 ErrorCode(ErrorCode::ERR_ALLOWED),
822 ErrorCode(ENOMEM))); 821 ErrorCode(ENOMEM)));
823 default: 822 default:
824 return ErrorCode(ErrorCode::ERR_ALLOWED); 823 return ErrorCode(ErrorCode::ERR_ALLOWED);
825 } 824 }
826 } 825 }
827 826
828 BPF_TEST(SandboxBpf, SimpleCondTest, SimpleCondTestPolicy) { 827 BPF_TEST(SandboxBPF, SimpleCondTest, SimpleCondTestPolicy) {
829 int fd; 828 int fd;
830 BPF_ASSERT((fd = open("/proc/self/comm", O_RDWR)) == -1); 829 BPF_ASSERT((fd = open("/proc/self/comm", O_RDWR)) == -1);
831 BPF_ASSERT(errno == EROFS); 830 BPF_ASSERT(errno == EROFS);
832 BPF_ASSERT((fd = open("/proc/self/comm", O_RDONLY)) >= 0); 831 BPF_ASSERT((fd = open("/proc/self/comm", O_RDONLY)) >= 0);
833 close(fd); 832 close(fd);
834 833
835 int ret; 834 int ret;
836 BPF_ASSERT((ret = prctl(PR_GET_DUMPABLE)) >= 0); 835 BPF_ASSERT((ret = prctl(PR_GET_DUMPABLE)) >= 0);
837 BPF_ASSERT(prctl(PR_SET_DUMPABLE, 1 - ret) == 0); 836 BPF_ASSERT(prctl(PR_SET_DUMPABLE, 1 - ret) == 0);
838 BPF_ASSERT(prctl(PR_GET_ENDIAN, &ret) == -1); 837 BPF_ASSERT(prctl(PR_GET_ENDIAN, &ret) == -1);
839 BPF_ASSERT(errno == ENOMEM); 838 BPF_ASSERT(errno == ENOMEM);
840 } 839 }
841 840
842 // This test exercises the Sandbox::Cond() method by building a complex 841 // This test exercises the SandboxBPF::Cond() method by building a complex
843 // tree of conditional equality operations. It then makes system calls and 842 // tree of conditional equality operations. It then makes system calls and
844 // verifies that they return the values that we expected from our BPF 843 // verifies that they return the values that we expected from our BPF
845 // program. 844 // program.
846 class EqualityStressTest { 845 class EqualityStressTest {
847 public: 846 public:
848 EqualityStressTest() { 847 EqualityStressTest() {
849 // We want a deterministic test 848 // We want a deterministic test
850 srand(0); 849 srand(0);
851 850
852 // Iterates over system call numbers and builds a random tree of 851 // Iterates over system call numbers and builds a random tree of
(...skipping 19 matching lines...) Expand all
872 } 871 }
873 872
874 ~EqualityStressTest() { 873 ~EqualityStressTest() {
875 for (std::vector<ArgValue*>::iterator iter = arg_values_.begin(); 874 for (std::vector<ArgValue*>::iterator iter = arg_values_.begin();
876 iter != arg_values_.end(); 875 iter != arg_values_.end();
877 ++iter) { 876 ++iter) {
878 DeleteArgValue(*iter); 877 DeleteArgValue(*iter);
879 } 878 }
880 } 879 }
881 880
882 ErrorCode Policy(Sandbox* sandbox, int sysno) { 881 ErrorCode Policy(SandboxBPF* sandbox, int sysno) {
883 if (!Sandbox::IsValidSyscallNumber(sysno)) { 882 if (!SandboxBPF::IsValidSyscallNumber(sysno)) {
884 // FIXME: we should really not have to do that in a trivial policy 883 // FIXME: we should really not have to do that in a trivial policy
885 return ErrorCode(ENOSYS); 884 return ErrorCode(ENOSYS);
886 } else if (sysno < 0 || sysno >= (int)arg_values_.size() || 885 } else if (sysno < 0 || sysno >= (int)arg_values_.size() ||
887 IsReservedSyscall(sysno)) { 886 IsReservedSyscall(sysno)) {
888 // We only return ErrorCode values for the system calls that 887 // We only return ErrorCode values for the system calls that
889 // are part of our test data. Every other system call remains 888 // are part of our test data. Every other system call remains
890 // allowed. 889 // allowed.
891 return ErrorCode(ErrorCode::ERR_ALLOWED); 890 return ErrorCode(ErrorCode::ERR_ALLOWED);
892 } else { 891 } else {
893 // ToErrorCode() turns an ArgValue object into an ErrorCode that is 892 // ToErrorCode() turns an ArgValue object into an ErrorCode that is
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1032 } 1031 }
1033 delete[] arg_value->tests; 1032 delete[] arg_value->tests;
1034 } 1033 }
1035 if (!arg_value->err) { 1034 if (!arg_value->err) {
1036 DeleteArgValue(arg_value->arg_value); 1035 DeleteArgValue(arg_value->arg_value);
1037 } 1036 }
1038 delete arg_value; 1037 delete arg_value;
1039 } 1038 }
1040 } 1039 }
1041 1040
1042 ErrorCode ToErrorCode(Sandbox* sandbox, ArgValue* arg_value) { 1041 ErrorCode ToErrorCode(SandboxBPF* sandbox, ArgValue* arg_value) {
1043 // Compute the ErrorCode that should be returned, if none of our 1042 // Compute the ErrorCode that should be returned, if none of our
1044 // tests succeed (i.e. the system call parameter doesn't match any 1043 // tests succeed (i.e. the system call parameter doesn't match any
1045 // of the values in arg_value->tests[].k_value). 1044 // of the values in arg_value->tests[].k_value).
1046 ErrorCode err; 1045 ErrorCode err;
1047 if (arg_value->err) { 1046 if (arg_value->err) {
1048 // If this was a leaf node, return the errno value that we expect to 1047 // If this was a leaf node, return the errno value that we expect to
1049 // return from the BPF filter program. 1048 // return from the BPF filter program.
1050 err = ErrorCode(arg_value->err); 1049 err = ErrorCode(arg_value->err);
1051 } else { 1050 } else {
1052 // If this wasn't a leaf node yet, recursively descend into the rest 1051 // If this wasn't a leaf node yet, recursively descend into the rest
1053 // of the tree. This will end up adding a few more Sandbox::Cond() 1052 // of the tree. This will end up adding a few more SandboxBPF::Cond()
1054 // tests to our ErrorCode. 1053 // tests to our ErrorCode.
1055 err = ToErrorCode(sandbox, arg_value->arg_value); 1054 err = ToErrorCode(sandbox, arg_value->arg_value);
1056 } 1055 }
1057 1056
1058 // Now, iterate over all the test cases that we want to compare against. 1057 // Now, iterate over all the test cases that we want to compare against.
1059 // This builds a chain of Sandbox::Cond() tests 1058 // This builds a chain of SandboxBPF::Cond() tests
1060 // (aka "if ... elif ... elif ... elif ... fi") 1059 // (aka "if ... elif ... elif ... elif ... fi")
1061 for (int n = arg_value->size; n-- > 0;) { 1060 for (int n = arg_value->size; n-- > 0;) {
1062 ErrorCode matched; 1061 ErrorCode matched;
1063 // Again, we distinguish between leaf nodes and subtrees. 1062 // Again, we distinguish between leaf nodes and subtrees.
1064 if (arg_value->tests[n].err) { 1063 if (arg_value->tests[n].err) {
1065 matched = ErrorCode(arg_value->tests[n].err); 1064 matched = ErrorCode(arg_value->tests[n].err);
1066 } else { 1065 } else {
1067 matched = ToErrorCode(sandbox, arg_value->tests[n].arg_value); 1066 matched = ToErrorCode(sandbox, arg_value->tests[n].arg_value);
1068 } 1067 }
1069 // For now, all of our tests are limited to 32bit. 1068 // For now, all of our tests are limited to 32bit.
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1133 std::vector<ArgValue*> arg_values_; 1132 std::vector<ArgValue*> arg_values_;
1134 1133
1135 // Don't increase these values. We are pushing the limits of the maximum 1134 // Don't increase these values. We are pushing the limits of the maximum
1136 // BPF program that the kernel will allow us to load. If the values are 1135 // BPF program that the kernel will allow us to load. If the values are
1137 // increased too much, the test will start failing. 1136 // increased too much, the test will start failing.
1138 static const int kNumTestCases = 40; 1137 static const int kNumTestCases = 40;
1139 static const int kMaxFanOut = 3; 1138 static const int kMaxFanOut = 3;
1140 static const int kMaxArgs = 6; 1139 static const int kMaxArgs = 6;
1141 }; 1140 };
1142 1141
1143 ErrorCode EqualityStressTestPolicy(Sandbox* sandbox, int sysno, void* aux) { 1142 ErrorCode EqualityStressTestPolicy(SandboxBPF* sandbox, int sysno, void* aux) {
1144 return reinterpret_cast<EqualityStressTest*>(aux)->Policy(sandbox, sysno); 1143 return reinterpret_cast<EqualityStressTest*>(aux)->Policy(sandbox, sysno);
1145 } 1144 }
1146 1145
1147 BPF_TEST(SandboxBpf, 1146 BPF_TEST(SandboxBPF,
1148 EqualityTests, 1147 EqualityTests,
1149 EqualityStressTestPolicy, 1148 EqualityStressTestPolicy,
1150 EqualityStressTest /* BPF_AUX */) { 1149 EqualityStressTest /* BPF_AUX */) {
1151 BPF_AUX.VerifyFilter(); 1150 BPF_AUX.VerifyFilter();
1152 } 1151 }
1153 1152
1154 ErrorCode EqualityArgumentWidthPolicy(Sandbox* sandbox, int sysno, void*) { 1153 ErrorCode EqualityArgumentWidthPolicy(SandboxBPF* sandbox, int sysno, void*) {
1155 if (!Sandbox::IsValidSyscallNumber(sysno)) { 1154 if (!SandboxBPF::IsValidSyscallNumber(sysno)) {
1156 // FIXME: we should really not have to do that in a trivial policy 1155 // FIXME: we should really not have to do that in a trivial policy
1157 return ErrorCode(ENOSYS); 1156 return ErrorCode(ENOSYS);
1158 } else if (sysno == __NR_uname) { 1157 } else if (sysno == __NR_uname) {
1159 return sandbox->Cond( 1158 return sandbox->Cond(
1160 0, 1159 0,
1161 ErrorCode::TP_32BIT, 1160 ErrorCode::TP_32BIT,
1162 ErrorCode::OP_EQUAL, 1161 ErrorCode::OP_EQUAL,
1163 0, 1162 0,
1164 sandbox->Cond(1, 1163 sandbox->Cond(1,
1165 ErrorCode::TP_32BIT, 1164 ErrorCode::TP_32BIT,
(...skipping 13 matching lines...) Expand all
1179 ErrorCode::TP_64BIT, 1178 ErrorCode::TP_64BIT,
1180 ErrorCode::OP_EQUAL, 1179 ErrorCode::OP_EQUAL,
1181 0x55555555AAAAAAAAULL, 1180 0x55555555AAAAAAAAULL,
1182 ErrorCode(1), 1181 ErrorCode(1),
1183 ErrorCode(2))); 1182 ErrorCode(2)));
1184 } else { 1183 } else {
1185 return ErrorCode(ErrorCode::ERR_ALLOWED); 1184 return ErrorCode(ErrorCode::ERR_ALLOWED);
1186 } 1185 }
1187 } 1186 }
1188 1187
1189 BPF_TEST(SandboxBpf, EqualityArgumentWidth, EqualityArgumentWidthPolicy) { 1188 BPF_TEST(SandboxBPF, EqualityArgumentWidth, EqualityArgumentWidthPolicy) {
1190 BPF_ASSERT(SandboxSyscall(__NR_uname, 0, 0x55555555) == -1); 1189 BPF_ASSERT(SandboxSyscall(__NR_uname, 0, 0x55555555) == -1);
1191 BPF_ASSERT(SandboxSyscall(__NR_uname, 0, 0xAAAAAAAA) == -2); 1190 BPF_ASSERT(SandboxSyscall(__NR_uname, 0, 0xAAAAAAAA) == -2);
1192 #if __SIZEOF_POINTER__ > 4 1191 #if __SIZEOF_POINTER__ > 4
1193 // On 32bit machines, there is no way to pass a 64bit argument through the 1192 // On 32bit machines, there is no way to pass a 64bit argument through the
1194 // syscall interface. So, we have to skip the part of the test that requires 1193 // syscall interface. So, we have to skip the part of the test that requires
1195 // 64bit arguments. 1194 // 64bit arguments.
1196 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x55555555AAAAAAAAULL) == -1); 1195 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x55555555AAAAAAAAULL) == -1);
1197 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x5555555500000000ULL) == -2); 1196 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x5555555500000000ULL) == -2);
1198 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x5555555511111111ULL) == -2); 1197 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x5555555511111111ULL) == -2);
1199 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x11111111AAAAAAAAULL) == -2); 1198 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x11111111AAAAAAAAULL) == -2);
1200 #else 1199 #else
1201 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x55555555) == -2); 1200 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x55555555) == -2);
1202 #endif 1201 #endif
1203 } 1202 }
1204 1203
1205 #if __SIZEOF_POINTER__ > 4 1204 #if __SIZEOF_POINTER__ > 4
1206 // On 32bit machines, there is no way to pass a 64bit argument through the 1205 // On 32bit machines, there is no way to pass a 64bit argument through the
1207 // syscall interface. So, we have to skip the part of the test that requires 1206 // syscall interface. So, we have to skip the part of the test that requires
1208 // 64bit arguments. 1207 // 64bit arguments.
1209 BPF_DEATH_TEST(SandboxBpf, 1208 BPF_DEATH_TEST(SandboxBPF,
1210 EqualityArgumentUnallowed64bit, 1209 EqualityArgumentUnallowed64bit,
1211 DEATH_MESSAGE("Unexpected 64bit argument detected"), 1210 DEATH_MESSAGE("Unexpected 64bit argument detected"),
1212 EqualityArgumentWidthPolicy) { 1211 EqualityArgumentWidthPolicy) {
1213 SandboxSyscall(__NR_uname, 0, 0x5555555555555555ULL); 1212 SandboxSyscall(__NR_uname, 0, 0x5555555555555555ULL);
1214 } 1213 }
1215 #endif 1214 #endif
1216 1215
1217 ErrorCode EqualityWithNegativeArgumentsPolicy(Sandbox* sandbox, 1216 ErrorCode EqualityWithNegativeArgumentsPolicy(SandboxBPF* sandbox,
1218 int sysno, 1217 int sysno,
1219 void*) { 1218 void*) {
1220 if (!Sandbox::IsValidSyscallNumber(sysno)) { 1219 if (!SandboxBPF::IsValidSyscallNumber(sysno)) {
1221 // FIXME: we should really not have to do that in a trivial policy 1220 // FIXME: we should really not have to do that in a trivial policy
1222 return ErrorCode(ENOSYS); 1221 return ErrorCode(ENOSYS);
1223 } else if (sysno == __NR_uname) { 1222 } else if (sysno == __NR_uname) {
1224 return sandbox->Cond(0, 1223 return sandbox->Cond(0,
1225 ErrorCode::TP_32BIT, 1224 ErrorCode::TP_32BIT,
1226 ErrorCode::OP_EQUAL, 1225 ErrorCode::OP_EQUAL,
1227 0xFFFFFFFF, 1226 0xFFFFFFFF,
1228 ErrorCode(1), 1227 ErrorCode(1),
1229 ErrorCode(2)); 1228 ErrorCode(2));
1230 } else { 1229 } else {
1231 return ErrorCode(ErrorCode::ERR_ALLOWED); 1230 return ErrorCode(ErrorCode::ERR_ALLOWED);
1232 } 1231 }
1233 } 1232 }
1234 1233
1235 BPF_TEST(SandboxBpf, 1234 BPF_TEST(SandboxBPF,
1236 EqualityWithNegativeArguments, 1235 EqualityWithNegativeArguments,
1237 EqualityWithNegativeArgumentsPolicy) { 1236 EqualityWithNegativeArgumentsPolicy) {
1238 BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF) == -1); 1237 BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF) == -1);
1239 BPF_ASSERT(SandboxSyscall(__NR_uname, -1) == -1); 1238 BPF_ASSERT(SandboxSyscall(__NR_uname, -1) == -1);
1240 BPF_ASSERT(SandboxSyscall(__NR_uname, -1LL) == -1); 1239 BPF_ASSERT(SandboxSyscall(__NR_uname, -1LL) == -1);
1241 } 1240 }
1242 1241
1243 #if __SIZEOF_POINTER__ > 4 1242 #if __SIZEOF_POINTER__ > 4
1244 BPF_DEATH_TEST(SandboxBpf, 1243 BPF_DEATH_TEST(SandboxBPF,
1245 EqualityWithNegative64bitArguments, 1244 EqualityWithNegative64bitArguments,
1246 DEATH_MESSAGE("Unexpected 64bit argument detected"), 1245 DEATH_MESSAGE("Unexpected 64bit argument detected"),
1247 EqualityWithNegativeArgumentsPolicy) { 1246 EqualityWithNegativeArgumentsPolicy) {
1248 // When expecting a 32bit system call argument, we look at the MSB of the 1247 // When expecting a 32bit system call argument, we look at the MSB of the
1249 // 64bit value and allow both "0" and "-1". But the latter is allowed only 1248 // 64bit value and allow both "0" and "-1". But the latter is allowed only
1250 // iff the LSB was negative. So, this death test should error out. 1249 // iff the LSB was negative. So, this death test should error out.
1251 BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF00000000LL) == -1); 1250 BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF00000000LL) == -1);
1252 } 1251 }
1253 #endif 1252 #endif
1254 ErrorCode AllBitTestPolicy(Sandbox *sandbox, int sysno, void *) { 1253 ErrorCode AllBitTestPolicy(SandboxBPF* sandbox, int sysno, void *) {
1255 // Test the OP_HAS_ALL_BITS conditional test operator with a couple of 1254 // Test the OP_HAS_ALL_BITS conditional test operator with a couple of
1256 // different bitmasks. We try to find bitmasks that could conceivably 1255 // different bitmasks. We try to find bitmasks that could conceivably
1257 // touch corner cases. 1256 // touch corner cases.
1258 // For all of these tests, we override the uname(). We can make use with 1257 // For all of these tests, we override the uname(). We can make use with
1259 // a single system call number, as we use the first system call argument to 1258 // a single system call number, as we use the first system call argument to
1260 // select the different bit masks that we want to test against. 1259 // select the different bit masks that we want to test against.
1261 if (!Sandbox::IsValidSyscallNumber(sysno)) { 1260 if (!SandboxBPF::IsValidSyscallNumber(sysno)) {
1262 // FIXME: we should really not have to do that in a trivial policy 1261 // FIXME: we should really not have to do that in a trivial policy
1263 return ErrorCode(ENOSYS); 1262 return ErrorCode(ENOSYS);
1264 } else if (sysno == __NR_uname) { 1263 } else if (sysno == __NR_uname) {
1265 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0, 1264 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0,
1266 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, 1265 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS,
1267 0x0, 1266 0x0,
1268 ErrorCode(1), ErrorCode(0)), 1267 ErrorCode(1), ErrorCode(0)),
1269 1268
1270 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 1, 1269 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 1,
1271 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, 1270 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS,
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1337 // exit code of -1 or 0. 1336 // exit code of -1 or 0.
1338 #define EXPECT_FAILURE 0 1337 #define EXPECT_FAILURE 0
1339 #define EXPECT_SUCCESS -1 1338 #define EXPECT_SUCCESS -1
1340 1339
1341 // A couple of our tests behave differently on 32bit and 64bit systems, as 1340 // A couple of our tests behave differently on 32bit and 64bit systems, as
1342 // there is no way for a 32bit system call to pass in a 64bit system call 1341 // there is no way for a 32bit system call to pass in a 64bit system call
1343 // argument "arg". 1342 // argument "arg".
1344 // We expect these tests to succeed on 64bit systems, but to tail on 32bit 1343 // We expect these tests to succeed on 64bit systems, but to tail on 32bit
1345 // systems. 1344 // systems.
1346 #define EXPT64_SUCCESS (sizeof(void*) > 4 ? EXPECT_SUCCESS : EXPECT_FAILURE) 1345 #define EXPT64_SUCCESS (sizeof(void*) > 4 ? EXPECT_SUCCESS : EXPECT_FAILURE)
1347 BPF_TEST(SandboxBpf, AllBitTests, AllBitTestPolicy) { 1346 BPF_TEST(SandboxBPF, AllBitTests, AllBitTestPolicy) {
1348 // 32bit test: all of 0x0 (should always be true) 1347 // 32bit test: all of 0x0 (should always be true)
1349 BITMASK_TEST( 0, 0, ALLBITS32, 0, EXPECT_SUCCESS); 1348 BITMASK_TEST( 0, 0, ALLBITS32, 0, EXPECT_SUCCESS);
1350 BITMASK_TEST( 0, 1, ALLBITS32, 0, EXPECT_SUCCESS); 1349 BITMASK_TEST( 0, 1, ALLBITS32, 0, EXPECT_SUCCESS);
1351 BITMASK_TEST( 0, 3, ALLBITS32, 0, EXPECT_SUCCESS); 1350 BITMASK_TEST( 0, 3, ALLBITS32, 0, EXPECT_SUCCESS);
1352 BITMASK_TEST( 0, 0xFFFFFFFFU, ALLBITS32, 0, EXPECT_SUCCESS); 1351 BITMASK_TEST( 0, 0xFFFFFFFFU, ALLBITS32, 0, EXPECT_SUCCESS);
1353 BITMASK_TEST( 0, -1LL, ALLBITS32, 0, EXPECT_SUCCESS); 1352 BITMASK_TEST( 0, -1LL, ALLBITS32, 0, EXPECT_SUCCESS);
1354 1353
1355 // 32bit test: all of 0x1 1354 // 32bit test: all of 0x1
1356 BITMASK_TEST( 1, 0, ALLBITS32, 0x1, EXPECT_FAILURE); 1355 BITMASK_TEST( 1, 0, ALLBITS32, 0x1, EXPECT_FAILURE);
1357 BITMASK_TEST( 1, 1, ALLBITS32, 0x1, EXPECT_SUCCESS); 1356 BITMASK_TEST( 1, 1, ALLBITS32, 0x1, EXPECT_SUCCESS);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1440 1439
1441 // 64bit test: all of 0x100000001 1440 // 64bit test: all of 0x100000001
1442 BITMASK_TEST(10, 0x000000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE); 1441 BITMASK_TEST(10, 0x000000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE);
1443 BITMASK_TEST(10, 0x000000001LL, ALLBITS64,0x100000001, EXPECT_FAILURE); 1442 BITMASK_TEST(10, 0x000000001LL, ALLBITS64,0x100000001, EXPECT_FAILURE);
1444 BITMASK_TEST(10, 0x100000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE); 1443 BITMASK_TEST(10, 0x100000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE);
1445 BITMASK_TEST(10, 0x100000001LL, ALLBITS64,0x100000001, EXPT64_SUCCESS); 1444 BITMASK_TEST(10, 0x100000001LL, ALLBITS64,0x100000001, EXPT64_SUCCESS);
1446 BITMASK_TEST(10, 0xFFFFFFFFU, ALLBITS64,0x100000001, EXPECT_FAILURE); 1445 BITMASK_TEST(10, 0xFFFFFFFFU, ALLBITS64,0x100000001, EXPECT_FAILURE);
1447 BITMASK_TEST(10, -1L, ALLBITS64,0x100000001, EXPT64_SUCCESS); 1446 BITMASK_TEST(10, -1L, ALLBITS64,0x100000001, EXPT64_SUCCESS);
1448 } 1447 }
1449 1448
1450 ErrorCode AnyBitTestPolicy(Sandbox* sandbox, int sysno, void*) { 1449 ErrorCode AnyBitTestPolicy(SandboxBPF* sandbox, int sysno, void*) {
1451 // Test the OP_HAS_ANY_BITS conditional test operator with a couple of 1450 // Test the OP_HAS_ANY_BITS conditional test operator with a couple of
1452 // different bitmasks. We try to find bitmasks that could conceivably 1451 // different bitmasks. We try to find bitmasks that could conceivably
1453 // touch corner cases. 1452 // touch corner cases.
1454 // For all of these tests, we override the uname(). We can make use with 1453 // For all of these tests, we override the uname(). We can make use with
1455 // a single system call number, as we use the first system call argument to 1454 // a single system call number, as we use the first system call argument to
1456 // select the different bit masks that we want to test against. 1455 // select the different bit masks that we want to test against.
1457 if (!Sandbox::IsValidSyscallNumber(sysno)) { 1456 if (!SandboxBPF::IsValidSyscallNumber(sysno)) {
1458 // FIXME: we should really not have to do that in a trivial policy 1457 // FIXME: we should really not have to do that in a trivial policy
1459 return ErrorCode(ENOSYS); 1458 return ErrorCode(ENOSYS);
1460 } else if (sysno == __NR_uname) { 1459 } else if (sysno == __NR_uname) {
1461 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0, 1460 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0,
1462 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, 1461 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS,
1463 0x0, 1462 0x0,
1464 ErrorCode(1), ErrorCode(0)), 1463 ErrorCode(1), ErrorCode(0)),
1465 1464
1466 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 1, 1465 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 1,
1467 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, 1466 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS,
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1514 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, 1513 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS,
1515 0x100000001ULL, 1514 0x100000001ULL,
1516 ErrorCode(1), ErrorCode(0)), 1515 ErrorCode(1), ErrorCode(0)),
1517 1516
1518 sandbox->Kill("Invalid test case number")))))))))))); 1517 sandbox->Kill("Invalid test case number"))))))))))));
1519 } else { 1518 } else {
1520 return ErrorCode(ErrorCode::ERR_ALLOWED); 1519 return ErrorCode(ErrorCode::ERR_ALLOWED);
1521 } 1520 }
1522 } 1521 }
1523 1522
1524 BPF_TEST(SandboxBpf, AnyBitTests, AnyBitTestPolicy) { 1523 BPF_TEST(SandboxBPF, AnyBitTests, AnyBitTestPolicy) {
1525 // 32bit test: any of 0x0 (should always be false) 1524 // 32bit test: any of 0x0 (should always be false)
1526 BITMASK_TEST( 0, 0, ANYBITS32, 0x0, EXPECT_FAILURE); 1525 BITMASK_TEST( 0, 0, ANYBITS32, 0x0, EXPECT_FAILURE);
1527 BITMASK_TEST( 0, 1, ANYBITS32, 0x0, EXPECT_FAILURE); 1526 BITMASK_TEST( 0, 1, ANYBITS32, 0x0, EXPECT_FAILURE);
1528 BITMASK_TEST( 0, 3, ANYBITS32, 0x0, EXPECT_FAILURE); 1527 BITMASK_TEST( 0, 3, ANYBITS32, 0x0, EXPECT_FAILURE);
1529 BITMASK_TEST( 0, 0xFFFFFFFFU, ANYBITS32, 0x0, EXPECT_FAILURE); 1528 BITMASK_TEST( 0, 0xFFFFFFFFU, ANYBITS32, 0x0, EXPECT_FAILURE);
1530 BITMASK_TEST( 0, -1LL, ANYBITS32, 0x0, EXPECT_FAILURE); 1529 BITMASK_TEST( 0, -1LL, ANYBITS32, 0x0, EXPECT_FAILURE);
1531 1530
1532 // 32bit test: any of 0x1 1531 // 32bit test: any of 0x1
1533 BITMASK_TEST( 1, 0, ANYBITS32, 0x1, EXPECT_FAILURE); 1532 BITMASK_TEST( 1, 0, ANYBITS32, 0x1, EXPECT_FAILURE);
1534 BITMASK_TEST( 1, 1, ANYBITS32, 0x1, EXPECT_SUCCESS); 1533 BITMASK_TEST( 1, 1, ANYBITS32, 0x1, EXPECT_SUCCESS);
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1644 (long long)args.args[0], 1643 (long long)args.args[0],
1645 (long long)args.args[1], 1644 (long long)args.args[1],
1646 (long long)args.args[2], 1645 (long long)args.args[2],
1647 (long long)args.args[3], 1646 (long long)args.args[3],
1648 (long long)args.args[4], 1647 (long long)args.args[4],
1649 (long long)args.args[5], 1648 (long long)args.args[5],
1650 msg); 1649 msg);
1651 } 1650 }
1652 return -EPERM; 1651 return -EPERM;
1653 } 1652 }
1654 ErrorCode PthreadPolicyEquality(Sandbox* sandbox, int sysno, void* aux) { 1653 ErrorCode PthreadPolicyEquality(SandboxBPF* sandbox, int sysno, void* aux) {
1655 // This policy allows creating threads with pthread_create(). But it 1654 // This policy allows creating threads with pthread_create(). But it
1656 // doesn't allow any other uses of clone(). Most notably, it does not 1655 // doesn't allow any other uses of clone(). Most notably, it does not
1657 // allow callers to implement fork() or vfork() by passing suitable flags 1656 // allow callers to implement fork() or vfork() by passing suitable flags
1658 // to the clone() system call. 1657 // to the clone() system call.
1659 if (!Sandbox::IsValidSyscallNumber(sysno)) { 1658 if (!SandboxBPF::IsValidSyscallNumber(sysno)) {
1660 // FIXME: we should really not have to do that in a trivial policy 1659 // FIXME: we should really not have to do that in a trivial policy
1661 return ErrorCode(ENOSYS); 1660 return ErrorCode(ENOSYS);
1662 } else if (sysno == __NR_clone) { 1661 } else if (sysno == __NR_clone) {
1663 // We have seen two different valid combinations of flags. Glibc 1662 // We have seen two different valid combinations of flags. Glibc
1664 // uses the more modern flags, sets the TLS from the call to clone(), and 1663 // uses the more modern flags, sets the TLS from the call to clone(), and
1665 // uses futexes to monitor threads. Android's C run-time library, doesn't 1664 // uses futexes to monitor threads. Android's C run-time library, doesn't
1666 // do any of this, but it sets the obsolete (and no-op) CLONE_DETACHED. 1665 // do any of this, but it sets the obsolete (and no-op) CLONE_DETACHED.
1667 // More recent versions of Android don't set CLONE_DETACHED anymore, so 1666 // More recent versions of Android don't set CLONE_DETACHED anymore, so
1668 // the last case accounts for that. 1667 // the last case accounts for that.
1669 // The following policy is very strict. It only allows the exact masks 1668 // The following policy is very strict. It only allows the exact masks
(...skipping 14 matching lines...) Expand all
1684 ErrorCode(ErrorCode::ERR_ALLOWED), 1683 ErrorCode(ErrorCode::ERR_ALLOWED),
1685 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 1684 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
1686 kBaseAndroidCloneMask, 1685 kBaseAndroidCloneMask,
1687 ErrorCode(ErrorCode::ERR_ALLOWED), 1686 ErrorCode(ErrorCode::ERR_ALLOWED),
1688 sandbox->Trap(PthreadTrapHandler, "Unknown mask")))); 1687 sandbox->Trap(PthreadTrapHandler, "Unknown mask"))));
1689 } else { 1688 } else {
1690 return ErrorCode(ErrorCode::ERR_ALLOWED); 1689 return ErrorCode(ErrorCode::ERR_ALLOWED);
1691 } 1690 }
1692 } 1691 }
1693 1692
1694 ErrorCode PthreadPolicyBitMask(Sandbox* sandbox, int sysno, void* aux) { 1693 ErrorCode PthreadPolicyBitMask(SandboxBPF* sandbox, int sysno, void* aux) {
1695 // This policy allows creating threads with pthread_create(). But it 1694 // This policy allows creating threads with pthread_create(). But it
1696 // doesn't allow any other uses of clone(). Most notably, it does not 1695 // doesn't allow any other uses of clone(). Most notably, it does not
1697 // allow callers to implement fork() or vfork() by passing suitable flags 1696 // allow callers to implement fork() or vfork() by passing suitable flags
1698 // to the clone() system call. 1697 // to the clone() system call.
1699 if (!Sandbox::IsValidSyscallNumber(sysno)) { 1698 if (!SandboxBPF::IsValidSyscallNumber(sysno)) {
1700 // FIXME: we should really not have to do that in a trivial policy 1699 // FIXME: we should really not have to do that in a trivial policy
1701 return ErrorCode(ENOSYS); 1700 return ErrorCode(ENOSYS);
1702 } else if (sysno == __NR_clone) { 1701 } else if (sysno == __NR_clone) {
1703 // We have seen two different valid combinations of flags. Glibc 1702 // We have seen two different valid combinations of flags. Glibc
1704 // uses the more modern flags, sets the TLS from the call to clone(), and 1703 // uses the more modern flags, sets the TLS from the call to clone(), and
1705 // uses futexes to monitor threads. Android's C run-time library, doesn't 1704 // uses futexes to monitor threads. Android's C run-time library, doesn't
1706 // do any of this, but it sets the obsolete (and no-op) CLONE_DETACHED. 1705 // do any of this, but it sets the obsolete (and no-op) CLONE_DETACHED.
1707 // The following policy allows for either combination of flags, but it 1706 // The following policy allows for either combination of flags, but it
1708 // is generally a little more conservative than strictly necessary. We 1707 // is generally a little more conservative than strictly necessary. We
1709 // err on the side of rather safe than sorry. 1708 // err on the side of rather safe than sorry.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1768 // run-time libraries other than glibc might call __NR_fork instead of 1767 // run-time libraries other than glibc might call __NR_fork instead of
1769 // __NR_clone, and that would introduce a bogus test failure. 1768 // __NR_clone, and that would introduce a bogus test failure.
1770 int pid; 1769 int pid;
1771 BPF_ASSERT(SandboxSyscall(__NR_clone, 1770 BPF_ASSERT(SandboxSyscall(__NR_clone,
1772 CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | SIGCHLD, 1771 CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | SIGCHLD,
1773 0, 1772 0,
1774 0, 1773 0,
1775 &pid) == -EPERM); 1774 &pid) == -EPERM);
1776 } 1775 }
1777 1776
1778 BPF_TEST(SandboxBpf, PthreadEquality, PthreadPolicyEquality) { PthreadTest(); } 1777 BPF_TEST(SandboxBPF, PthreadEquality, PthreadPolicyEquality) { PthreadTest(); }
1779 1778
1780 BPF_TEST(SandboxBpf, PthreadBitMask, PthreadPolicyBitMask) { PthreadTest(); } 1779 BPF_TEST(SandboxBPF, PthreadBitMask, PthreadPolicyBitMask) { PthreadTest(); }
1781 1780
1782 } // namespace 1781 } // namespace
1782
1783 } // namespace sandbox
OLDNEW
« no previous file with comments | « sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h ('k') | sandbox/linux/seccomp-bpf/syscall.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698