Bug 1386404 - Intercept access to /tmp and rewrite to content process tempdir. r=jld
☠☠ backed out by fc577ae44921 ☠ ☠
authorGian-Carlo Pascutto <gcp@mozilla.com>
Thu, 26 Oct 2017 17:50:49 +0200
changeset 452829 2c007d385ce4c1277240945d6f6f0e89a1e3584c
parent 452828 fbe717b9a66443bdefa742be1875fa58de04a309
child 452830 b7ca6ae185f2eb6e138613d95dfb04ed3a477f1e
push id1648
push usermtabara@mozilla.com
push dateThu, 01 Mar 2018 12:45:47 +0000
treeherdermozilla-release@cbb9688c2eeb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjld
bugs1386404
milestone59.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 1386404 - Intercept access to /tmp and rewrite to content process tempdir. r=jld MozReview-Commit-ID: 2h9hw6opYof
security/sandbox/linux/broker/SandboxBroker.cpp
security/sandbox/linux/broker/SandboxBroker.h
security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
--- a/security/sandbox/linux/broker/SandboxBroker.cpp
+++ b/security/sandbox/linux/broker/SandboxBroker.cpp
@@ -23,16 +23,19 @@
 
 #include "base/string_util.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/Move.h"
 #include "mozilla/NullPtr.h"
 #include "mozilla/Sprintf.h"
 #include "mozilla/ipc/FileDescriptor.h"
+#include "nsDirectoryServiceDefs.h"
+#include "nsAppDirectoryServiceDefs.h"
+#include "SpecialSystemDirectory.h"
 #include "sandbox/linux/system_headers/linux_syscalls.h"
 
 namespace mozilla {
 
 // This constructor signals failure by setting mFileDesc and aClientFd to -1.
 SandboxBroker::SandboxBroker(UniquePtr<const Policy> aPolicy, int aChildPid,
                              int& aClientFd)
   : mChildPid(aChildPid), mPolicy(Move(aPolicy))
@@ -510,16 +513,44 @@ SandboxBroker::ConvertToRealPath(char* a
       // Size changed, but guaranteed to be 0 terminated
       aPathLen = strlen(aPath);
     }
     // ValidatePath will handle failure to translate
   }
   return aPathLen;
 }
 
+size_t
+SandboxBroker::RemapTempDirs(char* aPath, size_t aBufSize, size_t aPathLen)
+{
+  nsAutoCString path(aPath);
+  static const nsLiteralCString tempPrefix(NS_LITERAL_CSTRING("/tmp"));
+
+  if (StringBeginsWith(path, tempPrefix)) {
+    size_t prefixLen = tempPrefix.Length();
+    const nsDependentCSubstring cutPath =
+      Substring(path, prefixLen, path.Length() - prefixLen);
+    // Only now try to get the content process temp dir
+    nsCOMPtr<nsIFile> tmpDir;
+    nsresult rv = NS_GetSpecialDirectory(NS_APP_CONTENT_PROCESS_TEMP_DIR,
+                                          getter_AddRefs(tmpDir));
+    if (NS_SUCCEEDED(rv)) {
+      nsAutoCString tmpPath;
+      rv = tmpDir->GetNativePath(tmpPath);
+      if (NS_SUCCEEDED(rv)) {
+        tmpPath.Append(cutPath);
+        base::strlcpy(aPath, tmpPath.get(), aBufSize);
+        return strlen(aPath);
+      }
+    }
+  }
+
+  return aPathLen;
+}
+
 nsCString
 SandboxBroker::ReverseSymlinks(const nsACString& aPath)
 {
   // Revert any symlinks we previously resolved.
   int32_t cutLength = aPath.Length();
   nsCString cutPath(Substring(aPath, 0, cutLength));
 
   for (;;) {
@@ -670,16 +701,17 @@ SandboxBroker::ThreadMain(void)
       // enforced below.
       strncpy(pathBuf2, recvBuf + first_len + 1, kMaxPathLen + 1);
 
       // First string is guaranteed to be 0-terminated.
       pathLen = first_len;
 
       // Look up the first pathname but first translate relative paths.
       pathLen = ConvertToRealPath(pathBuf, sizeof(pathBuf), pathLen);
+      pathLen = RemapTempDirs(pathBuf, sizeof(pathBuf), pathLen);
       perms = mPolicy->Lookup(nsDependentCString(pathBuf, pathLen));
 
       // We don't have read permissions on the requested dir.
       // Did we arrive from a symlink in a path that is not writable?
       // Then try to figure out the original path and see if that is readable.
       if (!(perms & MAY_READ)) {
           // Work on the original path,
           // this reverses ConvertToRealPath above.
--- a/security/sandbox/linux/broker/SandboxBroker.h
+++ b/security/sandbox/linux/broker/SandboxBroker.h
@@ -138,16 +138,18 @@ class SandboxBroker final
 
   SandboxBroker(UniquePtr<const Policy> aPolicy, int aChildPid,
                 int& aClientFd);
   void ThreadMain(void) override;
   void AuditPermissive(int aOp, int aFlags, int aPerms, const char* aPath);
   void AuditDenial(int aOp, int aFlags, int aPerms, const char* aPath);
   // Remap relative paths to absolute paths.
   size_t ConvertToRealPath(char* aPath, size_t aBufSize, size_t aPathLen);
+  // Remap references to /tmp and friends to the content process tempdir
+  size_t RemapTempDirs(char* aPath, size_t aBufSize, size_t aPathLen);
   nsCString ReverseSymlinks(const nsACString& aPath);
   // Retrieves permissions for the path the original symlink sits in.
   int SymlinkPermissions(const char* aPath, const size_t aPathLen);
   // In SandboxBrokerRealPath.cpp
   char* SymlinkPath(const Policy* aPolicy, const char* __restrict aPath,
                     char* __restrict aResolved, int* aPermission);
 
   // Holding a UniquePtr should disallow copying, but to make that explicit:
--- a/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
+++ b/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
@@ -228,18 +228,16 @@ SandboxBrokerPolicyFactory::SandboxBroke
   policy->AddDir(rdonly, "/usr/lib32");
   policy->AddDir(rdonly, "/usr/lib64");
   policy->AddDir(rdonly, "/etc");
 #ifdef MOZ_PULSEAUDIO
   policy->AddPath(rdonly, "/var/lib/dbus/machine-id");
 #endif
   policy->AddDir(rdonly, "/usr/share");
   policy->AddDir(rdonly, "/usr/local/share");
-  policy->AddDir(rdonly, "/usr/tmp");
-  policy->AddDir(rdonly, "/var/tmp");
   // Various places where fonts reside
   policy->AddDir(rdonly, "/usr/X11R6/lib/X11/fonts");
   policy->AddDir(rdonly, "/nix/store");
   policy->AddDir(rdonly, "/run/host/fonts");
   policy->AddDir(rdonly, "/run/host/user-fonts");
 
   AddMesaSysfsPaths(policy);
   AddLdconfigPaths(policy);