OLD | NEW |
---|---|
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 <signal.h> | 8 #include <signal.h> |
9 #include <sys/prctl.h> | 9 #include <sys/prctl.h> |
10 #include <sys/ptrace.h> | 10 #include <sys/ptrace.h> |
(...skipping 13 matching lines...) Expand all Loading... | |
24 #include <ostream> | 24 #include <ostream> |
25 | 25 |
26 #include "base/bind.h" | 26 #include "base/bind.h" |
27 #include "base/logging.h" | 27 #include "base/logging.h" |
28 #include "base/macros.h" | 28 #include "base/macros.h" |
29 #include "base/memory/scoped_ptr.h" | 29 #include "base/memory/scoped_ptr.h" |
30 #include "base/posix/eintr_wrapper.h" | 30 #include "base/posix/eintr_wrapper.h" |
31 #include "base/synchronization/waitable_event.h" | 31 #include "base/synchronization/waitable_event.h" |
32 #include "base/threading/thread.h" | 32 #include "base/threading/thread.h" |
33 #include "build/build_config.h" | 33 #include "build/build_config.h" |
34 #include "sandbox/linux/bpf_dsl/bpf_dsl.h" | |
34 #include "sandbox/linux/seccomp-bpf/bpf_tests.h" | 35 #include "sandbox/linux/seccomp-bpf/bpf_tests.h" |
35 #include "sandbox/linux/seccomp-bpf/syscall.h" | 36 #include "sandbox/linux/seccomp-bpf/syscall.h" |
36 #include "sandbox/linux/seccomp-bpf/trap.h" | 37 #include "sandbox/linux/seccomp-bpf/trap.h" |
37 #include "sandbox/linux/seccomp-bpf/verifier.h" | 38 #include "sandbox/linux/seccomp-bpf/verifier.h" |
38 #include "sandbox/linux/services/broker_process.h" | 39 #include "sandbox/linux/services/broker_process.h" |
39 #include "sandbox/linux/services/linux_syscalls.h" | 40 #include "sandbox/linux/services/linux_syscalls.h" |
40 #include "sandbox/linux/tests/scoped_temporary_file.h" | 41 #include "sandbox/linux/tests/scoped_temporary_file.h" |
41 #include "sandbox/linux/tests/unit_tests.h" | 42 #include "sandbox/linux/tests/unit_tests.h" |
42 #include "testing/gtest/include/gtest/gtest.h" | 43 #include "testing/gtest/include/gtest/gtest.h" |
43 | 44 |
44 // Workaround for Android's prctl.h file. | 45 // Workaround for Android's prctl.h file. |
45 #ifndef PR_GET_ENDIAN | 46 #ifndef PR_GET_ENDIAN |
46 #define PR_GET_ENDIAN 19 | 47 #define PR_GET_ENDIAN 19 |
47 #endif | 48 #endif |
48 #ifndef PR_CAPBSET_READ | 49 #ifndef PR_CAPBSET_READ |
49 #define PR_CAPBSET_READ 23 | 50 #define PR_CAPBSET_READ 23 |
50 #define PR_CAPBSET_DROP 24 | 51 #define PR_CAPBSET_DROP 24 |
51 #endif | 52 #endif |
52 | 53 |
53 namespace sandbox { | 54 namespace sandbox { |
55 namespace bpf_dsl { | |
54 | 56 |
55 namespace { | 57 namespace { |
56 | 58 |
57 const int kExpectedReturnValue = 42; | 59 const int kExpectedReturnValue = 42; |
58 const char kSandboxDebuggingEnv[] = "CHROME_SANDBOX_DEBUGGING"; | 60 const char kSandboxDebuggingEnv[] = "CHROME_SANDBOX_DEBUGGING"; |
59 | 61 |
60 // Set the global environment to allow the use of UnsafeTrap() policies. | 62 // Set the global environment to allow the use of UnsafeTrap() policies. |
61 void EnableUnsafeTraps() { | 63 void EnableUnsafeTraps() { |
62 // The use of UnsafeTrap() causes us to print a warning message. This is | 64 // The use of UnsafeTrap() causes us to print a warning message. This is |
63 // generally desirable, but it results in the unittest failing, as it doesn't | 65 // generally desirable, but it results in the unittest failing, as it doesn't |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
96 // and it helps us accidentally forgetting any of the crucial steps in | 98 // and it helps us accidentally forgetting any of the crucial steps in |
97 // setting up the sandbox. But it wouldn't hurt to have at least one test | 99 // setting up the sandbox. But it wouldn't hurt to have at least one test |
98 // that explicitly walks through all these steps. | 100 // that explicitly walks through all these steps. |
99 | 101 |
100 intptr_t IncreaseCounter(const struct arch_seccomp_data& args, void* aux) { | 102 intptr_t IncreaseCounter(const struct arch_seccomp_data& args, void* aux) { |
101 BPF_ASSERT(aux); | 103 BPF_ASSERT(aux); |
102 int* counter = static_cast<int*>(aux); | 104 int* counter = static_cast<int*>(aux); |
103 return (*counter)++; | 105 return (*counter)++; |
104 } | 106 } |
105 | 107 |
106 class VerboseAPITestingPolicy : public SandboxBPFPolicy { | 108 class VerboseAPITestingPolicy : public SandboxBPFDSLPolicy { |
107 public: | 109 public: |
108 VerboseAPITestingPolicy(int* counter_ptr) : counter_ptr_(counter_ptr) {} | 110 VerboseAPITestingPolicy(int* counter_ptr) : counter_ptr_(counter_ptr) {} |
111 virtual ~VerboseAPITestingPolicy() {} | |
109 | 112 |
110 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, | 113 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE { |
111 int sysno) const OVERRIDE { | |
112 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | 114 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
113 if (sysno == __NR_uname) { | 115 if (sysno == __NR_uname) { |
114 return sandbox->Trap(IncreaseCounter, counter_ptr_); | 116 return Trap(IncreaseCounter, counter_ptr_); |
115 } | 117 } |
116 return ErrorCode(ErrorCode::ERR_ALLOWED); | 118 return Allow(); |
117 } | 119 } |
118 | 120 |
119 private: | 121 private: |
120 int* counter_ptr_; | 122 int* counter_ptr_; |
123 | |
121 DISALLOW_COPY_AND_ASSIGN(VerboseAPITestingPolicy); | 124 DISALLOW_COPY_AND_ASSIGN(VerboseAPITestingPolicy); |
122 }; | 125 }; |
123 | 126 |
124 SANDBOX_TEST(SandboxBPF, DISABLE_ON_TSAN(VerboseAPITesting)) { | 127 SANDBOX_TEST(SandboxBPF, DISABLE_ON_TSAN(VerboseAPITesting)) { |
125 if (SandboxBPF::SupportsSeccompSandbox(-1) == | 128 if (SandboxBPF::SupportsSeccompSandbox(-1) == |
126 sandbox::SandboxBPF::STATUS_AVAILABLE) { | 129 sandbox::SandboxBPF::STATUS_AVAILABLE) { |
127 static int counter = 0; | 130 static int counter = 0; |
128 | 131 |
129 SandboxBPF sandbox; | 132 SandboxBPF sandbox; |
130 sandbox.SetSandboxPolicy(new VerboseAPITestingPolicy(&counter)); | 133 sandbox.SetSandboxPolicy(new VerboseAPITestingPolicy(&counter)); |
131 BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::PROCESS_SINGLE_THREADED)); | 134 BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::PROCESS_SINGLE_THREADED)); |
132 | 135 |
133 BPF_ASSERT_EQ(0, counter); | 136 BPF_ASSERT_EQ(0, counter); |
134 BPF_ASSERT_EQ(0, syscall(__NR_uname, 0)); | 137 BPF_ASSERT_EQ(0, syscall(__NR_uname, 0)); |
135 BPF_ASSERT_EQ(1, counter); | 138 BPF_ASSERT_EQ(1, counter); |
136 BPF_ASSERT_EQ(1, syscall(__NR_uname, 0)); | 139 BPF_ASSERT_EQ(1, syscall(__NR_uname, 0)); |
137 BPF_ASSERT_EQ(2, counter); | 140 BPF_ASSERT_EQ(2, counter); |
138 } | 141 } |
139 } | 142 } |
140 | 143 |
141 // A simple blacklist test | 144 // A simple blacklist test |
142 | 145 |
143 class BlacklistNanosleepPolicy : public SandboxBPFPolicy { | 146 class BlacklistNanosleepPolicy : public SandboxBPFDSLPolicy { |
144 public: | 147 public: |
145 BlacklistNanosleepPolicy() {} | 148 BlacklistNanosleepPolicy() {} |
146 virtual ErrorCode EvaluateSyscall(SandboxBPF*, int sysno) const OVERRIDE { | 149 virtual ~BlacklistNanosleepPolicy() {} |
150 | |
151 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE { | |
147 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | 152 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
148 switch (sysno) { | 153 switch (sysno) { |
149 case __NR_nanosleep: | 154 case __NR_nanosleep: |
150 return ErrorCode(EACCES); | 155 return Error(EACCES); |
151 default: | 156 default: |
152 return ErrorCode(ErrorCode::ERR_ALLOWED); | 157 return Allow(); |
153 } | 158 } |
154 } | 159 } |
155 | 160 |
156 static void AssertNanosleepFails() { | 161 static void AssertNanosleepFails() { |
157 const struct timespec ts = {0, 0}; | 162 const struct timespec ts = {0, 0}; |
158 errno = 0; | 163 errno = 0; |
159 BPF_ASSERT_EQ(-1, HANDLE_EINTR(syscall(__NR_nanosleep, &ts, NULL))); | 164 BPF_ASSERT_EQ(-1, HANDLE_EINTR(syscall(__NR_nanosleep, &ts, NULL))); |
160 BPF_ASSERT_EQ(EACCES, errno); | 165 BPF_ASSERT_EQ(EACCES, errno); |
161 } | 166 } |
162 | 167 |
163 private: | 168 private: |
164 DISALLOW_COPY_AND_ASSIGN(BlacklistNanosleepPolicy); | 169 DISALLOW_COPY_AND_ASSIGN(BlacklistNanosleepPolicy); |
165 }; | 170 }; |
166 | 171 |
167 BPF_TEST_C(SandboxBPF, ApplyBasicBlacklistPolicy, BlacklistNanosleepPolicy) { | 172 BPF_TEST_C(SandboxBPF, ApplyBasicBlacklistPolicy, BlacklistNanosleepPolicy) { |
168 BlacklistNanosleepPolicy::AssertNanosleepFails(); | 173 BlacklistNanosleepPolicy::AssertNanosleepFails(); |
169 } | 174 } |
170 | 175 |
171 // Now do a simple whitelist test | 176 // Now do a simple whitelist test |
172 | 177 |
173 class WhitelistGetpidPolicy : public SandboxBPFPolicy { | 178 class WhitelistGetpidPolicy : public SandboxBPFDSLPolicy { |
174 public: | 179 public: |
175 WhitelistGetpidPolicy() {} | 180 WhitelistGetpidPolicy() {} |
176 virtual ErrorCode EvaluateSyscall(SandboxBPF*, int sysno) const OVERRIDE { | 181 virtual ~WhitelistGetpidPolicy() {} |
182 | |
183 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE { | |
177 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | 184 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
178 switch (sysno) { | 185 switch (sysno) { |
179 case __NR_getpid: | 186 case __NR_getpid: |
180 case __NR_exit_group: | 187 case __NR_exit_group: |
181 return ErrorCode(ErrorCode::ERR_ALLOWED); | 188 return Allow(); |
182 default: | 189 default: |
183 return ErrorCode(ENOMEM); | 190 return Error(ENOMEM); |
184 } | 191 } |
185 } | 192 } |
186 | 193 |
187 private: | 194 private: |
188 DISALLOW_COPY_AND_ASSIGN(WhitelistGetpidPolicy); | 195 DISALLOW_COPY_AND_ASSIGN(WhitelistGetpidPolicy); |
189 }; | 196 }; |
190 | 197 |
191 BPF_TEST_C(SandboxBPF, ApplyBasicWhitelistPolicy, WhitelistGetpidPolicy) { | 198 BPF_TEST_C(SandboxBPF, ApplyBasicWhitelistPolicy, WhitelistGetpidPolicy) { |
192 // getpid() should be allowed | 199 // getpid() should be allowed |
193 errno = 0; | 200 errno = 0; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
233 const struct timespec ts = {0, 0}; | 240 const struct timespec ts = {0, 0}; |
234 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); | 241 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); |
235 BPF_ASSERT(errno == ENOMEM); | 242 BPF_ASSERT(errno == ENOMEM); |
236 | 243 |
237 // We expect the signal handler to modify AuxData | 244 // We expect the signal handler to modify AuxData |
238 BPF_ASSERT(*BPF_AUX == kExpectedReturnValue); | 245 BPF_ASSERT(*BPF_AUX == kExpectedReturnValue); |
239 } | 246 } |
240 | 247 |
241 // A simple test that verifies we can return arbitrary errno values. | 248 // A simple test that verifies we can return arbitrary errno values. |
242 | 249 |
243 class ErrnoTestPolicy : public SandboxBPFPolicy { | 250 class ErrnoTestPolicy : public SandboxBPFDSLPolicy { |
244 public: | 251 public: |
245 ErrnoTestPolicy() {} | 252 ErrnoTestPolicy() {} |
246 virtual ErrorCode EvaluateSyscall(SandboxBPF*, int sysno) const OVERRIDE; | 253 virtual ~ErrnoTestPolicy() {} |
254 | |
255 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE; | |
247 | 256 |
248 private: | 257 private: |
249 DISALLOW_COPY_AND_ASSIGN(ErrnoTestPolicy); | 258 DISALLOW_COPY_AND_ASSIGN(ErrnoTestPolicy); |
250 }; | 259 }; |
251 | 260 |
252 ErrorCode ErrnoTestPolicy::EvaluateSyscall(SandboxBPF*, int sysno) const { | 261 ResultExpr ErrnoTestPolicy::EvaluateSyscall(int sysno) const { |
253 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | 262 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
254 switch (sysno) { | 263 switch (sysno) { |
255 case __NR_dup3: // dup2 is a wrapper of dup3 in android | 264 case __NR_dup3: // dup2 is a wrapper of dup3 in android |
256 #if defined(__NR_dup2) | 265 #if defined(__NR_dup2) |
257 case __NR_dup2: | 266 case __NR_dup2: |
258 #endif | 267 #endif |
259 // Pretend that dup2() worked, but don't actually do anything. | 268 // Pretend that dup2() worked, but don't actually do anything. |
260 return ErrorCode(0); | 269 return Error(0); |
261 case __NR_setuid: | 270 case __NR_setuid: |
262 #if defined(__NR_setuid32) | 271 #if defined(__NR_setuid32) |
263 case __NR_setuid32: | 272 case __NR_setuid32: |
264 #endif | 273 #endif |
265 // Return errno = 1. | 274 // Return errno = 1. |
266 return ErrorCode(1); | 275 return Error(1); |
267 case __NR_setgid: | 276 case __NR_setgid: |
268 #if defined(__NR_setgid32) | 277 #if defined(__NR_setgid32) |
269 case __NR_setgid32: | 278 case __NR_setgid32: |
270 #endif | 279 #endif |
271 // Return maximum errno value (typically 4095). | 280 // Return maximum errno value (typically 4095). |
272 return ErrorCode(ErrorCode::ERR_MAX_ERRNO); | 281 return Error(ErrorCode::ERR_MAX_ERRNO); |
273 case __NR_uname: | 282 case __NR_uname: |
274 // Return errno = 42; | 283 // Return errno = 42; |
275 return ErrorCode(42); | 284 return Error(42); |
276 default: | 285 default: |
277 return ErrorCode(ErrorCode::ERR_ALLOWED); | 286 return Allow(); |
278 } | 287 } |
279 } | 288 } |
280 | 289 |
281 BPF_TEST_C(SandboxBPF, ErrnoTest, ErrnoTestPolicy) { | 290 BPF_TEST_C(SandboxBPF, ErrnoTest, ErrnoTestPolicy) { |
282 // Verify that dup2() returns success, but doesn't actually run. | 291 // Verify that dup2() returns success, but doesn't actually run. |
283 int fds[4]; | 292 int fds[4]; |
284 BPF_ASSERT(pipe(fds) == 0); | 293 BPF_ASSERT(pipe(fds) == 0); |
285 BPF_ASSERT(pipe(fds + 2) == 0); | 294 BPF_ASSERT(pipe(fds + 2) == 0); |
286 BPF_ASSERT(dup2(fds[2], fds[0]) == 0); | 295 BPF_ASSERT(dup2(fds[2], fds[0]) == 0); |
287 char buf[1] = {}; | 296 char buf[1] = {}; |
(...skipping 25 matching lines...) Expand all Loading... | |
313 | 322 |
314 // Finally, test an errno in between the minimum and maximum. | 323 // Finally, test an errno in between the minimum and maximum. |
315 errno = 0; | 324 errno = 0; |
316 struct utsname uts_buf; | 325 struct utsname uts_buf; |
317 BPF_ASSERT(uname(&uts_buf) == -1); | 326 BPF_ASSERT(uname(&uts_buf) == -1); |
318 BPF_ASSERT(errno == 42); | 327 BPF_ASSERT(errno == 42); |
319 } | 328 } |
320 | 329 |
321 // Testing the stacking of two sandboxes | 330 // Testing the stacking of two sandboxes |
322 | 331 |
323 class StackingPolicyPartOne : public SandboxBPFPolicy { | 332 class StackingPolicyPartOne : public SandboxBPFDSLPolicy { |
324 public: | 333 public: |
325 StackingPolicyPartOne() {} | 334 StackingPolicyPartOne() {} |
326 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, | 335 virtual ~StackingPolicyPartOne() {} |
327 int sysno) const OVERRIDE { | 336 |
337 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE { | |
328 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | 338 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
329 switch (sysno) { | 339 switch (sysno) { |
330 case __NR_getppid: | 340 case __NR_getppid: { |
331 return sandbox->Cond(0, | 341 const Arg<int> arg(0); |
332 ErrorCode::TP_32BIT, | 342 return If(arg == 0, Allow()).Else(Error(EPERM)); |
333 ErrorCode::OP_EQUAL, | 343 } |
334 0, | |
335 ErrorCode(ErrorCode::ERR_ALLOWED), | |
336 ErrorCode(EPERM)); | |
337 default: | 344 default: |
338 return ErrorCode(ErrorCode::ERR_ALLOWED); | 345 return Allow(); |
339 } | 346 } |
340 } | 347 } |
341 | 348 |
342 private: | 349 private: |
343 DISALLOW_COPY_AND_ASSIGN(StackingPolicyPartOne); | 350 DISALLOW_COPY_AND_ASSIGN(StackingPolicyPartOne); |
344 }; | 351 }; |
345 | 352 |
346 class StackingPolicyPartTwo : public SandboxBPFPolicy { | 353 class StackingPolicyPartTwo : public SandboxBPFDSLPolicy { |
347 public: | 354 public: |
348 StackingPolicyPartTwo() {} | 355 StackingPolicyPartTwo() {} |
349 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, | 356 virtual ~StackingPolicyPartTwo() {} |
350 int sysno) const OVERRIDE { | 357 |
358 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE { | |
351 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | 359 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
352 switch (sysno) { | 360 switch (sysno) { |
353 case __NR_getppid: | 361 case __NR_getppid: { |
354 return sandbox->Cond(0, | 362 const Arg<int> arg(0); |
355 ErrorCode::TP_32BIT, | 363 return If(arg == 0, Error(EINVAL)).Else(Allow()); |
356 ErrorCode::OP_EQUAL, | 364 } |
357 0, | |
358 ErrorCode(EINVAL), | |
359 ErrorCode(ErrorCode::ERR_ALLOWED)); | |
360 default: | 365 default: |
361 return ErrorCode(ErrorCode::ERR_ALLOWED); | 366 return Allow(); |
362 } | 367 } |
363 } | 368 } |
364 | 369 |
365 private: | 370 private: |
366 DISALLOW_COPY_AND_ASSIGN(StackingPolicyPartTwo); | 371 DISALLOW_COPY_AND_ASSIGN(StackingPolicyPartTwo); |
367 }; | 372 }; |
368 | 373 |
369 BPF_TEST_C(SandboxBPF, StackingPolicy, StackingPolicyPartOne) { | 374 BPF_TEST_C(SandboxBPF, StackingPolicy, StackingPolicyPartOne) { |
370 errno = 0; | 375 errno = 0; |
371 BPF_ASSERT(syscall(__NR_getppid, 0) > 0); | 376 BPF_ASSERT(syscall(__NR_getppid, 0) > 0); |
(...skipping 24 matching lines...) Expand all Loading... | |
396 // We try to make sure we exercise optimizations in the BPF compiler. We make | 401 // We try to make sure we exercise optimizations in the BPF compiler. We make |
397 // sure that the compiler can have an opportunity to coalesce syscalls with | 402 // sure that the compiler can have an opportunity to coalesce syscalls with |
398 // contiguous numbers and we also make sure that disjoint sets can return the | 403 // contiguous numbers and we also make sure that disjoint sets can return the |
399 // same errno. | 404 // same errno. |
400 int SysnoToRandomErrno(int sysno) { | 405 int SysnoToRandomErrno(int sysno) { |
401 // Small contiguous sets of 3 system calls return an errno equal to the | 406 // Small contiguous sets of 3 system calls return an errno equal to the |
402 // index of that set + 1 (so that we never return a NUL errno). | 407 // index of that set + 1 (so that we never return a NUL errno). |
403 return ((sysno & ~3) >> 2) % 29 + 1; | 408 return ((sysno & ~3) >> 2) % 29 + 1; |
404 } | 409 } |
405 | 410 |
406 class SyntheticPolicy : public SandboxBPFPolicy { | 411 class SyntheticPolicy : public SandboxBPFDSLPolicy { |
407 public: | 412 public: |
408 SyntheticPolicy() {} | 413 SyntheticPolicy() {} |
409 virtual ErrorCode EvaluateSyscall(SandboxBPF*, int sysno) const OVERRIDE { | 414 virtual ~SyntheticPolicy() {} |
415 | |
416 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE { | |
410 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | 417 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
411 if (sysno == __NR_exit_group || sysno == __NR_write) { | 418 if (sysno == __NR_exit_group || sysno == __NR_write) { |
412 // exit_group() is special, we really need it to work. | 419 // exit_group() is special, we really need it to work. |
413 // write() is needed for BPF_ASSERT() to report a useful error message. | 420 // write() is needed for BPF_ASSERT() to report a useful error message. |
414 return ErrorCode(ErrorCode::ERR_ALLOWED); | 421 return Allow(); |
415 } | 422 } |
416 return ErrorCode(SysnoToRandomErrno(sysno)); | 423 return Error(SysnoToRandomErrno(sysno)); |
417 } | 424 } |
418 | 425 |
419 private: | 426 private: |
420 DISALLOW_COPY_AND_ASSIGN(SyntheticPolicy); | 427 DISALLOW_COPY_AND_ASSIGN(SyntheticPolicy); |
421 }; | 428 }; |
422 | 429 |
423 BPF_TEST_C(SandboxBPF, SyntheticPolicy, SyntheticPolicy) { | 430 BPF_TEST_C(SandboxBPF, SyntheticPolicy, SyntheticPolicy) { |
424 // Ensure that that kExpectedReturnValue + syscallnumber + 1 does not int | 431 // Ensure that that kExpectedReturnValue + syscallnumber + 1 does not int |
425 // overflow. | 432 // overflow. |
426 BPF_ASSERT(std::numeric_limits<int>::max() - kExpectedReturnValue - 1 >= | 433 BPF_ASSERT(std::numeric_limits<int>::max() - kExpectedReturnValue - 1 >= |
(...skipping 20 matching lines...) Expand all Loading... | |
447 // MIN_PRIVATE_SYSCALL plus 1 (to avoid NUL errno). | 454 // MIN_PRIVATE_SYSCALL plus 1 (to avoid NUL errno). |
448 int ArmPrivateSysnoToErrno(int sysno) { | 455 int ArmPrivateSysnoToErrno(int sysno) { |
449 if (sysno >= static_cast<int>(MIN_PRIVATE_SYSCALL) && | 456 if (sysno >= static_cast<int>(MIN_PRIVATE_SYSCALL) && |
450 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) { | 457 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) { |
451 return (sysno - MIN_PRIVATE_SYSCALL) + 1; | 458 return (sysno - MIN_PRIVATE_SYSCALL) + 1; |
452 } else { | 459 } else { |
453 return ENOSYS; | 460 return ENOSYS; |
454 } | 461 } |
455 } | 462 } |
456 | 463 |
457 class ArmPrivatePolicy : public SandboxBPFPolicy { | 464 class ArmPrivatePolicy : public SandboxBPFDSLPolicy { |
458 public: | 465 public: |
459 ArmPrivatePolicy() {} | 466 ArmPrivatePolicy() {} |
460 virtual ErrorCode EvaluateSyscall(SandboxBPF*, int sysno) const OVERRIDE { | 467 virtual ~ArmPrivatePolicy() {} |
468 | |
469 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE { | |
461 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | 470 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
462 // Start from |__ARM_NR_set_tls + 1| so as not to mess with actual | 471 // Start from |__ARM_NR_set_tls + 1| so as not to mess with actual |
463 // ARM private system calls. | 472 // ARM private system calls. |
464 if (sysno >= static_cast<int>(__ARM_NR_set_tls + 1) && | 473 if (sysno >= static_cast<int>(__ARM_NR_set_tls + 1) && |
465 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) { | 474 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) { |
466 return ErrorCode(ArmPrivateSysnoToErrno(sysno)); | 475 return Error(ArmPrivateSysnoToErrno(sysno)); |
467 } | 476 } |
468 return ErrorCode(ErrorCode::ERR_ALLOWED); | 477 return Allow(); |
469 } | 478 } |
470 | 479 |
471 private: | 480 private: |
472 DISALLOW_COPY_AND_ASSIGN(ArmPrivatePolicy); | 481 DISALLOW_COPY_AND_ASSIGN(ArmPrivatePolicy); |
473 }; | 482 }; |
474 | 483 |
475 BPF_TEST_C(SandboxBPF, ArmPrivatePolicy, ArmPrivatePolicy) { | 484 BPF_TEST_C(SandboxBPF, ArmPrivatePolicy, ArmPrivatePolicy) { |
476 for (int syscall_number = static_cast<int>(__ARM_NR_set_tls + 1); | 485 for (int syscall_number = static_cast<int>(__ARM_NR_set_tls + 1); |
477 syscall_number <= static_cast<int>(MAX_PRIVATE_SYSCALL); | 486 syscall_number <= static_cast<int>(MAX_PRIVATE_SYSCALL); |
478 ++syscall_number) { | 487 ++syscall_number) { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
550 intptr_t PrctlHandler(const struct arch_seccomp_data& args, void*) { | 559 intptr_t PrctlHandler(const struct arch_seccomp_data& args, void*) { |
551 if (args.args[0] == PR_CAPBSET_DROP && static_cast<int>(args.args[1]) == -1) { | 560 if (args.args[0] == PR_CAPBSET_DROP && static_cast<int>(args.args[1]) == -1) { |
552 // prctl(PR_CAPBSET_DROP, -1) is never valid. The kernel will always | 561 // prctl(PR_CAPBSET_DROP, -1) is never valid. The kernel will always |
553 // return an error. But our handler allows this call. | 562 // return an error. But our handler allows this call. |
554 return 0; | 563 return 0; |
555 } else { | 564 } else { |
556 return SandboxBPF::ForwardSyscall(args); | 565 return SandboxBPF::ForwardSyscall(args); |
557 } | 566 } |
558 } | 567 } |
559 | 568 |
560 class PrctlPolicy : public SandboxBPFPolicy { | 569 class PrctlPolicy : public SandboxBPFDSLPolicy { |
561 public: | 570 public: |
562 PrctlPolicy() {} | 571 PrctlPolicy() {} |
563 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, | 572 virtual ~PrctlPolicy() {} |
564 int sysno) const OVERRIDE { | 573 |
574 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE { | |
565 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | 575 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
566 setenv(kSandboxDebuggingEnv, "t", 0); | 576 setenv(kSandboxDebuggingEnv, "t", 0); |
567 Die::SuppressInfoMessages(true); | 577 Die::SuppressInfoMessages(true); |
568 | 578 |
569 if (sysno == __NR_prctl) { | 579 if (sysno == __NR_prctl) { |
570 // Handle prctl() inside an UnsafeTrap() | 580 // Handle prctl() inside an UnsafeTrap() |
571 return sandbox->UnsafeTrap(PrctlHandler, NULL); | 581 return UnsafeTrap(PrctlHandler, NULL); |
572 } | 582 } |
573 | 583 |
574 // Allow all other system calls. | 584 // Allow all other system calls. |
575 return ErrorCode(ErrorCode::ERR_ALLOWED); | 585 return Allow(); |
576 } | 586 } |
577 | 587 |
578 private: | 588 private: |
579 DISALLOW_COPY_AND_ASSIGN(PrctlPolicy); | 589 DISALLOW_COPY_AND_ASSIGN(PrctlPolicy); |
580 }; | 590 }; |
581 | 591 |
582 BPF_TEST_C(SandboxBPF, ForwardSyscall, PrctlPolicy) { | 592 BPF_TEST_C(SandboxBPF, ForwardSyscall, PrctlPolicy) { |
583 // This call should never be allowed. But our policy will intercept it and | 593 // This call should never be allowed. But our policy will intercept it and |
584 // let it pass successfully. | 594 // let it pass successfully. |
585 BPF_ASSERT( | 595 BPF_ASSERT( |
(...skipping 17 matching lines...) Expand all Loading... | |
603 // unaffected by our policy. | 613 // unaffected by our policy. |
604 struct utsname uts = {}; | 614 struct utsname uts = {}; |
605 BPF_ASSERT(!uname(&uts)); | 615 BPF_ASSERT(!uname(&uts)); |
606 BPF_ASSERT(!strcmp(uts.sysname, "Linux")); | 616 BPF_ASSERT(!strcmp(uts.sysname, "Linux")); |
607 } | 617 } |
608 | 618 |
609 intptr_t AllowRedirectedSyscall(const struct arch_seccomp_data& args, void*) { | 619 intptr_t AllowRedirectedSyscall(const struct arch_seccomp_data& args, void*) { |
610 return SandboxBPF::ForwardSyscall(args); | 620 return SandboxBPF::ForwardSyscall(args); |
611 } | 621 } |
612 | 622 |
613 class RedirectAllSyscallsPolicy : public SandboxBPFPolicy { | 623 class RedirectAllSyscallsPolicy : public SandboxBPFDSLPolicy { |
614 public: | 624 public: |
615 RedirectAllSyscallsPolicy() {} | 625 RedirectAllSyscallsPolicy() {} |
616 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, | 626 virtual ~RedirectAllSyscallsPolicy() {} |
617 int sysno) const OVERRIDE; | 627 |
628 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE; | |
618 | 629 |
619 private: | 630 private: |
620 DISALLOW_COPY_AND_ASSIGN(RedirectAllSyscallsPolicy); | 631 DISALLOW_COPY_AND_ASSIGN(RedirectAllSyscallsPolicy); |
621 }; | 632 }; |
622 | 633 |
623 ErrorCode RedirectAllSyscallsPolicy::EvaluateSyscall(SandboxBPF* sandbox, | 634 ResultExpr RedirectAllSyscallsPolicy::EvaluateSyscall(int sysno) const { |
624 int sysno) const { | |
625 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | 635 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
626 setenv(kSandboxDebuggingEnv, "t", 0); | 636 setenv(kSandboxDebuggingEnv, "t", 0); |
627 Die::SuppressInfoMessages(true); | 637 Die::SuppressInfoMessages(true); |
628 | 638 |
629 // Some system calls must always be allowed, if our policy wants to make | 639 // Some system calls must always be allowed, if our policy wants to make |
630 // use of UnsafeTrap() | 640 // use of UnsafeTrap() |
631 if (SandboxBPF::IsRequiredForUnsafeTrap(sysno)) | 641 if (SandboxBPF::IsRequiredForUnsafeTrap(sysno)) |
632 return ErrorCode(ErrorCode::ERR_ALLOWED); | 642 return Allow(); |
633 return sandbox->UnsafeTrap(AllowRedirectedSyscall, NULL); | 643 return UnsafeTrap(AllowRedirectedSyscall, NULL); |
634 } | 644 } |
635 | 645 |
636 int bus_handler_fd_ = -1; | 646 int bus_handler_fd_ = -1; |
637 | 647 |
638 void SigBusHandler(int, siginfo_t* info, void* void_context) { | 648 void SigBusHandler(int, siginfo_t* info, void* void_context) { |
639 BPF_ASSERT(write(bus_handler_fd_, "\x55", 1) == 1); | 649 BPF_ASSERT(write(bus_handler_fd_, "\x55", 1) == 1); |
640 } | 650 } |
641 | 651 |
642 BPF_TEST_C(SandboxBPF, SigBus, RedirectAllSyscallsPolicy) { | 652 BPF_TEST_C(SandboxBPF, SigBus, RedirectAllSyscallsPolicy) { |
643 // We use the SIGBUS bit in the signal mask as a thread-local boolean | 653 // We use the SIGBUS bit in the signal mask as a thread-local boolean |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
707 // would make system calls, but it allows us to verify that we don't | 717 // would make system calls, but it allows us to verify that we don't |
708 // accidentally mess with errno, when we shouldn't. | 718 // accidentally mess with errno, when we shouldn't. |
709 errno = 0; | 719 errno = 0; |
710 struct arch_seccomp_data args = {}; | 720 struct arch_seccomp_data args = {}; |
711 args.nr = __NR_close; | 721 args.nr = __NR_close; |
712 args.args[0] = -1; | 722 args.args[0] = -1; |
713 BPF_ASSERT(SandboxBPF::ForwardSyscall(args) == -EBADF); | 723 BPF_ASSERT(SandboxBPF::ForwardSyscall(args) == -EBADF); |
714 BPF_ASSERT(errno == 0); | 724 BPF_ASSERT(errno == 0); |
715 } | 725 } |
716 | 726 |
717 bool NoOpCallback() { return true; } | 727 bool NoOpCallback() { |
728 return true; | |
729 } | |
718 | 730 |
719 // Test a trap handler that makes use of a broker process to open(). | 731 // Test a trap handler that makes use of a broker process to open(). |
720 | 732 |
721 class InitializedOpenBroker { | 733 class InitializedOpenBroker { |
722 public: | 734 public: |
723 InitializedOpenBroker() : initialized_(false) { | 735 InitializedOpenBroker() : initialized_(false) { |
724 std::vector<std::string> allowed_files; | 736 std::vector<std::string> allowed_files; |
725 allowed_files.push_back("/proc/allowed"); | 737 allowed_files.push_back("/proc/allowed"); |
726 allowed_files.push_back("/proc/cpuinfo"); | 738 allowed_files.push_back("/proc/cpuinfo"); |
727 | 739 |
(...skipping 11 matching lines...) Expand all Loading... | |
739 bool initialized_; | 751 bool initialized_; |
740 scoped_ptr<class BrokerProcess> broker_process_; | 752 scoped_ptr<class BrokerProcess> broker_process_; |
741 DISALLOW_COPY_AND_ASSIGN(InitializedOpenBroker); | 753 DISALLOW_COPY_AND_ASSIGN(InitializedOpenBroker); |
742 }; | 754 }; |
743 | 755 |
744 intptr_t BrokerOpenTrapHandler(const struct arch_seccomp_data& args, | 756 intptr_t BrokerOpenTrapHandler(const struct arch_seccomp_data& args, |
745 void* aux) { | 757 void* aux) { |
746 BPF_ASSERT(aux); | 758 BPF_ASSERT(aux); |
747 BrokerProcess* broker_process = static_cast<BrokerProcess*>(aux); | 759 BrokerProcess* broker_process = static_cast<BrokerProcess*>(aux); |
748 switch (args.nr) { | 760 switch (args.nr) { |
749 case __NR_faccessat: // access is a wrapper of faccessat in android | 761 case __NR_faccessat: // access is a wrapper of faccessat in android |
750 BPF_ASSERT(static_cast<int>(args.args[0]) == AT_FDCWD); | 762 BPF_ASSERT(static_cast<int>(args.args[0]) == AT_FDCWD); |
751 return broker_process->Access(reinterpret_cast<const char*>(args.args[1]), | 763 return broker_process->Access(reinterpret_cast<const char*>(args.args[1]), |
752 static_cast<int>(args.args[2])); | 764 static_cast<int>(args.args[2])); |
753 #if defined(__NR_access) | 765 #if defined(__NR_access) |
754 case __NR_access: | 766 case __NR_access: |
755 return broker_process->Access(reinterpret_cast<const char*>(args.args[0]), | 767 return broker_process->Access(reinterpret_cast<const char*>(args.args[0]), |
756 static_cast<int>(args.args[1])); | 768 static_cast<int>(args.args[1])); |
757 #endif | 769 #endif |
758 #if defined(__NR_open) | 770 #if defined(__NR_open) |
759 case __NR_open: | 771 case __NR_open: |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
839 int cpu_info_access = access("/proc/cpuinfo", R_OK); | 851 int cpu_info_access = access("/proc/cpuinfo", R_OK); |
840 BPF_ASSERT(cpu_info_access == 0); | 852 BPF_ASSERT(cpu_info_access == 0); |
841 int cpu_info_fd = open("/proc/cpuinfo", O_RDONLY); | 853 int cpu_info_fd = open("/proc/cpuinfo", O_RDONLY); |
842 BPF_ASSERT(cpu_info_fd >= 0); | 854 BPF_ASSERT(cpu_info_fd >= 0); |
843 char buf[1024]; | 855 char buf[1024]; |
844 BPF_ASSERT(read(cpu_info_fd, buf, sizeof(buf)) > 0); | 856 BPF_ASSERT(read(cpu_info_fd, buf, sizeof(buf)) > 0); |
845 } | 857 } |
846 | 858 |
847 // Simple test demonstrating how to use SandboxBPF::Cond() | 859 // Simple test demonstrating how to use SandboxBPF::Cond() |
848 | 860 |
849 class SimpleCondTestPolicy : public SandboxBPFPolicy { | 861 class SimpleCondTestPolicy : public SandboxBPFDSLPolicy { |
850 public: | 862 public: |
851 SimpleCondTestPolicy() {} | 863 SimpleCondTestPolicy() {} |
852 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, | 864 virtual ~SimpleCondTestPolicy() {} |
853 int sysno) const OVERRIDE; | 865 |
866 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE; | |
854 | 867 |
855 private: | 868 private: |
856 DISALLOW_COPY_AND_ASSIGN(SimpleCondTestPolicy); | 869 DISALLOW_COPY_AND_ASSIGN(SimpleCondTestPolicy); |
857 }; | 870 }; |
858 | 871 |
859 ErrorCode SimpleCondTestPolicy::EvaluateSyscall(SandboxBPF* sandbox, | 872 ResultExpr SimpleCondTestPolicy::EvaluateSyscall(int sysno) const { |
860 int sysno) const { | |
861 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | 873 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
862 | 874 |
863 // We deliberately return unusual errno values upon failure, so that we | 875 // We deliberately return unusual errno values upon failure, so that we |
864 // can uniquely test for these values. In a "real" policy, you would want | 876 // can uniquely test for these values. In a "real" policy, you would want |
865 // to return more traditional values. | 877 // to return more traditional values. |
866 int flags_argument_position = -1; | 878 int flags_argument_position = -1; |
867 switch (sysno) { | 879 switch (sysno) { |
868 #if defined(__NR_open) | 880 #if defined(__NR_open) |
869 case __NR_open: | 881 case __NR_open: |
870 flags_argument_position = 1; | 882 flags_argument_position = 1; |
871 #endif | 883 #endif |
872 case __NR_openat: // open can be a wrapper for openat(2). | 884 case __NR_openat: { // open can be a wrapper for openat(2). |
873 if (sysno == __NR_openat) | 885 if (sysno == __NR_openat) |
874 flags_argument_position = 2; | 886 flags_argument_position = 2; |
875 | 887 |
876 // Allow opening files for reading, but don't allow writing. | 888 // Allow opening files for reading, but don't allow writing. |
877 COMPILE_ASSERT(O_RDONLY == 0, O_RDONLY_must_be_all_zero_bits); | 889 COMPILE_ASSERT(O_RDONLY == 0, O_RDONLY_must_be_all_zero_bits); |
878 return sandbox->Cond(flags_argument_position, | 890 const Arg<int> flags(flags_argument_position); |
879 ErrorCode::TP_32BIT, | 891 return If((flags & O_ACCMODE) != 0, Error(EROFS)).Else(Allow()); |
880 ErrorCode::OP_HAS_ANY_BITS, | 892 } |
881 O_ACCMODE /* 0x3 */, | 893 case __NR_prctl: { |
882 ErrorCode(EROFS), | |
883 ErrorCode(ErrorCode::ERR_ALLOWED)); | |
884 case __NR_prctl: | |
885 // Allow prctl(PR_SET_DUMPABLE) and prctl(PR_GET_DUMPABLE), but | 894 // Allow prctl(PR_SET_DUMPABLE) and prctl(PR_GET_DUMPABLE), but |
886 // disallow everything else. | 895 // disallow everything else. |
887 return sandbox->Cond(0, | 896 const Arg<int> option(0); |
888 ErrorCode::TP_32BIT, | 897 return If(option == PR_SET_DUMPABLE || option == PR_GET_DUMPABLE, Allow()) |
889 ErrorCode::OP_EQUAL, | 898 .Else(Error(ENOMEM)); |
890 PR_SET_DUMPABLE, | 899 } |
891 ErrorCode(ErrorCode::ERR_ALLOWED), | |
892 sandbox->Cond(0, | |
893 ErrorCode::TP_32BIT, | |
894 ErrorCode::OP_EQUAL, | |
895 PR_GET_DUMPABLE, | |
896 ErrorCode(ErrorCode::ERR_ALLOWED), | |
897 ErrorCode(ENOMEM))); | |
898 default: | 900 default: |
899 return ErrorCode(ErrorCode::ERR_ALLOWED); | 901 return Allow(); |
900 } | 902 } |
901 } | 903 } |
902 | 904 |
903 BPF_TEST_C(SandboxBPF, SimpleCondTest, SimpleCondTestPolicy) { | 905 BPF_TEST_C(SandboxBPF, SimpleCondTest, SimpleCondTestPolicy) { |
904 int fd; | 906 int fd; |
905 BPF_ASSERT((fd = open("/proc/self/comm", O_RDWR)) == -1); | 907 BPF_ASSERT((fd = open("/proc/self/comm", O_RDWR)) == -1); |
906 BPF_ASSERT(errno == EROFS); | 908 BPF_ASSERT(errno == EROFS); |
907 BPF_ASSERT((fd = open("/proc/self/comm", O_RDONLY)) >= 0); | 909 BPF_ASSERT((fd = open("/proc/self/comm", O_RDONLY)) >= 0); |
908 close(fd); | 910 close(fd); |
909 | 911 |
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1226 return aux->Policy(sandbox, sysno); | 1228 return aux->Policy(sandbox, sysno); |
1227 } | 1229 } |
1228 | 1230 |
1229 BPF_TEST(SandboxBPF, | 1231 BPF_TEST(SandboxBPF, |
1230 EqualityTests, | 1232 EqualityTests, |
1231 EqualityStressTestPolicy, | 1233 EqualityStressTestPolicy, |
1232 EqualityStressTest /* (*BPF_AUX) */) { | 1234 EqualityStressTest /* (*BPF_AUX) */) { |
1233 BPF_AUX->VerifyFilter(); | 1235 BPF_AUX->VerifyFilter(); |
1234 } | 1236 } |
1235 | 1237 |
1236 class EqualityArgumentWidthPolicy : public SandboxBPFPolicy { | 1238 class EqualityArgumentWidthPolicy : public SandboxBPFDSLPolicy { |
1237 public: | 1239 public: |
1238 EqualityArgumentWidthPolicy() {} | 1240 EqualityArgumentWidthPolicy() {} |
1239 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, | 1241 virtual ~EqualityArgumentWidthPolicy() {} |
1240 int sysno) const OVERRIDE; | 1242 |
1243 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE; | |
1241 | 1244 |
1242 private: | 1245 private: |
1243 DISALLOW_COPY_AND_ASSIGN(EqualityArgumentWidthPolicy); | 1246 DISALLOW_COPY_AND_ASSIGN(EqualityArgumentWidthPolicy); |
1244 }; | 1247 }; |
1245 | 1248 |
1246 ErrorCode EqualityArgumentWidthPolicy::EvaluateSyscall(SandboxBPF* sandbox, | 1249 ResultExpr EqualityArgumentWidthPolicy::EvaluateSyscall(int sysno) const { |
1247 int sysno) const { | |
1248 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | 1250 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
1249 if (sysno == __NR_uname) { | 1251 if (sysno == __NR_uname) { |
1250 return sandbox->Cond( | 1252 const Arg<int> option(0); |
1251 0, | 1253 const Arg<uint32_t> arg32(1); |
1252 ErrorCode::TP_32BIT, | 1254 const Arg<uint64_t> arg64(1); |
1253 ErrorCode::OP_EQUAL, | 1255 return Switch(option) |
1254 0, | 1256 .Case(0, If(arg32 == 0x55555555, Error(1)).Else(Error(2))) |
1255 sandbox->Cond(1, | 1257 #if __SIZEOF_POINTER__ > 4 |
1256 ErrorCode::TP_32BIT, | 1258 .Case(1, If(arg64 == 0x55555555AAAAAAAAULL, Error(1)).Else(Error(2))) |
1257 ErrorCode::OP_EQUAL, | 1259 #endif |
1258 0x55555555, | 1260 .Default(Error(3)); |
1259 ErrorCode(1), | |
1260 ErrorCode(2)), | |
1261 // The BPF compiler and the BPF interpreter in the kernel are | |
1262 // (mostly) agnostic of the host platform's word size. The compiler | |
1263 // will happily generate code that tests a 64bit value, and the | |
1264 // interpreter will happily perform this test. | |
1265 // But unless there is a kernel bug, there is no way for us to pass | |
1266 // in a 64bit quantity on a 32bit platform. The upper 32bits should | |
1267 // always be zero. So, this test should always evaluate as false on | |
1268 // 32bit systems. | |
1269 sandbox->Cond(1, | |
1270 ErrorCode::TP_64BIT, | |
1271 ErrorCode::OP_EQUAL, | |
1272 0x55555555AAAAAAAAULL, | |
1273 ErrorCode(1), | |
1274 ErrorCode(2))); | |
1275 } | 1261 } |
1276 return ErrorCode(ErrorCode::ERR_ALLOWED); | 1262 return Allow(); |
1277 } | 1263 } |
1278 | 1264 |
1279 BPF_TEST_C(SandboxBPF, EqualityArgumentWidth, EqualityArgumentWidthPolicy) { | 1265 BPF_TEST_C(SandboxBPF, EqualityArgumentWidth, EqualityArgumentWidthPolicy) { |
1280 BPF_ASSERT(Syscall::Call(__NR_uname, 0, 0x55555555) == -1); | 1266 BPF_ASSERT(Syscall::Call(__NR_uname, 0, 0x55555555) == -1); |
1281 BPF_ASSERT(Syscall::Call(__NR_uname, 0, 0xAAAAAAAA) == -2); | 1267 BPF_ASSERT(Syscall::Call(__NR_uname, 0, 0xAAAAAAAA) == -2); |
1282 #if __SIZEOF_POINTER__ > 4 | 1268 #if __SIZEOF_POINTER__ > 4 |
1283 // On 32bit machines, there is no way to pass a 64bit argument through the | 1269 // On 32bit machines, there is no way to pass a 64bit argument through the |
1284 // syscall interface. So, we have to skip the part of the test that requires | 1270 // syscall interface. So, we have to skip the part of the test that requires |
1285 // 64bit arguments. | 1271 // 64bit arguments. |
1286 BPF_ASSERT(Syscall::Call(__NR_uname, 1, 0x55555555AAAAAAAAULL) == -1); | 1272 BPF_ASSERT(Syscall::Call(__NR_uname, 1, 0x55555555AAAAAAAAULL) == -1); |
1287 BPF_ASSERT(Syscall::Call(__NR_uname, 1, 0x5555555500000000ULL) == -2); | 1273 BPF_ASSERT(Syscall::Call(__NR_uname, 1, 0x5555555500000000ULL) == -2); |
1288 BPF_ASSERT(Syscall::Call(__NR_uname, 1, 0x5555555511111111ULL) == -2); | 1274 BPF_ASSERT(Syscall::Call(__NR_uname, 1, 0x5555555511111111ULL) == -2); |
1289 BPF_ASSERT(Syscall::Call(__NR_uname, 1, 0x11111111AAAAAAAAULL) == -2); | 1275 BPF_ASSERT(Syscall::Call(__NR_uname, 1, 0x11111111AAAAAAAAULL) == -2); |
1290 #else | |
1291 BPF_ASSERT(Syscall::Call(__NR_uname, 1, 0x55555555) == -2); | |
jln (very slow on Chromium)
2014/09/12 23:52:57
Why removed?
mdempsky
2014/09/13 00:20:24
This assert was testing TP_64BIT on a 32-bit syste
| |
1292 #endif | 1276 #endif |
1293 } | 1277 } |
1294 | 1278 |
1295 #if __SIZEOF_POINTER__ > 4 | 1279 #if __SIZEOF_POINTER__ > 4 |
1296 // On 32bit machines, there is no way to pass a 64bit argument through the | 1280 // On 32bit machines, there is no way to pass a 64bit argument through the |
1297 // syscall interface. So, we have to skip the part of the test that requires | 1281 // syscall interface. So, we have to skip the part of the test that requires |
1298 // 64bit arguments. | 1282 // 64bit arguments. |
1299 BPF_DEATH_TEST_C(SandboxBPF, | 1283 BPF_DEATH_TEST_C(SandboxBPF, |
1300 EqualityArgumentUnallowed64bit, | 1284 EqualityArgumentUnallowed64bit, |
1301 DEATH_MESSAGE("Unexpected 64bit argument detected"), | 1285 DEATH_MESSAGE("Unexpected 64bit argument detected"), |
1302 EqualityArgumentWidthPolicy) { | 1286 EqualityArgumentWidthPolicy) { |
1303 Syscall::Call(__NR_uname, 0, 0x5555555555555555ULL); | 1287 Syscall::Call(__NR_uname, 0, 0x5555555555555555ULL); |
1304 } | 1288 } |
1305 #endif | 1289 #endif |
1306 | 1290 |
1307 class EqualityWithNegativeArgumentsPolicy : public SandboxBPFPolicy { | 1291 class EqualityWithNegativeArgumentsPolicy : public SandboxBPFDSLPolicy { |
1308 public: | 1292 public: |
1309 EqualityWithNegativeArgumentsPolicy() {} | 1293 EqualityWithNegativeArgumentsPolicy() {} |
1310 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, | 1294 virtual ~EqualityWithNegativeArgumentsPolicy() {} |
1311 int sysno) const OVERRIDE { | 1295 |
1296 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE { | |
1312 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | 1297 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
1313 if (sysno == __NR_uname) { | 1298 if (sysno == __NR_uname) { |
1314 return sandbox->Cond(0, | 1299 // TODO(mdempsky): This currently can't be Arg<int> because then |
1315 ErrorCode::TP_32BIT, | 1300 // 0xFFFFFFFF will be treated as a (signed) int, and then when |
1316 ErrorCode::OP_EQUAL, | 1301 // Arg::EqualTo casts it to uint64_t, it will be sign extended. |
1317 0xFFFFFFFF, | 1302 const Arg<unsigned> arg(0); |
1318 ErrorCode(1), | 1303 return If(arg == 0xFFFFFFFF, Error(1)).Else(Error(2)); |
1319 ErrorCode(2)); | |
1320 } | 1304 } |
1321 return ErrorCode(ErrorCode::ERR_ALLOWED); | 1305 return Allow(); |
1322 } | 1306 } |
1323 | 1307 |
1324 private: | 1308 private: |
1325 DISALLOW_COPY_AND_ASSIGN(EqualityWithNegativeArgumentsPolicy); | 1309 DISALLOW_COPY_AND_ASSIGN(EqualityWithNegativeArgumentsPolicy); |
1326 }; | 1310 }; |
1327 | 1311 |
1328 BPF_TEST_C(SandboxBPF, | 1312 BPF_TEST_C(SandboxBPF, |
1329 EqualityWithNegativeArguments, | 1313 EqualityWithNegativeArguments, |
1330 EqualityWithNegativeArgumentsPolicy) { | 1314 EqualityWithNegativeArgumentsPolicy) { |
1331 BPF_ASSERT(Syscall::Call(__NR_uname, 0xFFFFFFFF) == -1); | 1315 BPF_ASSERT(Syscall::Call(__NR_uname, 0xFFFFFFFF) == -1); |
1332 BPF_ASSERT(Syscall::Call(__NR_uname, -1) == -1); | 1316 BPF_ASSERT(Syscall::Call(__NR_uname, -1) == -1); |
1333 BPF_ASSERT(Syscall::Call(__NR_uname, -1LL) == -1); | 1317 BPF_ASSERT(Syscall::Call(__NR_uname, -1LL) == -1); |
1334 } | 1318 } |
1335 | 1319 |
1336 #if __SIZEOF_POINTER__ > 4 | 1320 #if __SIZEOF_POINTER__ > 4 |
1337 BPF_DEATH_TEST_C(SandboxBPF, | 1321 BPF_DEATH_TEST_C(SandboxBPF, |
1338 EqualityWithNegative64bitArguments, | 1322 EqualityWithNegative64bitArguments, |
1339 DEATH_MESSAGE("Unexpected 64bit argument detected"), | 1323 DEATH_MESSAGE("Unexpected 64bit argument detected"), |
1340 EqualityWithNegativeArgumentsPolicy) { | 1324 EqualityWithNegativeArgumentsPolicy) { |
1341 // When expecting a 32bit system call argument, we look at the MSB of the | 1325 // When expecting a 32bit system call argument, we look at the MSB of the |
1342 // 64bit value and allow both "0" and "-1". But the latter is allowed only | 1326 // 64bit value and allow both "0" and "-1". But the latter is allowed only |
1343 // iff the LSB was negative. So, this death test should error out. | 1327 // iff the LSB was negative. So, this death test should error out. |
1344 BPF_ASSERT(Syscall::Call(__NR_uname, 0xFFFFFFFF00000000LL) == -1); | 1328 BPF_ASSERT(Syscall::Call(__NR_uname, 0xFFFFFFFF00000000LL) == -1); |
1345 } | 1329 } |
1346 #endif | 1330 #endif |
1347 class AllBitTestPolicy : public SandboxBPFPolicy { | 1331 |
1332 class AllBitTestPolicy : public SandboxBPFDSLPolicy { | |
1348 public: | 1333 public: |
1349 AllBitTestPolicy() {} | 1334 AllBitTestPolicy() {} |
1350 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, | 1335 virtual ~AllBitTestPolicy() {} |
1351 int sysno) const OVERRIDE; | 1336 |
1337 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE; | |
1352 | 1338 |
1353 private: | 1339 private: |
1340 static ResultExpr HasAllBits32(uint32_t bits); | |
1341 static ResultExpr HasAllBits64(uint64_t bits); | |
1342 | |
1354 DISALLOW_COPY_AND_ASSIGN(AllBitTestPolicy); | 1343 DISALLOW_COPY_AND_ASSIGN(AllBitTestPolicy); |
1355 }; | 1344 }; |
1356 | 1345 |
1357 ErrorCode AllBitTestPolicy::EvaluateSyscall(SandboxBPF* sandbox, | 1346 ResultExpr AllBitTestPolicy::HasAllBits32(uint32_t bits) { |
1358 int sysno) const { | 1347 if (bits == 0) { |
1348 return Error(1); | |
1349 } | |
1350 const Arg<uint32_t> arg(1); | |
1351 return If((arg & bits) == bits, Error(1)).Else(Error(0)); | |
1352 } | |
1353 | |
1354 ResultExpr AllBitTestPolicy::HasAllBits64(uint64_t bits) { | |
1355 if (bits == 0) { | |
1356 return Error(1); | |
1357 } | |
1358 const Arg<uint64_t> arg(1); | |
1359 return If((arg & bits) == bits, Error(1)).Else(Error(0)); | |
1360 } | |
1361 | |
1362 ResultExpr AllBitTestPolicy::EvaluateSyscall(int sysno) const { | |
1359 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | 1363 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
1360 // Test the OP_HAS_ALL_BITS conditional test operator with a couple of | 1364 // Test masked-equality cases that should trigger the "has all bits" |
1361 // different bitmasks. We try to find bitmasks that could conceivably | 1365 // peephole optimizations. We try to find bitmasks that could conceivably |
1362 // touch corner cases. | 1366 // touch corner cases. |
1363 // For all of these tests, we override the uname(). We can make use with | 1367 // For all of these tests, we override the uname(). We can make use with |
1364 // a single system call number, as we use the first system call argument to | 1368 // a single system call number, as we use the first system call argument to |
1365 // select the different bit masks that we want to test against. | 1369 // select the different bit masks that we want to test against. |
1366 if (sysno == __NR_uname) { | 1370 if (sysno == __NR_uname) { |
1367 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0, | 1371 const Arg<int> option(0); |
1368 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, | 1372 return Switch(option) |
1369 0x0, | 1373 .Case(0, HasAllBits32(0x0)) |
1370 ErrorCode(1), ErrorCode(0)), | 1374 .Case(1, HasAllBits32(0x1)) |
1371 | 1375 .Case(2, HasAllBits32(0x3)) |
1372 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 1, | 1376 .Case(3, HasAllBits32(0x80000000)) |
1373 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, | 1377 #if __SIZEOF_POINTER__ > 4 |
1374 0x1, | 1378 .Case(4, HasAllBits64(0x0)) |
1375 ErrorCode(1), ErrorCode(0)), | 1379 .Case(5, HasAllBits64(0x1)) |
1376 | 1380 .Case(6, HasAllBits64(0x3)) |
1377 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 2, | 1381 .Case(7, HasAllBits64(0x80000000)) |
1378 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, | 1382 .Case(8, HasAllBits64(0x100000000ULL)) |
1379 0x3, | 1383 .Case(9, HasAllBits64(0x300000000ULL)) |
1380 ErrorCode(1), ErrorCode(0)), | 1384 .Case(10, HasAllBits64(0x100000001ULL)) |
1381 | 1385 #endif |
1382 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 3, | 1386 .Default(Kill("Invalid test case number")); |
1383 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, | |
1384 0x80000000, | |
1385 ErrorCode(1), ErrorCode(0)), | |
1386 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 4, | |
1387 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, | |
1388 0x0, | |
1389 ErrorCode(1), ErrorCode(0)), | |
1390 | |
1391 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 5, | |
1392 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, | |
1393 0x1, | |
1394 ErrorCode(1), ErrorCode(0)), | |
1395 | |
1396 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 6, | |
1397 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, | |
1398 0x3, | |
1399 ErrorCode(1), ErrorCode(0)), | |
1400 | |
1401 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 7, | |
1402 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, | |
1403 0x80000000, | |
1404 ErrorCode(1), ErrorCode(0)), | |
1405 | |
1406 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 8, | |
1407 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, | |
1408 0x100000000ULL, | |
1409 ErrorCode(1), ErrorCode(0)), | |
1410 | |
1411 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 9, | |
1412 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, | |
1413 0x300000000ULL, | |
1414 ErrorCode(1), ErrorCode(0)), | |
1415 | |
1416 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 10, | |
1417 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, | |
1418 0x100000001ULL, | |
1419 ErrorCode(1), ErrorCode(0)), | |
1420 | |
1421 sandbox->Kill("Invalid test case number")))))))))))); | |
1422 } | 1387 } |
1423 return ErrorCode(ErrorCode::ERR_ALLOWED); | 1388 return Allow(); |
1424 } | 1389 } |
1425 | 1390 |
1426 // Define a macro that performs tests using our test policy. | 1391 // Define a macro that performs tests using our test policy. |
1427 // NOTE: Not all of the arguments in this macro are actually used! | 1392 // NOTE: Not all of the arguments in this macro are actually used! |
1428 // They are here just to serve as documentation of the conditions | 1393 // They are here just to serve as documentation of the conditions |
1429 // implemented in the test policy. | 1394 // implemented in the test policy. |
1430 // Most notably, "op" and "mask" are unused by the macro. If you want | 1395 // Most notably, "op" and "mask" are unused by the macro. If you want |
1431 // to make changes to these values, you will have to edit the | 1396 // to make changes to these values, you will have to edit the |
1432 // test policy instead. | 1397 // test policy instead. |
1433 #define BITMASK_TEST(testcase, arg, op, mask, expected_value) \ | 1398 #define BITMASK_TEST(testcase, arg, op, mask, expected_value) \ |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1466 BITMASK_TEST( 2, 3, ALLBITS32, 0x3, EXPECT_SUCCESS); | 1431 BITMASK_TEST( 2, 3, ALLBITS32, 0x3, EXPECT_SUCCESS); |
1467 BITMASK_TEST( 2, 7, ALLBITS32, 0x3, EXPECT_SUCCESS); | 1432 BITMASK_TEST( 2, 7, ALLBITS32, 0x3, EXPECT_SUCCESS); |
1468 | 1433 |
1469 // 32bit test: all of 0x80000000 | 1434 // 32bit test: all of 0x80000000 |
1470 BITMASK_TEST( 3, 0, ALLBITS32, 0x80000000, EXPECT_FAILURE); | 1435 BITMASK_TEST( 3, 0, ALLBITS32, 0x80000000, EXPECT_FAILURE); |
1471 BITMASK_TEST( 3, 0x40000000U, ALLBITS32, 0x80000000, EXPECT_FAILURE); | 1436 BITMASK_TEST( 3, 0x40000000U, ALLBITS32, 0x80000000, EXPECT_FAILURE); |
1472 BITMASK_TEST( 3, 0x80000000U, ALLBITS32, 0x80000000, EXPECT_SUCCESS); | 1437 BITMASK_TEST( 3, 0x80000000U, ALLBITS32, 0x80000000, EXPECT_SUCCESS); |
1473 BITMASK_TEST( 3, 0xC0000000U, ALLBITS32, 0x80000000, EXPECT_SUCCESS); | 1438 BITMASK_TEST( 3, 0xC0000000U, ALLBITS32, 0x80000000, EXPECT_SUCCESS); |
1474 BITMASK_TEST( 3, -0x80000000LL, ALLBITS32, 0x80000000, EXPECT_SUCCESS); | 1439 BITMASK_TEST( 3, -0x80000000LL, ALLBITS32, 0x80000000, EXPECT_SUCCESS); |
1475 | 1440 |
1441 #if __SIZEOF_POINTER__ > 4 | |
1476 // 64bit test: all of 0x0 (should always be true) | 1442 // 64bit test: all of 0x0 (should always be true) |
1477 BITMASK_TEST( 4, 0, ALLBITS64, 0, EXPECT_SUCCESS); | 1443 BITMASK_TEST( 4, 0, ALLBITS64, 0, EXPECT_SUCCESS); |
1478 BITMASK_TEST( 4, 1, ALLBITS64, 0, EXPECT_SUCCESS); | 1444 BITMASK_TEST( 4, 1, ALLBITS64, 0, EXPECT_SUCCESS); |
1479 BITMASK_TEST( 4, 3, ALLBITS64, 0, EXPECT_SUCCESS); | 1445 BITMASK_TEST( 4, 3, ALLBITS64, 0, EXPECT_SUCCESS); |
1480 BITMASK_TEST( 4, 0xFFFFFFFFU, ALLBITS64, 0, EXPECT_SUCCESS); | 1446 BITMASK_TEST( 4, 0xFFFFFFFFU, ALLBITS64, 0, EXPECT_SUCCESS); |
1481 BITMASK_TEST( 4, 0x100000000LL, ALLBITS64, 0, EXPECT_SUCCESS); | 1447 BITMASK_TEST( 4, 0x100000000LL, ALLBITS64, 0, EXPECT_SUCCESS); |
1482 BITMASK_TEST( 4, 0x300000000LL, ALLBITS64, 0, EXPECT_SUCCESS); | 1448 BITMASK_TEST( 4, 0x300000000LL, ALLBITS64, 0, EXPECT_SUCCESS); |
1483 BITMASK_TEST( 4,0x8000000000000000LL, ALLBITS64, 0, EXPECT_SUCCESS); | 1449 BITMASK_TEST( 4,0x8000000000000000LL, ALLBITS64, 0, EXPECT_SUCCESS); |
1484 BITMASK_TEST( 4, -1LL, ALLBITS64, 0, EXPECT_SUCCESS); | 1450 BITMASK_TEST( 4, -1LL, ALLBITS64, 0, EXPECT_SUCCESS); |
1485 | 1451 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1539 BITMASK_TEST( 9, 0x300000001LL, ALLBITS64,0x300000000, EXPT64_SUCCESS); | 1505 BITMASK_TEST( 9, 0x300000001LL, ALLBITS64,0x300000000, EXPT64_SUCCESS); |
1540 BITMASK_TEST( 9, 0x700000001LL, ALLBITS64,0x300000000, EXPT64_SUCCESS); | 1506 BITMASK_TEST( 9, 0x700000001LL, ALLBITS64,0x300000000, EXPT64_SUCCESS); |
1541 | 1507 |
1542 // 64bit test: all of 0x100000001 | 1508 // 64bit test: all of 0x100000001 |
1543 BITMASK_TEST(10, 0x000000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE); | 1509 BITMASK_TEST(10, 0x000000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE); |
1544 BITMASK_TEST(10, 0x000000001LL, ALLBITS64,0x100000001, EXPECT_FAILURE); | 1510 BITMASK_TEST(10, 0x000000001LL, ALLBITS64,0x100000001, EXPECT_FAILURE); |
1545 BITMASK_TEST(10, 0x100000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE); | 1511 BITMASK_TEST(10, 0x100000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE); |
1546 BITMASK_TEST(10, 0x100000001LL, ALLBITS64,0x100000001, EXPT64_SUCCESS); | 1512 BITMASK_TEST(10, 0x100000001LL, ALLBITS64,0x100000001, EXPT64_SUCCESS); |
1547 BITMASK_TEST(10, 0xFFFFFFFFU, ALLBITS64,0x100000001, EXPECT_FAILURE); | 1513 BITMASK_TEST(10, 0xFFFFFFFFU, ALLBITS64,0x100000001, EXPECT_FAILURE); |
1548 BITMASK_TEST(10, -1L, ALLBITS64,0x100000001, EXPT64_SUCCESS); | 1514 BITMASK_TEST(10, -1L, ALLBITS64,0x100000001, EXPT64_SUCCESS); |
1515 #endif | |
1549 } | 1516 } |
1550 | 1517 |
1551 class AnyBitTestPolicy : public SandboxBPFPolicy { | 1518 class AnyBitTestPolicy : public SandboxBPFDSLPolicy { |
1552 public: | 1519 public: |
1553 AnyBitTestPolicy() {} | 1520 AnyBitTestPolicy() {} |
1554 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, | 1521 virtual ~AnyBitTestPolicy() {} |
1555 int sysno) const OVERRIDE; | 1522 |
1523 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE; | |
1556 | 1524 |
1557 private: | 1525 private: |
1526 static ResultExpr HasAnyBits32(uint32_t); | |
1527 static ResultExpr HasAnyBits64(uint64_t); | |
1528 | |
1558 DISALLOW_COPY_AND_ASSIGN(AnyBitTestPolicy); | 1529 DISALLOW_COPY_AND_ASSIGN(AnyBitTestPolicy); |
1559 }; | 1530 }; |
1560 | 1531 |
1561 ErrorCode AnyBitTestPolicy::EvaluateSyscall(SandboxBPF* sandbox, | 1532 ResultExpr AnyBitTestPolicy::HasAnyBits32(uint32_t bits) { |
1562 int sysno) const { | 1533 if (bits == 0) { |
1534 return Error(0); | |
1535 } | |
1536 const Arg<uint32_t> arg(1); | |
1537 return If((arg & bits) != 0, Error(1)).Else(Error(0)); | |
1538 } | |
1539 | |
1540 ResultExpr AnyBitTestPolicy::HasAnyBits64(uint64_t bits) { | |
1541 if (bits == 0) { | |
1542 return Error(0); | |
1543 } | |
1544 const Arg<uint64_t> arg(1); | |
1545 return If((arg & bits) != 0, Error(1)).Else(Error(0)); | |
1546 } | |
1547 | |
1548 ResultExpr AnyBitTestPolicy::EvaluateSyscall(int sysno) const { | |
1563 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | 1549 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
1564 // Test the OP_HAS_ANY_BITS conditional test operator with a couple of | 1550 // Test masked-equality cases that should trigger the "has any bits" |
1565 // different bitmasks. We try to find bitmasks that could conceivably | 1551 // peephole optimizations. We try to find bitmasks that could conceivably |
1566 // touch corner cases. | 1552 // touch corner cases. |
1567 // For all of these tests, we override the uname(). We can make use with | 1553 // For all of these tests, we override the uname(). We can make use with |
1568 // a single system call number, as we use the first system call argument to | 1554 // a single system call number, as we use the first system call argument to |
1569 // select the different bit masks that we want to test against. | 1555 // select the different bit masks that we want to test against. |
1570 if (sysno == __NR_uname) { | 1556 if (sysno == __NR_uname) { |
1571 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0, | 1557 const Arg<int> option(0); |
1572 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, | 1558 return Switch(option) |
1573 0x0, | 1559 .Case(0, HasAnyBits32(0x0)) |
1574 ErrorCode(1), ErrorCode(0)), | 1560 .Case(1, HasAnyBits32(0x1)) |
1575 | 1561 .Case(2, HasAnyBits32(0x3)) |
1576 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 1, | 1562 .Case(3, HasAnyBits32(0x80000000)) |
1577 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, | 1563 #if __SIZEOF_POINTER__ > 4 |
1578 0x1, | 1564 .Case(4, HasAnyBits64(0x0)) |
1579 ErrorCode(1), ErrorCode(0)), | 1565 .Case(5, HasAnyBits64(0x1)) |
1580 | 1566 .Case(6, HasAnyBits64(0x3)) |
1581 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 2, | 1567 .Case(7, HasAnyBits64(0x80000000)) |
1582 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, | 1568 .Case(8, HasAnyBits64(0x100000000ULL)) |
1583 0x3, | 1569 .Case(9, HasAnyBits64(0x300000000ULL)) |
1584 ErrorCode(1), ErrorCode(0)), | 1570 .Case(10, HasAnyBits64(0x100000001ULL)) |
1585 | 1571 #endif |
1586 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 3, | 1572 .Default(Kill("Invalid test case number")); |
1587 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, | |
1588 0x80000000, | |
1589 ErrorCode(1), ErrorCode(0)), | |
1590 | |
1591 // All the following tests don't really make much sense on 32bit | |
1592 // systems. They will always evaluate as false. | |
1593 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 4, | |
1594 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, | |
1595 0x0, | |
1596 ErrorCode(1), ErrorCode(0)), | |
1597 | |
1598 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 5, | |
1599 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, | |
1600 0x1, | |
1601 ErrorCode(1), ErrorCode(0)), | |
1602 | |
1603 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 6, | |
1604 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, | |
1605 0x3, | |
1606 ErrorCode(1), ErrorCode(0)), | |
1607 | |
1608 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 7, | |
1609 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, | |
1610 0x80000000, | |
1611 ErrorCode(1), ErrorCode(0)), | |
1612 | |
1613 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 8, | |
1614 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, | |
1615 0x100000000ULL, | |
1616 ErrorCode(1), ErrorCode(0)), | |
1617 | |
1618 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 9, | |
1619 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, | |
1620 0x300000000ULL, | |
1621 ErrorCode(1), ErrorCode(0)), | |
1622 | |
1623 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 10, | |
1624 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, | |
1625 0x100000001ULL, | |
1626 ErrorCode(1), ErrorCode(0)), | |
1627 | |
1628 sandbox->Kill("Invalid test case number")))))))))))); | |
1629 } | 1573 } |
1630 return ErrorCode(ErrorCode::ERR_ALLOWED); | 1574 return Allow(); |
1631 } | 1575 } |
1632 | 1576 |
1633 BPF_TEST_C(SandboxBPF, AnyBitTests, AnyBitTestPolicy) { | 1577 BPF_TEST_C(SandboxBPF, AnyBitTests, AnyBitTestPolicy) { |
1634 // 32bit test: any of 0x0 (should always be false) | 1578 // 32bit test: any of 0x0 (should always be false) |
1635 BITMASK_TEST( 0, 0, ANYBITS32, 0x0, EXPECT_FAILURE); | 1579 BITMASK_TEST( 0, 0, ANYBITS32, 0x0, EXPECT_FAILURE); |
1636 BITMASK_TEST( 0, 1, ANYBITS32, 0x0, EXPECT_FAILURE); | 1580 BITMASK_TEST( 0, 1, ANYBITS32, 0x0, EXPECT_FAILURE); |
1637 BITMASK_TEST( 0, 3, ANYBITS32, 0x0, EXPECT_FAILURE); | 1581 BITMASK_TEST( 0, 3, ANYBITS32, 0x0, EXPECT_FAILURE); |
1638 BITMASK_TEST( 0, 0xFFFFFFFFU, ANYBITS32, 0x0, EXPECT_FAILURE); | 1582 BITMASK_TEST( 0, 0xFFFFFFFFU, ANYBITS32, 0x0, EXPECT_FAILURE); |
1639 BITMASK_TEST( 0, -1LL, ANYBITS32, 0x0, EXPECT_FAILURE); | 1583 BITMASK_TEST( 0, -1LL, ANYBITS32, 0x0, EXPECT_FAILURE); |
1640 | 1584 |
(...skipping 10 matching lines...) Expand all Loading... | |
1651 BITMASK_TEST( 2, 3, ANYBITS32, 0x3, EXPECT_SUCCESS); | 1595 BITMASK_TEST( 2, 3, ANYBITS32, 0x3, EXPECT_SUCCESS); |
1652 BITMASK_TEST( 2, 7, ANYBITS32, 0x3, EXPECT_SUCCESS); | 1596 BITMASK_TEST( 2, 7, ANYBITS32, 0x3, EXPECT_SUCCESS); |
1653 | 1597 |
1654 // 32bit test: any of 0x80000000 | 1598 // 32bit test: any of 0x80000000 |
1655 BITMASK_TEST( 3, 0, ANYBITS32, 0x80000000, EXPECT_FAILURE); | 1599 BITMASK_TEST( 3, 0, ANYBITS32, 0x80000000, EXPECT_FAILURE); |
1656 BITMASK_TEST( 3, 0x40000000U, ANYBITS32, 0x80000000, EXPECT_FAILURE); | 1600 BITMASK_TEST( 3, 0x40000000U, ANYBITS32, 0x80000000, EXPECT_FAILURE); |
1657 BITMASK_TEST( 3, 0x80000000U, ANYBITS32, 0x80000000, EXPECT_SUCCESS); | 1601 BITMASK_TEST( 3, 0x80000000U, ANYBITS32, 0x80000000, EXPECT_SUCCESS); |
1658 BITMASK_TEST( 3, 0xC0000000U, ANYBITS32, 0x80000000, EXPECT_SUCCESS); | 1602 BITMASK_TEST( 3, 0xC0000000U, ANYBITS32, 0x80000000, EXPECT_SUCCESS); |
1659 BITMASK_TEST( 3, -0x80000000LL, ANYBITS32, 0x80000000, EXPECT_SUCCESS); | 1603 BITMASK_TEST( 3, -0x80000000LL, ANYBITS32, 0x80000000, EXPECT_SUCCESS); |
1660 | 1604 |
1605 #if __SIZEOF_POINTER__ > 4 | |
1661 // 64bit test: any of 0x0 (should always be false) | 1606 // 64bit test: any of 0x0 (should always be false) |
1662 BITMASK_TEST( 4, 0, ANYBITS64, 0x0, EXPECT_FAILURE); | 1607 BITMASK_TEST( 4, 0, ANYBITS64, 0x0, EXPECT_FAILURE); |
1663 BITMASK_TEST( 4, 1, ANYBITS64, 0x0, EXPECT_FAILURE); | 1608 BITMASK_TEST( 4, 1, ANYBITS64, 0x0, EXPECT_FAILURE); |
1664 BITMASK_TEST( 4, 3, ANYBITS64, 0x0, EXPECT_FAILURE); | 1609 BITMASK_TEST( 4, 3, ANYBITS64, 0x0, EXPECT_FAILURE); |
1665 BITMASK_TEST( 4, 0xFFFFFFFFU, ANYBITS64, 0x0, EXPECT_FAILURE); | 1610 BITMASK_TEST( 4, 0xFFFFFFFFU, ANYBITS64, 0x0, EXPECT_FAILURE); |
1666 BITMASK_TEST( 4, 0x100000000LL, ANYBITS64, 0x0, EXPECT_FAILURE); | 1611 BITMASK_TEST( 4, 0x100000000LL, ANYBITS64, 0x0, EXPECT_FAILURE); |
1667 BITMASK_TEST( 4, 0x300000000LL, ANYBITS64, 0x0, EXPECT_FAILURE); | 1612 BITMASK_TEST( 4, 0x300000000LL, ANYBITS64, 0x0, EXPECT_FAILURE); |
1668 BITMASK_TEST( 4,0x8000000000000000LL, ANYBITS64, 0x0, EXPECT_FAILURE); | 1613 BITMASK_TEST( 4,0x8000000000000000LL, ANYBITS64, 0x0, EXPECT_FAILURE); |
1669 BITMASK_TEST( 4, -1LL, ANYBITS64, 0x0, EXPECT_FAILURE); | 1614 BITMASK_TEST( 4, -1LL, ANYBITS64, 0x0, EXPECT_FAILURE); |
1670 | 1615 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1724 BITMASK_TEST( 9, 0x300000001LL, ANYBITS64,0x300000000, EXPT64_SUCCESS); | 1669 BITMASK_TEST( 9, 0x300000001LL, ANYBITS64,0x300000000, EXPT64_SUCCESS); |
1725 BITMASK_TEST( 9, 0x700000001LL, ANYBITS64,0x300000000, EXPT64_SUCCESS); | 1670 BITMASK_TEST( 9, 0x700000001LL, ANYBITS64,0x300000000, EXPT64_SUCCESS); |
1726 | 1671 |
1727 // 64bit test: any of 0x100000001 | 1672 // 64bit test: any of 0x100000001 |
1728 BITMASK_TEST( 10, 0x000000000LL, ANYBITS64,0x100000001, EXPECT_FAILURE); | 1673 BITMASK_TEST( 10, 0x000000000LL, ANYBITS64,0x100000001, EXPECT_FAILURE); |
1729 BITMASK_TEST( 10, 0x000000001LL, ANYBITS64,0x100000001, EXPECT_SUCCESS); | 1674 BITMASK_TEST( 10, 0x000000001LL, ANYBITS64,0x100000001, EXPECT_SUCCESS); |
1730 BITMASK_TEST( 10, 0x100000000LL, ANYBITS64,0x100000001, EXPT64_SUCCESS); | 1675 BITMASK_TEST( 10, 0x100000000LL, ANYBITS64,0x100000001, EXPT64_SUCCESS); |
1731 BITMASK_TEST( 10, 0x100000001LL, ANYBITS64,0x100000001, EXPECT_SUCCESS); | 1676 BITMASK_TEST( 10, 0x100000001LL, ANYBITS64,0x100000001, EXPECT_SUCCESS); |
1732 BITMASK_TEST( 10, 0xFFFFFFFFU, ANYBITS64,0x100000001, EXPECT_SUCCESS); | 1677 BITMASK_TEST( 10, 0xFFFFFFFFU, ANYBITS64,0x100000001, EXPECT_SUCCESS); |
1733 BITMASK_TEST( 10, -1L, ANYBITS64,0x100000001, EXPECT_SUCCESS); | 1678 BITMASK_TEST( 10, -1L, ANYBITS64,0x100000001, EXPECT_SUCCESS); |
1679 #endif | |
1734 } | 1680 } |
1735 | 1681 |
1736 class MaskedEqualTestPolicy : public SandboxBPFPolicy { | 1682 class MaskedEqualTestPolicy : public SandboxBPFDSLPolicy { |
1737 public: | 1683 public: |
1738 MaskedEqualTestPolicy() {} | 1684 MaskedEqualTestPolicy() {} |
1739 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, | 1685 virtual ~MaskedEqualTestPolicy() {} |
1740 int sysno) const OVERRIDE; | 1686 |
1687 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE; | |
1741 | 1688 |
1742 private: | 1689 private: |
1743 struct Rule { | 1690 static ResultExpr MaskedEqual32(uint32_t mask, uint32_t value); |
1744 ErrorCode::ArgType arg_type; | 1691 static ResultExpr MaskedEqual64(uint64_t mask, uint64_t value); |
1745 uint64_t mask; | |
1746 uint64_t value; | |
1747 }; | |
1748 | |
1749 static Rule rules[]; | |
1750 | 1692 |
1751 DISALLOW_COPY_AND_ASSIGN(MaskedEqualTestPolicy); | 1693 DISALLOW_COPY_AND_ASSIGN(MaskedEqualTestPolicy); |
1752 }; | 1694 }; |
1753 | 1695 |
1754 MaskedEqualTestPolicy::Rule MaskedEqualTestPolicy::rules[] = { | 1696 ResultExpr MaskedEqualTestPolicy::MaskedEqual32(uint32_t mask, uint32_t value) { |
1755 /* 0 = */ {ErrorCode::TP_32BIT, 0x0000000000ff00ff, 0x00000000005500aa}, | 1697 const Arg<uint32_t> arg(1); |
1698 return If((arg & mask) == value, Error(1)).Else(Error(0)); | |
1699 } | |
1756 | 1700 |
1757 #if __SIZEOF_POINTER__ > 4 | 1701 ResultExpr MaskedEqualTestPolicy::MaskedEqual64(uint64_t mask, uint64_t value) { |
1758 /* 1 = */ {ErrorCode::TP_64BIT, 0x00ff00ff00000000, 0x005500aa00000000}, | 1702 const Arg<uint64_t> arg(1); |
1759 /* 2 = */ {ErrorCode::TP_64BIT, 0x00ff00ff00ff00ff, 0x005500aa005500aa}, | 1703 return If((arg & mask) == value, Error(1)).Else(Error(0)); |
1760 #endif | 1704 } |
1761 }; | |
1762 | 1705 |
1763 ErrorCode MaskedEqualTestPolicy::EvaluateSyscall(SandboxBPF* sandbox, | 1706 ResultExpr MaskedEqualTestPolicy::EvaluateSyscall(int sysno) const { |
1764 int sysno) const { | |
1765 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | 1707 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
1766 | 1708 |
1767 if (sysno == __NR_uname) { | 1709 if (sysno == __NR_uname) { |
1768 ErrorCode err = sandbox->Kill("Invalid test case number"); | 1710 const Arg<int> option(0); |
1769 for (size_t i = 0; i < arraysize(rules); i++) { | 1711 return Switch(option) |
1770 err = sandbox->Cond(0, | 1712 .Case(0, MaskedEqual32(0x00ff00ff, 0x005500aa)) |
1771 ErrorCode::TP_32BIT, | 1713 #if __SIZEOF_POINTER__ > 4 |
1772 ErrorCode::OP_EQUAL, | 1714 .Case(1, MaskedEqual64(0x00ff00ff00000000, 0x005500aa00000000)) |
1773 i, | 1715 .Case(2, MaskedEqual64(0x00ff00ff00ff00ff, 0x005500aa005500aa)) |
1774 sandbox->CondMaskedEqual(1, | 1716 #endif |
1775 rules[i].arg_type, | 1717 .Default(Kill("Invalid test case number")); |
1776 rules[i].mask, | |
1777 rules[i].value, | |
1778 ErrorCode(1), | |
1779 ErrorCode(0)), | |
1780 err); | |
1781 } | |
1782 return err; | |
1783 } | 1718 } |
1784 return ErrorCode(ErrorCode::ERR_ALLOWED); | 1719 |
1720 return Allow(); | |
1785 } | 1721 } |
1786 | 1722 |
1787 #define MASKEQ_TEST(rulenum, arg, expected_result) \ | 1723 #define MASKEQ_TEST(rulenum, arg, expected_result) \ |
1788 BPF_ASSERT(Syscall::Call(__NR_uname, (rulenum), (arg)) == (expected_result)) | 1724 BPF_ASSERT(Syscall::Call(__NR_uname, (rulenum), (arg)) == (expected_result)) |
1789 | 1725 |
1790 BPF_TEST_C(SandboxBPF, MaskedEqualTests, MaskedEqualTestPolicy) { | 1726 BPF_TEST_C(SandboxBPF, MaskedEqualTests, MaskedEqualTestPolicy) { |
1791 // Allowed: 0x__55__aa | 1727 // Allowed: 0x__55__aa |
1792 MASKEQ_TEST(0, 0x00000000, EXPECT_FAILURE); | 1728 MASKEQ_TEST(0, 0x00000000, EXPECT_FAILURE); |
1793 MASKEQ_TEST(0, 0x00000001, EXPECT_FAILURE); | 1729 MASKEQ_TEST(0, 0x00000001, EXPECT_FAILURE); |
1794 MASKEQ_TEST(0, 0x00000003, EXPECT_FAILURE); | 1730 MASKEQ_TEST(0, 0x00000003, EXPECT_FAILURE); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1863 (long long)args.args[1], | 1799 (long long)args.args[1], |
1864 (long long)args.args[2], | 1800 (long long)args.args[2], |
1865 (long long)args.args[3], | 1801 (long long)args.args[3], |
1866 (long long)args.args[4], | 1802 (long long)args.args[4], |
1867 (long long)args.args[5], | 1803 (long long)args.args[5], |
1868 msg); | 1804 msg); |
1869 } | 1805 } |
1870 return -EPERM; | 1806 return -EPERM; |
1871 } | 1807 } |
1872 | 1808 |
1873 class PthreadPolicyEquality : public SandboxBPFPolicy { | 1809 class PthreadPolicyEquality : public SandboxBPFDSLPolicy { |
1874 public: | 1810 public: |
1875 PthreadPolicyEquality() {} | 1811 PthreadPolicyEquality() {} |
1876 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, | 1812 virtual ~PthreadPolicyEquality() {} |
1877 int sysno) const OVERRIDE; | 1813 |
1814 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE; | |
1878 | 1815 |
1879 private: | 1816 private: |
1880 DISALLOW_COPY_AND_ASSIGN(PthreadPolicyEquality); | 1817 DISALLOW_COPY_AND_ASSIGN(PthreadPolicyEquality); |
1881 }; | 1818 }; |
1882 | 1819 |
1883 ErrorCode PthreadPolicyEquality::EvaluateSyscall(SandboxBPF* sandbox, | 1820 ResultExpr PthreadPolicyEquality::EvaluateSyscall(int sysno) const { |
1884 int sysno) const { | |
1885 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | 1821 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
1886 // This policy allows creating threads with pthread_create(). But it | 1822 // This policy allows creating threads with pthread_create(). But it |
1887 // doesn't allow any other uses of clone(). Most notably, it does not | 1823 // doesn't allow any other uses of clone(). Most notably, it does not |
1888 // allow callers to implement fork() or vfork() by passing suitable flags | 1824 // allow callers to implement fork() or vfork() by passing suitable flags |
1889 // to the clone() system call. | 1825 // to the clone() system call. |
1890 if (sysno == __NR_clone) { | 1826 if (sysno == __NR_clone) { |
1891 // We have seen two different valid combinations of flags. Glibc | 1827 // We have seen two different valid combinations of flags. Glibc |
1892 // uses the more modern flags, sets the TLS from the call to clone(), and | 1828 // uses the more modern flags, sets the TLS from the call to clone(), and |
1893 // uses futexes to monitor threads. Android's C run-time library, doesn't | 1829 // uses futexes to monitor threads. Android's C run-time library, doesn't |
1894 // do any of this, but it sets the obsolete (and no-op) CLONE_DETACHED. | 1830 // do any of this, but it sets the obsolete (and no-op) CLONE_DETACHED. |
1895 // More recent versions of Android don't set CLONE_DETACHED anymore, so | 1831 // More recent versions of Android don't set CLONE_DETACHED anymore, so |
1896 // the last case accounts for that. | 1832 // the last case accounts for that. |
1897 // The following policy is very strict. It only allows the exact masks | 1833 // The following policy is very strict. It only allows the exact masks |
1898 // that we have seen in known implementations. It is probably somewhat | 1834 // that we have seen in known implementations. It is probably somewhat |
1899 // stricter than what we would want to do. | 1835 // stricter than what we would want to do. |
1900 const uint64_t kGlibcCloneMask = | 1836 const uint64_t kGlibcCloneMask = CLONE_VM | CLONE_FS | CLONE_FILES | |
1901 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | | 1837 CLONE_SIGHAND | CLONE_THREAD | |
1902 CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS | | 1838 CLONE_SYSVSEM | CLONE_SETTLS | |
1903 CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID; | 1839 CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID; |
1904 const uint64_t kBaseAndroidCloneMask = | 1840 const uint64_t kBaseAndroidCloneMask = CLONE_VM | CLONE_FS | CLONE_FILES | |
1905 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | | 1841 CLONE_SIGHAND | CLONE_THREAD | |
1906 CLONE_THREAD | CLONE_SYSVSEM; | 1842 CLONE_SYSVSEM; |
1907 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, | 1843 const Arg<unsigned long> flags(0); |
1908 kGlibcCloneMask, | 1844 return If(flags == kGlibcCloneMask || |
1909 ErrorCode(ErrorCode::ERR_ALLOWED), | 1845 flags == (kBaseAndroidCloneMask | CLONE_DETACHED) || |
1910 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, | 1846 flags == kBaseAndroidCloneMask, |
1911 kBaseAndroidCloneMask | CLONE_DETACHED, | 1847 Allow()).Else(Trap(PthreadTrapHandler, "Unknown mask")); |
1912 ErrorCode(ErrorCode::ERR_ALLOWED), | |
1913 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, | |
1914 kBaseAndroidCloneMask, | |
1915 ErrorCode(ErrorCode::ERR_ALLOWED), | |
1916 sandbox->Trap(PthreadTrapHandler, "Unknown mask")))); | |
1917 } | 1848 } |
1918 return ErrorCode(ErrorCode::ERR_ALLOWED); | 1849 |
1850 return Allow(); | |
1919 } | 1851 } |
1920 | 1852 |
1921 class PthreadPolicyBitMask : public SandboxBPFPolicy { | 1853 class PthreadPolicyBitMask : public SandboxBPFDSLPolicy { |
1922 public: | 1854 public: |
1923 PthreadPolicyBitMask() {} | 1855 PthreadPolicyBitMask() {} |
1924 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, | 1856 virtual ~PthreadPolicyBitMask() {} |
1925 int sysno) const OVERRIDE; | 1857 |
1858 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE; | |
1926 | 1859 |
1927 private: | 1860 private: |
1861 static BoolExpr HasAnyBits(const Arg<unsigned long>& arg, unsigned long bits); | |
1862 static BoolExpr HasAllBits(const Arg<unsigned long>& arg, unsigned long bits); | |
1863 | |
1928 DISALLOW_COPY_AND_ASSIGN(PthreadPolicyBitMask); | 1864 DISALLOW_COPY_AND_ASSIGN(PthreadPolicyBitMask); |
1929 }; | 1865 }; |
1930 | 1866 |
1931 ErrorCode PthreadPolicyBitMask::EvaluateSyscall(SandboxBPF* sandbox, | 1867 BoolExpr PthreadPolicyBitMask::HasAnyBits(const Arg<unsigned long>& arg, |
1932 int sysno) const { | 1868 unsigned long bits) { |
1869 return (arg & bits) != 0; | |
1870 } | |
1871 | |
1872 BoolExpr PthreadPolicyBitMask::HasAllBits(const Arg<unsigned long>& arg, | |
1873 unsigned long bits) { | |
1874 return (arg & bits) == bits; | |
1875 } | |
1876 | |
1877 ResultExpr PthreadPolicyBitMask::EvaluateSyscall(int sysno) const { | |
1933 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | 1878 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
1934 // This policy allows creating threads with pthread_create(). But it | 1879 // This policy allows creating threads with pthread_create(). But it |
1935 // doesn't allow any other uses of clone(). Most notably, it does not | 1880 // doesn't allow any other uses of clone(). Most notably, it does not |
1936 // allow callers to implement fork() or vfork() by passing suitable flags | 1881 // allow callers to implement fork() or vfork() by passing suitable flags |
1937 // to the clone() system call. | 1882 // to the clone() system call. |
1938 if (sysno == __NR_clone) { | 1883 if (sysno == __NR_clone) { |
1939 // We have seen two different valid combinations of flags. Glibc | 1884 // We have seen two different valid combinations of flags. Glibc |
1940 // uses the more modern flags, sets the TLS from the call to clone(), and | 1885 // uses the more modern flags, sets the TLS from the call to clone(), and |
1941 // uses futexes to monitor threads. Android's C run-time library, doesn't | 1886 // uses futexes to monitor threads. Android's C run-time library, doesn't |
1942 // do any of this, but it sets the obsolete (and no-op) CLONE_DETACHED. | 1887 // do any of this, but it sets the obsolete (and no-op) CLONE_DETACHED. |
1943 // The following policy allows for either combination of flags, but it | 1888 // The following policy allows for either combination of flags, but it |
1944 // is generally a little more conservative than strictly necessary. We | 1889 // is generally a little more conservative than strictly necessary. We |
1945 // err on the side of rather safe than sorry. | 1890 // err on the side of rather safe than sorry. |
1946 // Very noticeably though, we disallow fork() (which is often just a | 1891 // Very noticeably though, we disallow fork() (which is often just a |
1947 // wrapper around clone()). | 1892 // wrapper around clone()). |
1948 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, | 1893 const unsigned long kMandatoryFlags = CLONE_VM | CLONE_FS | CLONE_FILES | |
1949 ~uint32(CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND| | 1894 CLONE_SIGHAND | CLONE_THREAD | |
1950 CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS| | 1895 CLONE_SYSVSEM; |
1951 CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID| | 1896 const unsigned long kFutexFlags = |
1952 CLONE_DETACHED), | 1897 CLONE_SETTLS | CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID; |
1953 sandbox->Trap(PthreadTrapHandler, | 1898 const unsigned long kNoopFlags = CLONE_DETACHED; |
1954 "Unexpected CLONE_XXX flag found"), | 1899 const unsigned long kKnownFlags = |
1955 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, | 1900 kMandatoryFlags | kFutexFlags | kNoopFlags; |
1956 CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND| | 1901 |
1957 CLONE_THREAD|CLONE_SYSVSEM, | 1902 const Arg<unsigned long> flags(0); |
1958 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, | 1903 return If(HasAnyBits(flags, ~kKnownFlags), |
1959 CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, | 1904 Trap(PthreadTrapHandler, "Unexpected CLONE_XXX flag found")) |
1960 ErrorCode(ErrorCode::ERR_ALLOWED), | 1905 .ElseIf(!HasAllBits(flags, kMandatoryFlags), |
1961 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, | 1906 Trap(PthreadTrapHandler, |
1962 CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, | 1907 "Missing mandatory CLONE_XXX flags " |
1963 sandbox->Trap(PthreadTrapHandler, | 1908 "when creating new thread")) |
1964 "Must set either all or none of the TLS" | 1909 .ElseIf( |
1965 " and futex bits in call to clone()"), | 1910 !HasAllBits(flags, kFutexFlags) && HasAnyBits(flags, kFutexFlags), |
1966 ErrorCode(ErrorCode::ERR_ALLOWED))), | 1911 Trap(PthreadTrapHandler, |
1967 sandbox->Trap(PthreadTrapHandler, | 1912 "Must set either all or none of the TLS and futex bits in " |
1968 "Missing mandatory CLONE_XXX flags " | 1913 "call to clone()")) |
1969 "when creating new thread"))); | 1914 .Else(Allow()); |
1970 } | 1915 } |
1971 return ErrorCode(ErrorCode::ERR_ALLOWED); | 1916 |
1917 return Allow(); | |
1972 } | 1918 } |
1973 | 1919 |
1974 static void* ThreadFnc(void* arg) { | 1920 static void* ThreadFnc(void* arg) { |
1975 ++*reinterpret_cast<int*>(arg); | 1921 ++*reinterpret_cast<int*>(arg); |
1976 Syscall::Call(__NR_futex, arg, FUTEX_WAKE, 1, 0, 0, 0); | 1922 Syscall::Call(__NR_futex, arg, FUTEX_WAKE, 1, 0, 0, 0); |
1977 return NULL; | 1923 return NULL; |
1978 } | 1924 } |
1979 | 1925 |
1980 static void PthreadTest() { | 1926 static void PthreadTest() { |
1981 // Attempt to start a joinable thread. This should succeed. | 1927 // Attempt to start a joinable thread. This should succeed. |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2068 // PTRACE_SET_SYSCALL may not be in the enum. | 2014 // PTRACE_SET_SYSCALL may not be in the enum. |
2069 return syscall(__NR_ptrace, PTRACE_SET_SYSCALL, pid, NULL, syscall_number); | 2015 return syscall(__NR_ptrace, PTRACE_SET_SYSCALL, pid, NULL, syscall_number); |
2070 #endif | 2016 #endif |
2071 | 2017 |
2072 SECCOMP_PT_SYSCALL(*regs) = syscall_number; | 2018 SECCOMP_PT_SYSCALL(*regs) = syscall_number; |
2073 return 0; | 2019 return 0; |
2074 } | 2020 } |
2075 | 2021 |
2076 const uint16_t kTraceData = 0xcc; | 2022 const uint16_t kTraceData = 0xcc; |
2077 | 2023 |
2078 class TraceAllPolicy : public SandboxBPFPolicy { | 2024 class TraceAllPolicy : public SandboxBPFDSLPolicy { |
2079 public: | 2025 public: |
2080 TraceAllPolicy() {} | 2026 TraceAllPolicy() {} |
2081 virtual ~TraceAllPolicy() {} | 2027 virtual ~TraceAllPolicy() {} |
2082 | 2028 |
2083 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, | 2029 virtual ResultExpr EvaluateSyscall(int system_call_number) const OVERRIDE { |
2084 int system_call_number) const OVERRIDE { | 2030 return Trace(kTraceData); |
2085 return ErrorCode(ErrorCode::ERR_TRACE + kTraceData); | |
2086 } | 2031 } |
2087 | 2032 |
2088 private: | 2033 private: |
2089 DISALLOW_COPY_AND_ASSIGN(TraceAllPolicy); | 2034 DISALLOW_COPY_AND_ASSIGN(TraceAllPolicy); |
2090 }; | 2035 }; |
2091 | 2036 |
2092 SANDBOX_TEST(SandboxBPF, DISABLE_ON_TSAN(SeccompRetTrace)) { | 2037 SANDBOX_TEST(SandboxBPF, DISABLE_ON_TSAN(SeccompRetTrace)) { |
2093 if (SandboxBPF::SupportsSeccompSandbox(-1) != | 2038 if (SandboxBPF::SupportsSeccompSandbox(-1) != |
2094 sandbox::SandboxBPF::STATUS_AVAILABLE) { | 2039 sandbox::SandboxBPF::STATUS_AVAILABLE) { |
2095 return; | 2040 return; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2130 syscall(__NR_kill, my_pid, SIGKILL); | 2075 syscall(__NR_kill, my_pid, SIGKILL); |
2131 | 2076 |
2132 // Should not be reached. | 2077 // Should not be reached. |
2133 BPF_ASSERT(false); | 2078 BPF_ASSERT(false); |
2134 } | 2079 } |
2135 | 2080 |
2136 int status; | 2081 int status; |
2137 BPF_ASSERT(HANDLE_EINTR(waitpid(pid, &status, WUNTRACED)) != -1); | 2082 BPF_ASSERT(HANDLE_EINTR(waitpid(pid, &status, WUNTRACED)) != -1); |
2138 BPF_ASSERT(WIFSTOPPED(status)); | 2083 BPF_ASSERT(WIFSTOPPED(status)); |
2139 | 2084 |
2140 BPF_ASSERT_NE(-1, ptrace(PTRACE_SETOPTIONS, pid, NULL, | 2085 BPF_ASSERT_NE(-1, |
2141 reinterpret_cast<void*>(PTRACE_O_TRACESECCOMP))); | 2086 ptrace(PTRACE_SETOPTIONS, |
2087 pid, | |
2088 NULL, | |
2089 reinterpret_cast<void*>(PTRACE_O_TRACESECCOMP))); | |
2142 BPF_ASSERT_NE(-1, ptrace(PTRACE_CONT, pid, NULL, NULL)); | 2090 BPF_ASSERT_NE(-1, ptrace(PTRACE_CONT, pid, NULL, NULL)); |
2143 while (true) { | 2091 while (true) { |
2144 BPF_ASSERT(HANDLE_EINTR(waitpid(pid, &status, 0)) != -1); | 2092 BPF_ASSERT(HANDLE_EINTR(waitpid(pid, &status, 0)) != -1); |
2145 if (WIFEXITED(status) || WIFSIGNALED(status)) { | 2093 if (WIFEXITED(status) || WIFSIGNALED(status)) { |
2146 BPF_ASSERT(WIFEXITED(status)); | 2094 BPF_ASSERT(WIFEXITED(status)); |
2147 BPF_ASSERT_EQ(kExpectedReturnValue, WEXITSTATUS(status)); | 2095 BPF_ASSERT_EQ(kExpectedReturnValue, WEXITSTATUS(status)); |
2148 break; | 2096 break; |
2149 } | 2097 } |
2150 | 2098 |
2151 if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGTRAP || | 2099 if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGTRAP || |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2212 } | 2160 } |
2213 count -= transfered; | 2161 count -= transfered; |
2214 buffer += transfered; | 2162 buffer += transfered; |
2215 offset += transfered; | 2163 offset += transfered; |
2216 } | 2164 } |
2217 return true; | 2165 return true; |
2218 } | 2166 } |
2219 | 2167 |
2220 bool pread_64_was_forwarded = false; | 2168 bool pread_64_was_forwarded = false; |
2221 | 2169 |
2222 class TrapPread64Policy : public SandboxBPFPolicy { | 2170 class TrapPread64Policy : public SandboxBPFDSLPolicy { |
2223 public: | 2171 public: |
2224 TrapPread64Policy() {} | 2172 TrapPread64Policy() {} |
2225 virtual ~TrapPread64Policy() {} | 2173 virtual ~TrapPread64Policy() {} |
2226 | 2174 |
2227 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, | 2175 virtual ResultExpr EvaluateSyscall(int system_call_number) const OVERRIDE { |
2228 int system_call_number) const OVERRIDE { | |
2229 // Set the global environment for unsafe traps once. | 2176 // Set the global environment for unsafe traps once. |
2230 if (system_call_number == MIN_SYSCALL) { | 2177 if (system_call_number == MIN_SYSCALL) { |
2231 EnableUnsafeTraps(); | 2178 EnableUnsafeTraps(); |
2232 } | 2179 } |
2233 | 2180 |
2234 if (system_call_number == __NR_pread64) { | 2181 if (system_call_number == __NR_pread64) { |
2235 return sandbox_compiler->UnsafeTrap(ForwardPreadHandler, NULL); | 2182 return UnsafeTrap(ForwardPreadHandler, NULL); |
2236 } | 2183 } |
2237 return ErrorCode(ErrorCode::ERR_ALLOWED); | 2184 return Allow(); |
2238 } | 2185 } |
2239 | 2186 |
2240 private: | 2187 private: |
2241 static intptr_t ForwardPreadHandler(const struct arch_seccomp_data& args, | 2188 static intptr_t ForwardPreadHandler(const struct arch_seccomp_data& args, |
2242 void* aux) { | 2189 void* aux) { |
2243 BPF_ASSERT(args.nr == __NR_pread64); | 2190 BPF_ASSERT(args.nr == __NR_pread64); |
2244 pread_64_was_forwarded = true; | 2191 pread_64_was_forwarded = true; |
2245 | 2192 |
2246 return SandboxBPF::ForwardSyscall(args); | 2193 return SandboxBPF::ForwardSyscall(args); |
2247 } | 2194 } |
2195 | |
2248 DISALLOW_COPY_AND_ASSIGN(TrapPread64Policy); | 2196 DISALLOW_COPY_AND_ASSIGN(TrapPread64Policy); |
2249 }; | 2197 }; |
2250 | 2198 |
2251 // pread(2) takes a 64 bits offset. On 32 bits systems, it will be split | 2199 // pread(2) takes a 64 bits offset. On 32 bits systems, it will be split |
2252 // between two arguments. In this test, we make sure that ForwardSyscall() can | 2200 // between two arguments. In this test, we make sure that ForwardSyscall() can |
2253 // forward it properly. | 2201 // forward it properly. |
2254 BPF_TEST_C(SandboxBPF, Pread64, TrapPread64Policy) { | 2202 BPF_TEST_C(SandboxBPF, Pread64, TrapPread64Policy) { |
2255 ScopedTemporaryFile temp_file; | 2203 ScopedTemporaryFile temp_file; |
2256 const uint64_t kLargeOffset = (static_cast<uint64_t>(1) << 32) | 0xBEEF; | 2204 const uint64_t kLargeOffset = (static_cast<uint64_t>(1) << 32) | 0xBEEF; |
2257 const char kTestString[] = "This is a test!"; | 2205 const char kTestString[] = "This is a test!"; |
(...skipping 21 matching lines...) Expand all Loading... | |
2279 | 2227 |
2280 BPF_ASSERT(event->IsSignaled()); | 2228 BPF_ASSERT(event->IsSignaled()); |
2281 | 2229 |
2282 BlacklistNanosleepPolicy::AssertNanosleepFails(); | 2230 BlacklistNanosleepPolicy::AssertNanosleepFails(); |
2283 | 2231 |
2284 return NULL; | 2232 return NULL; |
2285 } | 2233 } |
2286 | 2234 |
2287 SANDBOX_TEST(SandboxBPF, Tsync) { | 2235 SANDBOX_TEST(SandboxBPF, Tsync) { |
2288 if (SandboxBPF::SupportsSeccompThreadFilterSynchronization() != | 2236 if (SandboxBPF::SupportsSeccompThreadFilterSynchronization() != |
2289 SandboxBPF::STATUS_AVAILABLE) { | 2237 SandboxBPF::STATUS_AVAILABLE) { |
2290 return; | 2238 return; |
2291 } | 2239 } |
2292 | 2240 |
2293 base::WaitableEvent event(true, false); | 2241 base::WaitableEvent event(true, false); |
2294 | 2242 |
2295 // Create a thread on which to invoke the blocked syscall. | 2243 // Create a thread on which to invoke the blocked syscall. |
2296 pthread_t thread; | 2244 pthread_t thread; |
2297 BPF_ASSERT_EQ(0, | 2245 BPF_ASSERT_EQ( |
2298 pthread_create(&thread, NULL, &TsyncApplyToTwoThreadsFunc, &event)); | 2246 0, pthread_create(&thread, NULL, &TsyncApplyToTwoThreadsFunc, &event)); |
2299 | 2247 |
2300 // Test that nanoseelp success. | 2248 // Test that nanoseelp success. |
2301 const struct timespec ts = {0, 0}; | 2249 const struct timespec ts = {0, 0}; |
2302 BPF_ASSERT_EQ(0, HANDLE_EINTR(syscall(__NR_nanosleep, &ts, NULL))); | 2250 BPF_ASSERT_EQ(0, HANDLE_EINTR(syscall(__NR_nanosleep, &ts, NULL))); |
2303 | 2251 |
2304 // Engage the sandbox. | 2252 // Engage the sandbox. |
2305 SandboxBPF sandbox; | 2253 SandboxBPF sandbox; |
2306 sandbox.SetSandboxPolicy(new BlacklistNanosleepPolicy()); | 2254 sandbox.SetSandboxPolicy(new BlacklistNanosleepPolicy()); |
2307 BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::PROCESS_MULTI_THREADED)); | 2255 BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::PROCESS_MULTI_THREADED)); |
2308 | 2256 |
2309 // This thread should have the filter applied as well. | 2257 // This thread should have the filter applied as well. |
2310 BlacklistNanosleepPolicy::AssertNanosleepFails(); | 2258 BlacklistNanosleepPolicy::AssertNanosleepFails(); |
2311 | 2259 |
2312 // Signal the condition to invoke the system call. | 2260 // Signal the condition to invoke the system call. |
2313 event.Signal(); | 2261 event.Signal(); |
2314 | 2262 |
2315 // Wait for the thread to finish. | 2263 // Wait for the thread to finish. |
2316 BPF_ASSERT_EQ(0, pthread_join(thread, NULL)); | 2264 BPF_ASSERT_EQ(0, pthread_join(thread, NULL)); |
2317 } | 2265 } |
2318 | 2266 |
2319 class AllowAllPolicy : public SandboxBPFPolicy { | 2267 class AllowAllPolicy : public SandboxBPFDSLPolicy { |
2320 public: | 2268 public: |
2321 AllowAllPolicy() : SandboxBPFPolicy() {} | 2269 AllowAllPolicy() {} |
2322 virtual ~AllowAllPolicy() {} | 2270 virtual ~AllowAllPolicy() {} |
2323 | 2271 |
2324 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, | 2272 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE { |
2325 int sysno) const OVERRIDE { | 2273 return Allow(); |
2326 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
2327 } | 2274 } |
2328 | 2275 |
2329 private: | 2276 private: |
2330 DISALLOW_COPY_AND_ASSIGN(AllowAllPolicy); | 2277 DISALLOW_COPY_AND_ASSIGN(AllowAllPolicy); |
2331 }; | 2278 }; |
2332 | 2279 |
2333 SANDBOX_DEATH_TEST(SandboxBPF, StartMultiThreadedAsSingleThreaded, | 2280 SANDBOX_DEATH_TEST( |
2281 SandboxBPF, | |
2282 StartMultiThreadedAsSingleThreaded, | |
2334 DEATH_MESSAGE("Cannot start sandbox; process is already multi-threaded")) { | 2283 DEATH_MESSAGE("Cannot start sandbox; process is already multi-threaded")) { |
2335 base::Thread thread("sandbox.linux.StartMultiThreadedAsSingleThreaded"); | 2284 base::Thread thread("sandbox.linux.StartMultiThreadedAsSingleThreaded"); |
2336 BPF_ASSERT(thread.Start()); | 2285 BPF_ASSERT(thread.Start()); |
2337 | 2286 |
2338 SandboxBPF sandbox; | 2287 SandboxBPF sandbox; |
2339 sandbox.SetSandboxPolicy(new AllowAllPolicy()); | 2288 sandbox.SetSandboxPolicy(new AllowAllPolicy()); |
2340 BPF_ASSERT(!sandbox.StartSandbox(SandboxBPF::PROCESS_SINGLE_THREADED)); | 2289 BPF_ASSERT(!sandbox.StartSandbox(SandboxBPF::PROCESS_SINGLE_THREADED)); |
2341 } | 2290 } |
2342 | 2291 |
2343 // http://crbug.com/407357 | 2292 // http://crbug.com/407357 |
2344 #if !defined(THREAD_SANITIZER) | 2293 #if !defined(THREAD_SANITIZER) |
2345 SANDBOX_DEATH_TEST(SandboxBPF, StartSingleThreadedAsMultiThreaded, | 2294 SANDBOX_DEATH_TEST( |
2346 DEATH_MESSAGE("Cannot start sandbox; process may be single-threaded when " | 2295 SandboxBPF, |
2347 "reported as not")) { | 2296 StartSingleThreadedAsMultiThreaded, |
2297 DEATH_MESSAGE( | |
2298 "Cannot start sandbox; process may be single-threaded when " | |
2299 "reported as not")) { | |
2348 SandboxBPF sandbox; | 2300 SandboxBPF sandbox; |
2349 sandbox.SetSandboxPolicy(new AllowAllPolicy()); | 2301 sandbox.SetSandboxPolicy(new AllowAllPolicy()); |
2350 BPF_ASSERT(!sandbox.StartSandbox(SandboxBPF::PROCESS_MULTI_THREADED)); | 2302 BPF_ASSERT(!sandbox.StartSandbox(SandboxBPF::PROCESS_MULTI_THREADED)); |
2351 } | 2303 } |
2352 #endif // !defined(THREAD_SANITIZER) | 2304 #endif // !defined(THREAD_SANITIZER) |
2353 | 2305 |
2354 // A stub handler for the UnsafeTrap. Never called. | 2306 // A stub handler for the UnsafeTrap. Never called. |
2355 intptr_t NoOpHandler(const struct arch_seccomp_data& args, void*) { | 2307 intptr_t NoOpHandler(const struct arch_seccomp_data& args, void*) { |
2356 return -1; | 2308 return -1; |
2357 } | 2309 } |
2358 | 2310 |
2359 class UnsafeTrapWithCondPolicy : public SandboxBPFPolicy { | 2311 class UnsafeTrapWithCondPolicy : public SandboxBPFDSLPolicy { |
2360 public: | 2312 public: |
2361 UnsafeTrapWithCondPolicy() {} | 2313 UnsafeTrapWithCondPolicy() {} |
2362 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, | 2314 virtual ~UnsafeTrapWithCondPolicy() {} |
2363 int sysno) const OVERRIDE { | 2315 |
2316 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE { | |
2364 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | 2317 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
2365 setenv(kSandboxDebuggingEnv, "t", 0); | 2318 setenv(kSandboxDebuggingEnv, "t", 0); |
2366 Die::SuppressInfoMessages(true); | 2319 Die::SuppressInfoMessages(true); |
2367 | 2320 |
2368 if (SandboxBPF::IsRequiredForUnsafeTrap(sysno)) | 2321 if (SandboxBPF::IsRequiredForUnsafeTrap(sysno)) |
2369 return ErrorCode(ErrorCode::ERR_ALLOWED); | 2322 return Allow(); |
2370 | 2323 |
2371 switch (sysno) { | 2324 switch (sysno) { |
2372 case __NR_uname: | 2325 case __NR_uname: { |
2373 return sandbox->Cond(0, | 2326 const Arg<uint32_t> arg(0); |
2374 ErrorCode::TP_32BIT, | 2327 return If(arg == 0, Allow()).Else(Error(EPERM)); |
2375 ErrorCode::OP_EQUAL, | 2328 } |
2376 0, | 2329 case __NR_setgid: { |
2377 ErrorCode(ErrorCode::ERR_ALLOWED), | 2330 const Arg<uint32_t> arg(0); |
2378 ErrorCode(EPERM)); | 2331 return Switch(arg) |
2379 case __NR_setgid: | 2332 .Case(100, Error(ENOMEM)) |
2380 return sandbox->Cond(0, | 2333 .Case(200, Error(ENOSYS)) |
2381 ErrorCode::TP_32BIT, | 2334 .Default(Error(EPERM)); |
2382 ErrorCode::OP_EQUAL, | 2335 } |
2383 100, | |
2384 ErrorCode(ErrorCode(ENOMEM)), | |
2385 sandbox->Cond(0, | |
2386 ErrorCode::TP_32BIT, | |
2387 ErrorCode::OP_EQUAL, | |
2388 200, | |
2389 ErrorCode(ENOSYS), | |
2390 ErrorCode(EPERM))); | |
2391 case __NR_close: | 2336 case __NR_close: |
2392 case __NR_exit_group: | 2337 case __NR_exit_group: |
2393 case __NR_write: | 2338 case __NR_write: |
2394 return ErrorCode(ErrorCode::ERR_ALLOWED); | 2339 return Allow(); |
2395 case __NR_getppid: | 2340 case __NR_getppid: |
2396 return sandbox->UnsafeTrap(NoOpHandler, NULL); | 2341 return UnsafeTrap(NoOpHandler, NULL); |
2397 default: | 2342 default: |
2398 return ErrorCode(EPERM); | 2343 return Error(EPERM); |
2399 } | 2344 } |
2400 } | 2345 } |
2401 | 2346 |
2402 private: | 2347 private: |
2403 DISALLOW_COPY_AND_ASSIGN(UnsafeTrapWithCondPolicy); | 2348 DISALLOW_COPY_AND_ASSIGN(UnsafeTrapWithCondPolicy); |
2404 }; | 2349 }; |
2405 | 2350 |
2406 BPF_TEST_C(SandboxBPF, UnsafeTrapWithCond, UnsafeTrapWithCondPolicy) { | 2351 BPF_TEST_C(SandboxBPF, UnsafeTrapWithCond, UnsafeTrapWithCondPolicy) { |
2407 BPF_ASSERT_EQ(-1, syscall(__NR_uname, 0)); | 2352 BPF_ASSERT_EQ(-1, syscall(__NR_uname, 0)); |
2408 BPF_ASSERT_EQ(EFAULT, errno); | 2353 BPF_ASSERT_EQ(EFAULT, errno); |
2409 | 2354 |
2410 BPF_ASSERT_EQ(-1, syscall(__NR_uname, 1)); | 2355 BPF_ASSERT_EQ(-1, syscall(__NR_uname, 1)); |
2411 BPF_ASSERT_EQ(EPERM, errno); | 2356 BPF_ASSERT_EQ(EPERM, errno); |
2412 | 2357 |
2413 BPF_ASSERT_EQ(-1, syscall(__NR_setgid, 100)); | 2358 BPF_ASSERT_EQ(-1, syscall(__NR_setgid, 100)); |
2414 BPF_ASSERT_EQ(ENOMEM, errno); | 2359 BPF_ASSERT_EQ(ENOMEM, errno); |
2415 | 2360 |
2416 BPF_ASSERT_EQ(-1, syscall(__NR_setgid, 200)); | 2361 BPF_ASSERT_EQ(-1, syscall(__NR_setgid, 200)); |
2417 BPF_ASSERT_EQ(ENOSYS, errno); | 2362 BPF_ASSERT_EQ(ENOSYS, errno); |
2418 | 2363 |
2419 BPF_ASSERT_EQ(-1, syscall(__NR_setgid, 300)); | 2364 BPF_ASSERT_EQ(-1, syscall(__NR_setgid, 300)); |
2420 BPF_ASSERT_EQ(EPERM, errno); | 2365 BPF_ASSERT_EQ(EPERM, errno); |
2421 } | 2366 } |
2422 | 2367 |
2423 } // namespace | 2368 } // namespace |
2424 | 2369 |
2370 } // namespace bpf_dsl | |
2425 } // namespace sandbox | 2371 } // namespace sandbox |
OLD | NEW |