diff options
author | cevans@chromium.org <cevans@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-20 04:07:07 +0000 |
---|---|---|
committer | cevans@chromium.org <cevans@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-20 04:07:07 +0000 |
commit | b58eb6e8e7eb0479c846ae7ef481c64d16fd9acc (patch) | |
tree | d8ae90d83359d885ad90e3b6af0adfd7a637f0ba | |
parent | c7a8fd34f1fcabf3f730fc38a46907068927ea22 (diff) | |
download | chromium_src-b58eb6e8e7eb0479c846ae7ef481c64d16fd9acc.zip chromium_src-b58eb6e8e7eb0479c846ae7ef481c64d16fd9acc.tar.gz chromium_src-b58eb6e8e7eb0479c846ae7ef481c64d16fd9acc.tar.bz2 |
Restrict mmap(2) and mprotect(2) flags for x64.
(Reland of https://codereview.chromium.org/15112008 and https://codereview.chromium.org/15104005)
BUG=241220
TBR=jln@google.com
Review URL: https://chromiumcodereview.appspot.com/15295016
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@201013 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | content/common/sandbox_seccomp_bpf_linux.cc | 80 |
1 files changed, 68 insertions, 12 deletions
diff --git a/content/common/sandbox_seccomp_bpf_linux.cc b/content/common/sandbox_seccomp_bpf_linux.cc index b66b328..df14633 100644 --- a/content/common/sandbox_seccomp_bpf_linux.cc +++ b/content/common/sandbox_seccomp_bpf_linux.cc @@ -670,13 +670,6 @@ bool IsAllowedAddressSpaceAccess(int sysno) { switch (sysno) { case __NR_brk: case __NR_mlock: -#if defined(__i386__) || defined(__x86_64__) - case __NR_mmap: // TODO(jln): to restrict flags. -#endif -#if defined(__i386__) || defined(__arm__) - case __NR_mmap2: -#endif - case __NR_mprotect: case __NR_munlock: case __NR_munmap: return true; @@ -684,8 +677,15 @@ bool IsAllowedAddressSpaceAccess(int sysno) { case __NR_mincore: case __NR_mlockall: #if defined(__i386__) || defined(__x86_64__) + case __NR_mmap: +#endif +#if defined(__i386__) || defined(__arm__) + case __NR_mmap2: +#endif +#if defined(__i386__) || defined(__x86_64__) case __NR_modify_ldt: #endif + case __NR_mprotect: case __NR_mremap: case __NR_msync: case __NR_munlockall: @@ -1248,7 +1248,43 @@ bool IsBaselinePolicyWatched(int sysno) { } } +ErrorCode RestrictMmapFlags(Sandbox *sandbox) { + // The flags you see are actually the allowed ones, and the variable is a + // "denied" mask because of the negation operator. + // Significantly, we don't permit MAP_HUGETLB, or the newer flags such as + // MAP_POPULATE. + uint32_t denied_mask = ~(MAP_SHARED | MAP_PRIVATE | MAP_ANONYMOUS | + MAP_STACK | MAP_NORESERVE | MAP_FIXED); + return sandbox->Cond(3, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, + denied_mask, + sandbox->Trap(CrashSIGSYS_Handler, NULL), + ErrorCode(ErrorCode::ERR_ALLOWED)); +} + +ErrorCode RestrictMprotectFlags(Sandbox *sandbox) { + // The flags you see are actually the allowed ones, and the variable is a + // "denied" mask because of the negation operator. + // Significantly, we don't permit weird undocumented flags such as + // PROT_GROWSDOWN. + uint32_t denied_mask = ~(PROT_READ | PROT_WRITE | PROT_EXEC); + return sandbox->Cond(2, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, + denied_mask, + sandbox->Trap(CrashSIGSYS_Handler, NULL), + ErrorCode(ErrorCode::ERR_ALLOWED)); +} + ErrorCode BaselinePolicy(Sandbox *sandbox, int sysno) { + if (IsBaselinePolicyAllowed(sysno)) { + return ErrorCode(ErrorCode::ERR_ALLOWED); + } + +#if defined(__i386__) + // socketcall(2) should be tightened. + if (IsSocketCall(sysno)) { + return ErrorCode(ErrorCode::ERR_ALLOWED); + } +#endif + #if defined(__x86_64__) || defined(__arm__) if (sysno == __NR_socketpair) { // Only allow AF_UNIX, PF_UNIX. Crash if anything else is seen. @@ -1258,6 +1294,7 @@ ErrorCode BaselinePolicy(Sandbox *sandbox, int sysno) { sandbox->Trap(CrashSIGSYS_Handler, NULL)); } #endif + if (sysno == __NR_madvise) { // Only allow MADV_DONTNEED (aka MADV_FREE). return sandbox->Cond(2, ErrorCode::TP_32BIT, @@ -1266,17 +1303,28 @@ ErrorCode BaselinePolicy(Sandbox *sandbox, int sysno) { ErrorCode(EPERM)); } - if (IsBaselinePolicyAllowed(sysno)) { - return ErrorCode(ErrorCode::ERR_ALLOWED); +#if defined(__i386__) || defined(__x86_64__) + if (sysno == __NR_mmap) { + if (IsArchitectureX86_64()) + return RestrictMmapFlags(sandbox); + else + return ErrorCode(ErrorCode::ERR_ALLOWED); } +#endif -#if defined(__i386__) - // socketcall(2) should be tightened. - if (IsSocketCall(sysno)) { +#if defined(__i386__) || defined(__arm__) + if (sysno == __NR_mmap2) { return ErrorCode(ErrorCode::ERR_ALLOWED); } #endif + if (sysno == __NR_mprotect) { + if (IsArchitectureX86_64()) + return RestrictMprotectFlags(sandbox); + else + return ErrorCode(ErrorCode::ERR_ALLOWED); + } + // TODO(jln): some system calls in those sets are not supposed to // return ENOENT. Return the appropriate error. if (IsFileSystem(sysno) || IsCurrentDirectory(sysno)) { @@ -1302,6 +1350,14 @@ ErrorCode GpuProcessPolicy(Sandbox *sandbox, int sysno, void *broker_process) { switch(sysno) { case __NR_ioctl: +#if defined(__i386__) || defined(__x86_64__) + // The Nvidia driver uses flags not in the baseline policy + // (MAP_LOCKED | MAP_EXECUTABLE | MAP_32BIT) + case __NR_mmap: +#endif + // We also hit this on the linux_chromeos bot but don't yet know what + // weird flags were involved. + case __NR_mprotect: case __NR_sched_getaffinity: case __NR_sched_setaffinity: return ErrorCode(ErrorCode::ERR_ALLOWED); |