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
--- 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)