Bug 1386404 - Use the full tmpdir finding logic. r?jld draft
authorGian-Carlo Pascutto <gcp@mozilla.com>
Tue, 30 Jan 2018 21:31:07 +0100
changeset 749383 705018e7091862675d3f5845d0c5dcc72dfc4d31
parent 749382 50aaccec621d74e51db06dc2cb3d6cd2319d43d7
push id97374
push usergpascutto@mozilla.com
push dateWed, 31 Jan 2018 09:19:12 +0000
reviewersjld
bugs1386404
milestone60.0a1
Bug 1386404 - Use the full tmpdir finding logic. r?jld MozReview-Commit-ID: BDBslEZsctJ
security/sandbox/linux/broker/SandboxBroker.cpp
security/sandbox/linux/broker/SandboxBroker.h
--- a/security/sandbox/linux/broker/SandboxBroker.cpp
+++ b/security/sandbox/linux/broker/SandboxBroker.cpp
@@ -30,16 +30,19 @@
 #include "mozilla/ipc/FileDescriptor.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "SpecialSystemDirectory.h"
 #include "sandbox/linux/system_headers/linux_syscalls.h"
 
 namespace mozilla {
 
+// Default/fallback temporary directory
+static const nsLiteralCString tempDirPrefix(NS_LITERAL_CSTRING("/tmp"));
+
 // 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))
 {
   int fds[2];
   if (0 != socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, fds)) {
     SANDBOX_LOG_ERROR("SandboxBroker: socketpair failed: %s", strerror(errno));
@@ -517,22 +520,28 @@ SandboxBroker::ConvertToRealPath(char* a
   }
   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();
+  size_t prefixLen = 0;
+  if (!mTempPath.IsEmpty() && StringBeginsWith(path, mTempPath)) {
+    prefixLen = mTempPath.Length();
+  } else if (StringBeginsWith(path, tempDirPrefix)) {
+    prefixLen = tempDirPrefix.Length();
+  }
+
+  if (prefixLen) {
     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)) {
@@ -611,16 +620,42 @@ SandboxBroker::ThreadMain(void)
   SprintfLiteral(threadName, "FS Broker %d", mChildPid);
   PlatformThread::SetName(threadName);
 
   // Permissive mode can only be enabled through an environment variable,
   // therefore it is sufficient to fetch the value once
   // before the main thread loop starts
   bool permissive = SandboxInfo::Get().Test(SandboxInfo::kPermissive);
 
+  // Find the current temporary directory
+  nsCOMPtr<nsIFile> tmpDir;
+  nsresult rv = GetSpecialSystemDirectory(OS_TemporaryDirectory,
+                                          getter_AddRefs(tmpDir));
+  if (NS_SUCCEEDED(rv)) {
+    rv = tmpDir->GetNativePath(mTempPath);
+    if (NS_SUCCEEDED(rv)) {
+      // Make sure there's no terminating /
+      if (mTempPath.Last() == '/') {
+        mTempPath.Truncate(mTempPath.Length() - 1);
+      }
+    }
+  }
+  // If we can't find it, we aren't bothered much: we will
+  // always try /tmp anyway in the substitution code
+  if (NS_FAILED(rv) || mTempPath.IsEmpty()) {
+    SANDBOX_LOG_ERROR("Tempdir: /tmp");
+  } else {
+    SANDBOX_LOG_ERROR("Tempdir: %s", mTempPath.get());
+    // If it's /tmp, clear it here so we don't compare against
+    // it twice. Just let the fallback code do the work.
+    if (mTempPath.Equals(tempDirPrefix)) {
+      mTempPath.Truncate();
+    }
+  }
+
   while (true) {
     struct iovec ios[2];
     // We will receive the path strings in 1 buffer and split them back up.
     char recvBuf[2 * (kMaxPathLen + 1)];
     char pathBuf[kMaxPathLen + 1];
     char pathBuf2[kMaxPathLen + 1];
     size_t pathLen = 0;
     size_t pathLen2 = 0;
--- a/security/sandbox/linux/broker/SandboxBroker.h
+++ b/security/sandbox/linux/broker/SandboxBroker.h
@@ -127,16 +127,17 @@ class SandboxBroker final
            ipc::FileDescriptor& aClientFdOut);
   virtual ~SandboxBroker();
 
  private:
   PlatformThreadHandle mThread;
   int mFileDesc;
   const int mChildPid;
   const UniquePtr<const Policy> mPolicy;
+  nsCString mTempPath;
 
   typedef nsDataHashtable<nsCStringHashKey, nsCString> PathMap;
   PathMap mSymlinkMap;
 
   SandboxBroker(UniquePtr<const Policy> aPolicy, int aChildPid,
                 int& aClientFd);
   void ThreadMain(void) override;
   void AuditPermissive(int aOp, int aFlags, int aPerms, const char* aPath);