Bug 1383888 - Restrict sandboxed readlinkat() the same as readlink(). r=gcp
authorJed Davis <jld@mozilla.com>
Thu, 27 Jul 2017 17:22:23 -0600
changeset 427967 59db725def8282e1d77e83f002d247c7d0f95237
parent 427966 2d4783c5bf18027bd687213ad26f3f5160da606e
child 427984 37824bf5c5b08afa7e689fceb935b8f457ebd9eb
child 427987 7cec07add03a1e79d3da1cad2953c8afcec2ddf5
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgcp
bugs1383888
milestone57.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 1383888 - Restrict sandboxed readlinkat() the same as readlink(). r=gcp MozReview-Commit-ID: 3VLXp7AJePQ
security/sandbox/linux/SandboxFilter.cpp
--- a/security/sandbox/linux/SandboxFilter.cpp
+++ b/security/sandbox/linux/SandboxFilter.cpp
@@ -489,16 +489,30 @@ private:
   static intptr_t ReadlinkTrap(ArgsRef aArgs, void* aux) {
     auto broker = static_cast<SandboxBrokerClient*>(aux);
     auto path = reinterpret_cast<const char*>(aArgs.args[0]);
     auto buf = reinterpret_cast<char*>(aArgs.args[1]);
     auto size = static_cast<size_t>(aArgs.args[2]);
     return broker->Readlink(path, buf, size);
   }
 
+  static intptr_t ReadlinkAtTrap(ArgsRef aArgs, void* aux) {
+    auto broker = static_cast<SandboxBrokerClient*>(aux);
+    auto fd = static_cast<int>(aArgs.args[0]);
+    auto path = reinterpret_cast<const char*>(aArgs.args[1]);
+    auto buf = reinterpret_cast<char*>(aArgs.args[2]);
+    auto size = static_cast<size_t>(aArgs.args[3]);
+    if (fd != AT_FDCWD && path[0] != '/') {
+      SANDBOX_LOG_ERROR("unsupported fd-relative readlinkat(%d, %s, %p, %u)",
+                        fd, path, buf, size);
+      return BlockedSyscallTrap(aArgs, nullptr);
+    }
+    return broker->Readlink(path, buf, size);
+  }
+
   static intptr_t GetPPidTrap(ArgsRef aArgs, void* aux) {
     // In a pid namespace, getppid() will return 0. We will return 0 instead
     // of the real parent pid to see what breaks when we introduce the
     // pid namespace (Bug 1151624).
     return 0;
   }
 
   static intptr_t SocketpairDatagramTrap(ArgsRef aArgs, void* aux) {
@@ -624,16 +638,18 @@ public:
       case __NR_rename:
         return Trap(RenameTrap, mBroker);
       case __NR_rmdir:
         return Trap(RmdirTrap, mBroker);
       case __NR_unlink:
         return Trap(UnlinkTrap, mBroker);
       case __NR_readlink:
         return Trap(ReadlinkTrap, mBroker);
+      case __NR_readlinkat:
+        return Trap(ReadlinkAtTrap, mBroker);
       }
     } else {
       // No broker; allow the syscalls directly.  )-:
       switch(sysno) {
       case __NR_open:
       case __NR_openat:
       case __NR_access:
       case __NR_faccessat:
@@ -643,16 +659,17 @@ public:
       case __NR_chmod:
       case __NR_link:
       case __NR_mkdir:
       case __NR_symlink:
       case __NR_rename:
       case __NR_rmdir:
       case __NR_unlink:
       case __NR_readlink:
+      case __NR_readlinkat:
         return Allow();
       }
     }
 
     switch (sysno) {
 #ifdef DESKTOP
     case __NR_getppid:
       return Trap(GetPPidTrap, nullptr);
@@ -676,25 +693,16 @@ public:
     }
 
       // For ORBit called by GConf (on some systems) to get proxy
       // settings.  Can remove when bug 1325242 happens in some form.
     case __NR_utime:
       return Error(EPERM);
 #endif
 
-    case __NR_readlinkat:
-#ifdef DESKTOP
-      // Bug 1290896
-      return Allow();
-#else
-      // Workaround for bug 964455:
-      return Error(EINVAL);
-#endif
-
     CASES_FOR_select:
     case __NR_pselect6:
       return Allow();
 
     CASES_FOR_getdents:
     CASES_FOR_ftruncate:
     case __NR_writev:
     case __NR_pread64: