Bug 1386404 - Intercept access to /tmp and rewrite to content process tempdir. r=jld
☠☠ backed out by 27a4ccb808ea ☠ ☠
authorGian-Carlo Pascutto <gcp@mozilla.com>
Thu, 26 Oct 2017 17:50:49 +0200
changeset 389066 b136f90dc49f8c34b44246d8e3e4916bc5c5c24a
parent 389065 4600c2d575f9fdd3168942edde1bc01d2874c460
child 389067 36556e1a5ac7629336c789f006be524030b45765
push id32777
push userarchaeopteryx@coole-files.de
push dateMon, 30 Oct 2017 22:44:45 +0000
treeherdermozilla-central@dd0f265a1300 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjld
bugs1386404
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 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
@@ -226,18 +226,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);