Bug 1384986 - Adjust sandbox policy for dconf's `mkdir -p` behavior. r=gcp draft
authorJed Davis <jld@mozilla.com>
Thu, 10 Aug 2017 19:02:22 -0600
changeset 649314 ab1771a8e7b64d4e7b5c3ca01bba2c7015f60b69
parent 649313 28fa18b025a175ea1724c64ba682764e62e7c419
child 727055 3c177d06b40668ae73fce71e3e655a39856a1491
push id75007
push userbmo:jld@mozilla.com
push dateSat, 19 Aug 2017 00:02:19 +0000
reviewersgcp
bugs1384986
milestone57.0a1
Bug 1384986 - Adjust sandbox policy for dconf's `mkdir -p` behavior. r=gcp MozReview-Commit-ID: HNvOXNJTc1W
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
@@ -279,16 +279,32 @@ SandboxBroker::Policy::AddDynamic(int aP
       AddDir(aPerms, aPath);
     } else {
       AddPath(aPerms, aPath);
     }
   }
 }
 
 void
+SandboxBroker::Policy::AddAncestors(const char* aPath, int aPerms)
+{
+  nsAutoCString path(aPath);
+
+  while (true) {
+    const auto lastSlash = path.RFindCharInSet("/");
+    if (lastSlash <= 0) {
+      MOZ_ASSERT(lastSlash == 0);
+      return;
+    }
+    path.Truncate(lastSlash);
+    AddPath(aPerms, path.get());
+  }
+}
+
+void
 SandboxBroker::Policy::FixRecursivePermissions()
 {
   // This builds an entirely new hashtable in order to avoid iterator
   // invalidation problems.
   PathPermissionMap oldMap;
   mMap.SwapElements(oldMap);
 
   if (SandboxInfo::Get().Test(SandboxInfo::kVerbose)) {
--- a/security/sandbox/linux/broker/SandboxBroker.h
+++ b/security/sandbox/linux/broker/SandboxBroker.h
@@ -90,16 +90,20 @@ class SandboxBroker final
     void AddDir(int aPerms, const char* aPath);
     // All files in a directory with a given prefix; useful for devices.
     void AddFilePrefix(int aPerms, const char* aDir, const char* aPrefix);
     // Everything starting with the given path, even those files/dirs
     // added after creation. The file or directory may or may not exist.
     void AddPrefix(int aPerms, const char* aPath);
     // Adds a file or dir (end with /) if it exists, and a prefix otherwhise.
     void AddDynamic(int aPerms, const char* aPath);
+    // Adds permissions on all ancestors of a path.  (This doesn't
+    // include the root directory, but if the path is given with a
+    // trailing slash it includes the path without the slash.)
+    void AddAncestors(const char* aPath, int aPerms = MAY_ACCESS);
     // Default: add file if it exists when creating policy or if we're
     // conferring permission to create it (log files, etc.).
     void AddPath(int aPerms, const char* aPath) {
       AddPath(aPerms, aPath,
               (aPerms & MAY_CREATE) ? AddAlways : AddIfExistsNow);
     }
     int Lookup(const nsACString& aPath) const;
     int Lookup(const char* aPath) const {
--- a/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
+++ b/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
@@ -79,16 +79,17 @@ SandboxBrokerPolicyFactory::SandboxBroke
 #endif
 
 #ifdef MOZ_WIDGET_GTK
   if (const auto userDir = g_get_user_runtime_dir()) {
     // Bug 1321134: DConf's single bit of shared memory
     // The leaf filename is "user" by default, but is configurable.
     nsPrintfCString shmPath("%s/dconf/", userDir);
     policy->AddPrefix(rdwrcr, shmPath.get());
+    policy->AddAncestors(shmPath.get());
 #ifdef MOZ_PULSEAUDIO
     // PulseAudio, if it can't get server info from X11, will break
     // unless it can open this directory (or create it, but in our use
     // case we know it already exists).  See bug 1335329.
     nsPrintfCString pulsePath("%s/pulse", userDir);
     policy->AddPath(rdonly, pulsePath.get());
 #endif // MOZ_PULSEAUDIO
   }