summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcevans@chromium.org <cevans@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-20 04:07:07 +0000
committercevans@chromium.org <cevans@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-20 04:07:07 +0000
commitb58eb6e8e7eb0479c846ae7ef481c64d16fd9acc (patch)
treed8ae90d83359d885ad90e3b6af0adfd7a637f0ba
parentc7a8fd34f1fcabf3f730fc38a46907068927ea22 (diff)
downloadchromium_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.cc80
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);