Chromium Code Reviews| 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 <asm/unistd.h> | 5 #include <asm/unistd.h> |
| 6 #include <dlfcn.h> | 6 #include <dlfcn.h> |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <fcntl.h> | 8 #include <fcntl.h> |
| 9 #include <linux/audit.h> | 9 #include <linux/audit.h> |
| 10 #include <linux/filter.h> | 10 #include <linux/filter.h> |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 93 int syscall = args.nr; | 93 int syscall = args.nr; |
| 94 if (syscall >= 1024) | 94 if (syscall >= 1024) |
| 95 syscall = 0; | 95 syscall = 0; |
| 96 // Encode 8-bits of the 1st two arguments too, so we can discern which socket | 96 // Encode 8-bits of the 1st two arguments too, so we can discern which socket |
| 97 // type, which fcntl, ... etc., without being likely to hit a mapped | 97 // type, which fcntl, ... etc., without being likely to hit a mapped |
| 98 // address. | 98 // address. |
| 99 // Do not encode more bits here without thinking about increasing the | 99 // Do not encode more bits here without thinking about increasing the |
| 100 // likelihood of collision with mapped pages. | 100 // likelihood of collision with mapped pages. |
| 101 syscall |= ((args.args[0] & 0xffUL) << 12); | 101 syscall |= ((args.args[0] & 0xffUL) << 12); |
| 102 syscall |= ((args.args[1] & 0xffUL) << 20); | 102 syscall |= ((args.args[1] & 0xffUL) << 20); |
| 103 syscall = args.args[3] & 0xffffffffUL; | |
| 103 // Purposefully dereference the syscall as an address so it'll show up very | 104 // Purposefully dereference the syscall as an address so it'll show up very |
| 104 // clearly and easily in crash dumps. | 105 // clearly and easily in crash dumps. |
| 105 volatile char* addr = reinterpret_cast<volatile char*>(syscall); | 106 volatile char* addr = reinterpret_cast<volatile char*>(syscall); |
| 106 *addr = '\0'; | 107 *addr = '\0'; |
| 107 // In case we hit a mapped address, hit the null page with just the syscall, | 108 // In case we hit a mapped address, hit the null page with just the syscall, |
| 108 // for paranoia. | 109 // for paranoia. |
| 109 syscall &= 0xfffUL; | 110 syscall &= 0xfffUL; |
| 110 addr = reinterpret_cast<volatile char*>(syscall); | 111 addr = reinterpret_cast<volatile char*>(syscall); |
| 111 *addr = '\0'; | 112 *addr = '\0'; |
| 112 for (;;) | 113 for (;;) |
| (...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 651 default: | 652 default: |
| 652 return false; | 653 return false; |
| 653 } | 654 } |
| 654 } | 655 } |
| 655 #endif | 656 #endif |
| 656 | 657 |
| 657 bool IsAllowedAddressSpaceAccess(int sysno) { | 658 bool IsAllowedAddressSpaceAccess(int sysno) { |
| 658 switch (sysno) { | 659 switch (sysno) { |
| 659 case __NR_brk: | 660 case __NR_brk: |
| 660 case __NR_mlock: | 661 case __NR_mlock: |
| 662 case __NR_mprotect: | |
| 663 case __NR_munlock: | |
| 664 case __NR_munmap: | |
| 665 return true; | |
| 661 #if defined(__i386__) || defined(__x86_64__) | 666 #if defined(__i386__) || defined(__x86_64__) |
| 662 case __NR_mmap: // TODO(jln): to restrict flags. | 667 case __NR_mmap: |
|
jln (very slow on Chromium)
2013/05/15 20:01:05
Nit: if we keep it this way, let's move mmap and m
| |
| 663 #endif | 668 #endif |
| 664 #if defined(__i386__) || defined(__arm__) | 669 #if defined(__i386__) || defined(__arm__) |
| 665 case __NR_mmap2: | 670 case __NR_mmap2: |
| 666 #endif | 671 #endif |
| 667 case __NR_mprotect: | |
| 668 case __NR_munlock: | |
| 669 case __NR_munmap: | |
| 670 return true; | |
| 671 case __NR_madvise: | 672 case __NR_madvise: |
| 672 case __NR_mincore: | 673 case __NR_mincore: |
| 673 case __NR_mlockall: | 674 case __NR_mlockall: |
| 674 #if defined(__i386__) || defined(__x86_64__) | 675 #if defined(__i386__) || defined(__x86_64__) |
| 675 case __NR_modify_ldt: | 676 case __NR_modify_ldt: |
| 676 #endif | 677 #endif |
| 677 case __NR_mremap: | 678 case __NR_mremap: |
| 678 case __NR_msync: | 679 case __NR_msync: |
| 679 case __NR_munlockall: | 680 case __NR_munlockall: |
| 680 case __NR_readahead: | 681 case __NR_readahead: |
| (...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1229 #if defined(__arm__) | 1230 #if defined(__arm__) |
| 1230 IsArmPciConfig(sysno) || | 1231 IsArmPciConfig(sysno) || |
| 1231 #endif | 1232 #endif |
| 1232 IsTimer(sysno)) { | 1233 IsTimer(sysno)) { |
| 1233 return true; | 1234 return true; |
| 1234 } else { | 1235 } else { |
| 1235 return false; | 1236 return false; |
| 1236 } | 1237 } |
| 1237 } | 1238 } |
| 1238 | 1239 |
| 1240 ErrorCode RestrictMmapFlags(Sandbox *sandbox) { | |
| 1241 // These flags are allowed. Significantly, we don't permit MAP_HUGETLB, or | |
| 1242 // the newer flags such as MAP_POPULATE. | |
| 1243 uint32_t mask = ~(MAP_SHARED | MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK | | |
|
jln (very slow on Chromium)
2013/05/15 20:01:05
want to rename that variable denied_mask to make t
| |
| 1244 MAP_NORESERVE | MAP_FIXED); | |
| 1245 return sandbox->Cond(3, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, | |
|
jln (very slow on Chromium)
2013/05/15 20:01:05
Nit:
I guess we should have provided a OP_HAS_NO_
| |
| 1246 mask, sandbox->Trap(CrashSIGSYS_Handler, NULL), | |
| 1247 ErrorCode(ErrorCode::ERR_ALLOWED)); | |
| 1248 } | |
| 1249 | |
| 1239 ErrorCode BaselinePolicy(Sandbox *sandbox, int sysno) { | 1250 ErrorCode BaselinePolicy(Sandbox *sandbox, int sysno) { |
| 1240 #if defined(__x86_64__) || defined(__arm__) | 1251 #if defined(__x86_64__) || defined(__arm__) |
| 1241 if (sysno == __NR_socketpair) { | 1252 if (sysno == __NR_socketpair) { |
| 1242 // Only allow AF_UNIX, PF_UNIX. Crash if anything else is seen. | 1253 // Only allow AF_UNIX, PF_UNIX. Crash if anything else is seen. |
| 1243 COMPILE_ASSERT(AF_UNIX == PF_UNIX, af_unix_pf_unix_different); | 1254 COMPILE_ASSERT(AF_UNIX == PF_UNIX, af_unix_pf_unix_different); |
| 1244 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, AF_UNIX, | 1255 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, AF_UNIX, |
| 1245 ErrorCode(ErrorCode::ERR_ALLOWED), | 1256 ErrorCode(ErrorCode::ERR_ALLOWED), |
| 1246 sandbox->Trap(CrashSIGSYS_Handler, NULL)); | 1257 sandbox->Trap(CrashSIGSYS_Handler, NULL)); |
| 1247 } | 1258 } |
| 1248 #endif | 1259 #endif |
| 1249 if (sysno == __NR_madvise) { | 1260 switch (sysno) { |
|
jln (very slow on Chromium)
2013/05/15 20:01:05
If you want to make this a switch, make sure you s
| |
| 1261 case __NR_madvise: | |
| 1250 // Only allow MADV_DONTNEED (aka MADV_FREE). | 1262 // Only allow MADV_DONTNEED (aka MADV_FREE). |
| 1251 return sandbox->Cond(2, ErrorCode::TP_32BIT, | 1263 return sandbox->Cond(2, ErrorCode::TP_32BIT, |
| 1252 ErrorCode::OP_EQUAL, MADV_DONTNEED, | 1264 ErrorCode::OP_EQUAL, MADV_DONTNEED, |
| 1253 ErrorCode(ErrorCode::ERR_ALLOWED), | 1265 ErrorCode(ErrorCode::ERR_ALLOWED), |
| 1254 ErrorCode(EPERM)); | 1266 ErrorCode(EPERM)); |
| 1267 #if defined(__x86_64__) | |
| 1268 case __NR_mmap: | |
| 1269 return RestrictMmapFlags(sandbox); | |
| 1270 #elif defined(__i386__) | |
| 1271 case __NR_mmap: | |
| 1272 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
| 1273 #endif | |
| 1274 #if defined(__i386__) || defined(__arm__) | |
| 1275 case __NR_mmap2: | |
| 1276 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
| 1277 #endif | |
| 1255 } | 1278 } |
| 1256 | 1279 |
| 1257 if (IsBaselinePolicyAllowed(sysno)) { | 1280 if (IsBaselinePolicyAllowed(sysno)) { |
|
jln (DO NOT USE THIS)
2013/05/15 20:10:14
Another remark:
The goal of putting things *above
| |
| 1258 return ErrorCode(ErrorCode::ERR_ALLOWED); | 1281 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1259 } | 1282 } |
| 1260 | 1283 |
| 1261 #if defined(__i386__) | 1284 #if defined(__i386__) |
| 1262 // socketcall(2) should be tightened. | 1285 // socketcall(2) should be tightened. |
| 1263 if (IsSocketCall(sysno)) { | 1286 if (IsSocketCall(sysno)) { |
| 1264 return ErrorCode(ErrorCode::ERR_ALLOWED); | 1287 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1265 } | 1288 } |
| 1266 #endif | 1289 #endif |
| 1267 | 1290 |
| (...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1754 // should enable it, enable it or die. | 1777 // should enable it, enable it or die. |
| 1755 bool started_sandbox = StartBpfSandbox(command_line, process_type); | 1778 bool started_sandbox = StartBpfSandbox(command_line, process_type); |
| 1756 CHECK(started_sandbox); | 1779 CHECK(started_sandbox); |
| 1757 return true; | 1780 return true; |
| 1758 } | 1781 } |
| 1759 #endif | 1782 #endif |
| 1760 return false; | 1783 return false; |
| 1761 } | 1784 } |
| 1762 | 1785 |
| 1763 } // namespace content | 1786 } // namespace content |
| OLD | NEW |