Bug 1412480 - Statically check for overly large syscall arguments. r?gcp draft
authorJed Davis <jld@mozilla.com>
Fri, 27 Oct 2017 19:51:26 -0600
changeset 689116 a89aed9d9e5bc9fa2822e996f209fbc8316511e2
parent 689115 21df9e2db439843d97eac482243e8f86b9175f6f
child 738219 3e7941f72cbbe03dbb51c4bf1ce894beb0253532
push id86912
push userbmo:jld@mozilla.com
push dateTue, 31 Oct 2017 01:25:54 +0000
reviewersgcp
bugs1412480
milestone58.0a1
Bug 1412480 - Statically check for overly large syscall arguments. r?gcp See the previous patch for an explanation of the mistake that this is meant to catch. Note that, even for arguments that really are 64-bit on 32-bit platforms (typically off_t), it's generally not safe to pass them directly to syscall(): some architectures, like ARM, use ABIs that require such arguments to be passed in aligned register pairs, and they'll be aligned differently for syscall() vs. the actual system call due to the leading system call number argument. The syscall(2) man page discusses this and documents that such arguments should be split into high/low halves, passed separately, and manually padded. Therefore, this patch rejects any argument types larger than a word. MozReview-Commit-ID: FVhpri4zcWk
security/sandbox/linux/SandboxFilter.cpp
--- a/security/sandbox/linux/SandboxFilter.cpp
+++ b/security/sandbox/linux/SandboxFilter.cpp
@@ -10,16 +10,17 @@
 #include "SandboxBrokerClient.h"
 #include "SandboxInfo.h"
 #include "SandboxInternal.h"
 #include "SandboxLogging.h"
 #ifdef MOZ_GMP_SANDBOX
 #include "SandboxOpenedFiles.h"
 #endif
 #include "mozilla/PodOperations.h"
+#include "mozilla/TemplateLib.h"
 #include "mozilla/UniquePtr.h"
 
 #include <errno.h>
 #include <fcntl.h>
 #include <linux/ioctl.h>
 #include <linux/ipc.h>
 #include <linux/net.h>
 #include <linux/prctl.h>
@@ -100,16 +101,18 @@ protected:
   // Convert Unix-style "return -1 and set errno" APIs back into the
   // Linux ABI "return -err" style.
   static intptr_t ConvertError(long rv) {
     return rv < 0 ? -errno : rv;
   }
 
   template<typename... Args>
   static intptr_t DoSyscall(long nr, Args... args) {
+    static_assert(tl::And<(sizeof(Args) <= sizeof(void*))...>::value,
+                  "each syscall arg is at most one word");
     return ConvertError(syscall(nr, args...));
   }
 
 private:
   // Bug 1093893: Translate tkill to tgkill for pthread_kill; fixed in
   // bionic commit 10c8ce59a (in JB and up; API level 16 = Android 4.1).
   // Bug 1376653: musl also needs this, and security-wise it's harmless.
   static intptr_t TKillCompatTrap(ArgsRef aArgs, void *aux)