Bug 1384986 - Adjust sandbox policy for dconf's `mkdir -p` behavior. r=gcp
MozReview-Commit-ID: HNvOXNJTc1W
--- 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
}