Bug 1409900 - Handle sandboxed statfs() by replacing it with open+fstatfs. r=gcp
authorJed Davis <jld@mozilla.com>
Fri, 27 Oct 2017 19:32:37 -0600
changeset 389178 862de4b756405c181a1db886a16a603ffe2f20df
parent 389177 9f9c7289c55b64d0faba947f16162e178eab1a19
child 389179 d1e920ac2d7c1f6c03face443dc839bb26ad6f17
push id32779
push userebalazs@mozilla.com
push dateTue, 31 Oct 2017 10:45:04 +0000
treeherdermozilla-central@a16cc603d061 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgcp
bugs1409900
milestone58.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1409900 - Handle sandboxed statfs() by replacing it with open+fstatfs. r=gcp MozReview-Commit-ID: 4Q0XMWcxaAc
security/sandbox/linux/SandboxFilter.cpp
--- a/security/sandbox/linux/SandboxFilter.cpp
+++ b/security/sandbox/linux/SandboxFilter.cpp
@@ -534,16 +534,50 @@ private:
 
   static intptr_t SocketpairDatagramTrap(ArgsRef aArgs, void* aux) {
     auto fds = reinterpret_cast<int*>(aArgs.args[3]);
     // Return sequential packet sockets instead of the expected
     // datagram sockets; see bug 1355274 for details.
     return ConvertError(socketpair(AF_UNIX, SOCK_SEQPACKET, 0, fds));
   }
 
+  static intptr_t StatFsTrap(ArgsRef aArgs, void* aux) {
+    // Warning: the kernel interface is not the C interface.  The
+    // structs are different (<asm/statfs.h> vs. <sys/statfs.h>), and
+    // the statfs64 version takes an additional size parameter.
+    auto path = reinterpret_cast<const char*>(aArgs.args[0]);
+    int fd = open(path, O_RDONLY | O_LARGEFILE);
+    if (fd < 0) {
+      return -errno;
+    }
+
+    intptr_t rv;
+    switch (aArgs.nr) {
+    case __NR_statfs: {
+      auto buf = reinterpret_cast<void*>(aArgs.args[1]);
+      rv = DoSyscall(__NR_fstatfs, fd, buf);
+      break;
+    }
+#ifdef __NR_statfs64
+    case __NR_statfs64: {
+      auto sz = static_cast<size_t>(aArgs.args[1]);
+      auto buf = reinterpret_cast<void*>(aArgs.args[2]);
+      rv = DoSyscall(__NR_fstatfs64, fd, sz, buf);
+      break;
+    }
+#endif
+    default:
+      MOZ_ASSERT(false);
+      rv = -ENOSYS;
+    }
+
+    close(fd);
+    return rv;
+  }
+
 public:
   explicit ContentSandboxPolicy(SandboxBrokerClient* aBroker,
                                 const std::vector<int>& aSyscallWhitelist)
     : mBroker(aBroker),
       mSyscallWhitelist(aSyscallWhitelist) {}
   ~ContentSandboxPolicy() override = default;
   Maybe<ResultExpr> EvaluateSocketCall(int aCall) const override {
     switch(aCall) {
@@ -686,20 +720,22 @@ public:
       }
     }
 
     switch (sysno) {
 #ifdef DESKTOP
     case __NR_getppid:
       return Trap(GetPPidTrap, nullptr);
 
+    CASES_FOR_statfs:
+      return Trap(StatFsTrap, nullptr);
+
       // Filesystem syscalls that need more work to determine who's
       // using them, if they need to be, and what we intend to about it.
     case __NR_getcwd:
-    CASES_FOR_statfs:
     CASES_FOR_fstatfs:
     CASES_FOR_fchown:
     case __NR_fchmod:
     case __NR_flock:
       return Allow();
 
       // Bug 1354731: proprietary GL drivers try to mknod() their devices
     case __NR_mknod: {