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

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

Issue 330723003: Clean-up the SandboxSyscall interface (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments. Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « sandbox/linux/seccomp-bpf/sandbox_bpf.cc ('k') | sandbox/linux/seccomp-bpf/syscall.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <errno.h> 5 #include <errno.h>
6 #include <pthread.h> 6 #include <pthread.h>
7 #include <sched.h> 7 #include <sched.h>
8 #include <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 1186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1197 // Reset args[arg_value.argno]. This is not technically needed, but it 1197 // Reset args[arg_value.argno]. This is not technically needed, but it
1198 // makes it easier to reason about the correctness of our tests. 1198 // makes it easier to reason about the correctness of our tests.
1199 args[arg_value.argno] = 0; 1199 args[arg_value.argno] = 0;
1200 } 1200 }
1201 1201
1202 void VerifyErrno(int sysno, intptr_t* args, int err) { 1202 void VerifyErrno(int sysno, intptr_t* args, int err) {
1203 // We installed BPF filters that return different errno values 1203 // We installed BPF filters that return different errno values
1204 // based on the system call number and the parameters that we decided 1204 // based on the system call number and the parameters that we decided
1205 // to pass in. Verify that this condition holds true. 1205 // to pass in. Verify that this condition holds true.
1206 BPF_ASSERT( 1206 BPF_ASSERT(
1207 SandboxSyscall( 1207 Syscall::Call(
1208 sysno, args[0], args[1], args[2], args[3], args[4], args[5]) == 1208 sysno, args[0], args[1], args[2], args[3], args[4], args[5]) ==
1209 -err); 1209 -err);
1210 } 1210 }
1211 1211
1212 // Vector of ArgValue trees. These trees define all the possible boolean 1212 // Vector of ArgValue trees. These trees define all the possible boolean
1213 // expressions that we want to turn into a BPF filter program. 1213 // expressions that we want to turn into a BPF filter program.
1214 std::vector<ArgValue*> arg_values_; 1214 std::vector<ArgValue*> arg_values_;
1215 1215
1216 // Don't increase these values. We are pushing the limits of the maximum 1216 // Don't increase these values. We are pushing the limits of the maximum
1217 // BPF program that the kernel will allow us to load. If the values are 1217 // BPF program that the kernel will allow us to load. If the values are
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1272 ErrorCode::TP_64BIT, 1272 ErrorCode::TP_64BIT,
1273 ErrorCode::OP_EQUAL, 1273 ErrorCode::OP_EQUAL,
1274 0x55555555AAAAAAAAULL, 1274 0x55555555AAAAAAAAULL,
1275 ErrorCode(1), 1275 ErrorCode(1),
1276 ErrorCode(2))); 1276 ErrorCode(2)));
1277 } 1277 }
1278 return ErrorCode(ErrorCode::ERR_ALLOWED); 1278 return ErrorCode(ErrorCode::ERR_ALLOWED);
1279 } 1279 }
1280 1280
1281 BPF_TEST_C(SandboxBPF, EqualityArgumentWidth, EqualityArgumentWidthPolicy) { 1281 BPF_TEST_C(SandboxBPF, EqualityArgumentWidth, EqualityArgumentWidthPolicy) {
1282 BPF_ASSERT(SandboxSyscall(__NR_uname, 0, 0x55555555) == -1); 1282 BPF_ASSERT(Syscall::Call(__NR_uname, 0, 0x55555555) == -1);
1283 BPF_ASSERT(SandboxSyscall(__NR_uname, 0, 0xAAAAAAAA) == -2); 1283 BPF_ASSERT(Syscall::Call(__NR_uname, 0, 0xAAAAAAAA) == -2);
1284 #if __SIZEOF_POINTER__ > 4 1284 #if __SIZEOF_POINTER__ > 4
1285 // On 32bit machines, there is no way to pass a 64bit argument through the 1285 // On 32bit machines, there is no way to pass a 64bit argument through the
1286 // syscall interface. So, we have to skip the part of the test that requires 1286 // syscall interface. So, we have to skip the part of the test that requires
1287 // 64bit arguments. 1287 // 64bit arguments.
1288 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x55555555AAAAAAAAULL) == -1); 1288 BPF_ASSERT(Syscall::Call(__NR_uname, 1, 0x55555555AAAAAAAAULL) == -1);
1289 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x5555555500000000ULL) == -2); 1289 BPF_ASSERT(Syscall::Call(__NR_uname, 1, 0x5555555500000000ULL) == -2);
1290 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x5555555511111111ULL) == -2); 1290 BPF_ASSERT(Syscall::Call(__NR_uname, 1, 0x5555555511111111ULL) == -2);
1291 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x11111111AAAAAAAAULL) == -2); 1291 BPF_ASSERT(Syscall::Call(__NR_uname, 1, 0x11111111AAAAAAAAULL) == -2);
1292 #else 1292 #else
1293 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x55555555) == -2); 1293 BPF_ASSERT(Syscall::Call(__NR_uname, 1, 0x55555555) == -2);
1294 #endif 1294 #endif
1295 } 1295 }
1296 1296
1297 #if __SIZEOF_POINTER__ > 4 1297 #if __SIZEOF_POINTER__ > 4
1298 // On 32bit machines, there is no way to pass a 64bit argument through the 1298 // On 32bit machines, there is no way to pass a 64bit argument through the
1299 // syscall interface. So, we have to skip the part of the test that requires 1299 // syscall interface. So, we have to skip the part of the test that requires
1300 // 64bit arguments. 1300 // 64bit arguments.
1301 BPF_DEATH_TEST_C(SandboxBPF, 1301 BPF_DEATH_TEST_C(SandboxBPF,
1302 EqualityArgumentUnallowed64bit, 1302 EqualityArgumentUnallowed64bit,
1303 DEATH_MESSAGE("Unexpected 64bit argument detected"), 1303 DEATH_MESSAGE("Unexpected 64bit argument detected"),
1304 EqualityArgumentWidthPolicy) { 1304 EqualityArgumentWidthPolicy) {
1305 SandboxSyscall(__NR_uname, 0, 0x5555555555555555ULL); 1305 Syscall::Call(__NR_uname, 0, 0x5555555555555555ULL);
1306 } 1306 }
1307 #endif 1307 #endif
1308 1308
1309 class EqualityWithNegativeArgumentsPolicy : public SandboxBPFPolicy { 1309 class EqualityWithNegativeArgumentsPolicy : public SandboxBPFPolicy {
1310 public: 1310 public:
1311 EqualityWithNegativeArgumentsPolicy() {} 1311 EqualityWithNegativeArgumentsPolicy() {}
1312 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, 1312 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox,
1313 int sysno) const OVERRIDE { 1313 int sysno) const OVERRIDE {
1314 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); 1314 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno));
1315 if (sysno == __NR_uname) { 1315 if (sysno == __NR_uname) {
1316 return sandbox->Cond(0, 1316 return sandbox->Cond(0,
1317 ErrorCode::TP_32BIT, 1317 ErrorCode::TP_32BIT,
1318 ErrorCode::OP_EQUAL, 1318 ErrorCode::OP_EQUAL,
1319 0xFFFFFFFF, 1319 0xFFFFFFFF,
1320 ErrorCode(1), 1320 ErrorCode(1),
1321 ErrorCode(2)); 1321 ErrorCode(2));
1322 } 1322 }
1323 return ErrorCode(ErrorCode::ERR_ALLOWED); 1323 return ErrorCode(ErrorCode::ERR_ALLOWED);
1324 } 1324 }
1325 1325
1326 private: 1326 private:
1327 DISALLOW_COPY_AND_ASSIGN(EqualityWithNegativeArgumentsPolicy); 1327 DISALLOW_COPY_AND_ASSIGN(EqualityWithNegativeArgumentsPolicy);
1328 }; 1328 };
1329 1329
1330 BPF_TEST_C(SandboxBPF, 1330 BPF_TEST_C(SandboxBPF,
1331 EqualityWithNegativeArguments, 1331 EqualityWithNegativeArguments,
1332 EqualityWithNegativeArgumentsPolicy) { 1332 EqualityWithNegativeArgumentsPolicy) {
1333 BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF) == -1); 1333 BPF_ASSERT(Syscall::Call(__NR_uname, 0xFFFFFFFF) == -1);
1334 BPF_ASSERT(SandboxSyscall(__NR_uname, -1) == -1); 1334 BPF_ASSERT(Syscall::Call(__NR_uname, -1) == -1);
1335 BPF_ASSERT(SandboxSyscall(__NR_uname, -1LL) == -1); 1335 BPF_ASSERT(Syscall::Call(__NR_uname, -1LL) == -1);
1336 } 1336 }
1337 1337
1338 #if __SIZEOF_POINTER__ > 4 1338 #if __SIZEOF_POINTER__ > 4
1339 BPF_DEATH_TEST_C(SandboxBPF, 1339 BPF_DEATH_TEST_C(SandboxBPF,
1340 EqualityWithNegative64bitArguments, 1340 EqualityWithNegative64bitArguments,
1341 DEATH_MESSAGE("Unexpected 64bit argument detected"), 1341 DEATH_MESSAGE("Unexpected 64bit argument detected"),
1342 EqualityWithNegativeArgumentsPolicy) { 1342 EqualityWithNegativeArgumentsPolicy) {
1343 // When expecting a 32bit system call argument, we look at the MSB of the 1343 // When expecting a 32bit system call argument, we look at the MSB of the
1344 // 64bit value and allow both "0" and "-1". But the latter is allowed only 1344 // 64bit value and allow both "0" and "-1". But the latter is allowed only
1345 // iff the LSB was negative. So, this death test should error out. 1345 // iff the LSB was negative. So, this death test should error out.
1346 BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF00000000LL) == -1); 1346 BPF_ASSERT(Syscall::Call(__NR_uname, 0xFFFFFFFF00000000LL) == -1);
1347 } 1347 }
1348 #endif 1348 #endif
1349 class AllBitTestPolicy : public SandboxBPFPolicy { 1349 class AllBitTestPolicy : public SandboxBPFPolicy {
1350 public: 1350 public:
1351 AllBitTestPolicy() {} 1351 AllBitTestPolicy() {}
1352 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, 1352 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox,
1353 int sysno) const OVERRIDE; 1353 int sysno) const OVERRIDE;
1354 1354
1355 private: 1355 private:
1356 DISALLOW_COPY_AND_ASSIGN(AllBitTestPolicy); 1356 DISALLOW_COPY_AND_ASSIGN(AllBitTestPolicy);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1426 } 1426 }
1427 1427
1428 // Define a macro that performs tests using our test policy. 1428 // Define a macro that performs tests using our test policy.
1429 // NOTE: Not all of the arguments in this macro are actually used! 1429 // NOTE: Not all of the arguments in this macro are actually used!
1430 // They are here just to serve as documentation of the conditions 1430 // They are here just to serve as documentation of the conditions
1431 // implemented in the test policy. 1431 // implemented in the test policy.
1432 // Most notably, "op" and "mask" are unused by the macro. If you want 1432 // Most notably, "op" and "mask" are unused by the macro. If you want
1433 // to make changes to these values, you will have to edit the 1433 // to make changes to these values, you will have to edit the
1434 // test policy instead. 1434 // test policy instead.
1435 #define BITMASK_TEST(testcase, arg, op, mask, expected_value) \ 1435 #define BITMASK_TEST(testcase, arg, op, mask, expected_value) \
1436 BPF_ASSERT(SandboxSyscall(__NR_uname, (testcase), (arg)) == (expected_value)) 1436 BPF_ASSERT(Syscall::Call(__NR_uname, (testcase), (arg)) == (expected_value))
1437 1437
1438 // Our uname() system call returns ErrorCode(1) for success and 1438 // Our uname() system call returns ErrorCode(1) for success and
1439 // ErrorCode(0) for failure. SandboxSyscall() turns this into an 1439 // ErrorCode(0) for failure. Syscall::Call() turns this into an
1440 // exit code of -1 or 0. 1440 // exit code of -1 or 0.
1441 #define EXPECT_FAILURE 0 1441 #define EXPECT_FAILURE 0
1442 #define EXPECT_SUCCESS -1 1442 #define EXPECT_SUCCESS -1
1443 1443
1444 // A couple of our tests behave differently on 32bit and 64bit systems, as 1444 // A couple of our tests behave differently on 32bit and 64bit systems, as
1445 // there is no way for a 32bit system call to pass in a 64bit system call 1445 // there is no way for a 32bit system call to pass in a 64bit system call
1446 // argument "arg". 1446 // argument "arg".
1447 // We expect these tests to succeed on 64bit systems, but to tail on 32bit 1447 // We expect these tests to succeed on 64bit systems, but to tail on 32bit
1448 // systems. 1448 // systems.
1449 #define EXPT64_SUCCESS (sizeof(void*) > 4 ? EXPECT_SUCCESS : EXPECT_FAILURE) 1449 #define EXPT64_SUCCESS (sizeof(void*) > 4 ? EXPECT_SUCCESS : EXPECT_FAILURE)
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
1859 ErrorCode(ErrorCode::ERR_ALLOWED))), 1859 ErrorCode(ErrorCode::ERR_ALLOWED))),
1860 sandbox->Trap(PthreadTrapHandler, 1860 sandbox->Trap(PthreadTrapHandler,
1861 "Missing mandatory CLONE_XXX flags " 1861 "Missing mandatory CLONE_XXX flags "
1862 "when creating new thread"))); 1862 "when creating new thread")));
1863 } 1863 }
1864 return ErrorCode(ErrorCode::ERR_ALLOWED); 1864 return ErrorCode(ErrorCode::ERR_ALLOWED);
1865 } 1865 }
1866 1866
1867 static void* ThreadFnc(void* arg) { 1867 static void* ThreadFnc(void* arg) {
1868 ++*reinterpret_cast<int*>(arg); 1868 ++*reinterpret_cast<int*>(arg);
1869 SandboxSyscall(__NR_futex, arg, FUTEX_WAKE, 1, 0, 0, 0); 1869 Syscall::Call(__NR_futex, arg, FUTEX_WAKE, 1, 0, 0, 0);
1870 return NULL; 1870 return NULL;
1871 } 1871 }
1872 1872
1873 static void PthreadTest() { 1873 static void PthreadTest() {
1874 // Attempt to start a joinable thread. This should succeed. 1874 // Attempt to start a joinable thread. This should succeed.
1875 pthread_t thread; 1875 pthread_t thread;
1876 int thread_ran = 0; 1876 int thread_ran = 0;
1877 BPF_ASSERT(!pthread_create(&thread, NULL, ThreadFnc, &thread_ran)); 1877 BPF_ASSERT(!pthread_create(&thread, NULL, ThreadFnc, &thread_ran));
1878 BPF_ASSERT(!pthread_join(thread, NULL)); 1878 BPF_ASSERT(!pthread_join(thread, NULL));
1879 BPF_ASSERT(thread_ran); 1879 BPF_ASSERT(thread_ran);
1880 1880
1881 // Attempt to start a detached thread. This should succeed. 1881 // Attempt to start a detached thread. This should succeed.
1882 thread_ran = 0; 1882 thread_ran = 0;
1883 pthread_attr_t attr; 1883 pthread_attr_t attr;
1884 BPF_ASSERT(!pthread_attr_init(&attr)); 1884 BPF_ASSERT(!pthread_attr_init(&attr));
1885 BPF_ASSERT(!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)); 1885 BPF_ASSERT(!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED));
1886 BPF_ASSERT(!pthread_create(&thread, &attr, ThreadFnc, &thread_ran)); 1886 BPF_ASSERT(!pthread_create(&thread, &attr, ThreadFnc, &thread_ran));
1887 BPF_ASSERT(!pthread_attr_destroy(&attr)); 1887 BPF_ASSERT(!pthread_attr_destroy(&attr));
1888 while (SandboxSyscall(__NR_futex, &thread_ran, FUTEX_WAIT, 0, 0, 0, 0) == 1888 while (Syscall::Call(__NR_futex, &thread_ran, FUTEX_WAIT, 0, 0, 0, 0) ==
1889 -EINTR) { 1889 -EINTR) {
1890 } 1890 }
1891 BPF_ASSERT(thread_ran); 1891 BPF_ASSERT(thread_ran);
1892 1892
1893 // Attempt to fork() a process using clone(). This should fail. We use the 1893 // Attempt to fork() a process using clone(). This should fail. We use the
1894 // same flags that glibc uses when calling fork(). But we don't actually 1894 // same flags that glibc uses when calling fork(). But we don't actually
1895 // try calling the fork() implementation in the C run-time library, as 1895 // try calling the fork() implementation in the C run-time library, as
1896 // run-time libraries other than glibc might call __NR_fork instead of 1896 // run-time libraries other than glibc might call __NR_fork instead of
1897 // __NR_clone, and that would introduce a bogus test failure. 1897 // __NR_clone, and that would introduce a bogus test failure.
1898 int pid; 1898 int pid;
1899 BPF_ASSERT(SandboxSyscall(__NR_clone, 1899 BPF_ASSERT(Syscall::Call(__NR_clone,
1900 CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | SIGCHLD, 1900 CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | SIGCHLD,
1901 0, 1901 0,
1902 0, 1902 0,
1903 &pid) == -EPERM); 1903 &pid) == -EPERM);
1904 } 1904 }
1905 1905
1906 BPF_TEST_C(SandboxBPF, PthreadEquality, PthreadPolicyEquality) { 1906 BPF_TEST_C(SandboxBPF, PthreadEquality, PthreadPolicyEquality) {
1907 PthreadTest(); 1907 PthreadTest();
1908 } 1908 }
1909 1909
1910 BPF_TEST_C(SandboxBPF, PthreadBitMask, PthreadPolicyBitMask) { 1910 BPF_TEST_C(SandboxBPF, PthreadBitMask, PthreadPolicyBitMask) {
1911 PthreadTest(); 1911 PthreadTest();
1912 } 1912 }
1913 1913
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
2023 break; 2023 break;
2024 } 2024 }
2025 2025
2026 BPF_ASSERT_NE(-1, ptrace(PTRACE_CONT, pid, NULL, NULL)); 2026 BPF_ASSERT_NE(-1, ptrace(PTRACE_CONT, pid, NULL, NULL));
2027 } 2027 }
2028 } 2028 }
2029 2029
2030 } // namespace 2030 } // namespace
2031 2031
2032 } // namespace sandbox 2032 } // namespace sandbox
OLDNEW
« no previous file with comments | « sandbox/linux/seccomp-bpf/sandbox_bpf.cc ('k') | sandbox/linux/seccomp-bpf/syscall.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698