Bug 1374557 - Part 1 - Add the ability to specify a list of paths to whitelist read access to in the macOS content sandbox; r?haik draft
authorAlex Gaynor <agaynor@mozilla.com>
Wed, 21 Jun 2017 10:19:28 -0400
changeset 602743 8464eb0c00a44a3a635a955e7bf69a12d7c64384
parent 602698 0b5603017c25e943ba3ab97cb46d88adf1e6a3e4
child 602744 97b7462a993da82ca1e5dc0048422a6915b4a175
push id66530
push userbmo:agaynor@mozilla.com
push dateFri, 30 Jun 2017 18:02:22 +0000
reviewershaik
bugs1374557
milestone56.0a1
Bug 1374557 - Part 1 - Add the ability to specify a list of paths to whitelist read access to in the macOS content sandbox; r?haik MozReview-Commit-ID: HXBkyR7Tts2
dom/ipc/ContentChild.cpp
security/sandbox/mac/Sandbox.h
security/sandbox/mac/Sandbox.mm
security/sandbox/mac/SandboxPolicies.h
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -1515,22 +1515,35 @@ StartMacOSContentSandbox()
   MacSandboxInfo info;
   info.type = MacSandboxType_Content;
   info.level = sandboxLevel;
   info.hasFilePrivileges = isFileProcess;
   info.shouldLog = Preferences::GetBool("security.sandbox.logging.enabled") ||
                    PR_GetEnv("MOZ_SANDBOX_LOGGING");
   info.appPath.assign(appPath.get());
   info.appBinaryPath.assign(appBinaryPath.get());
-  if (developer_repo_dir != nullptr) {
-    info.appDir.assign(developer_repo_dir);
-  } else {
-    info.appDir.assign(appDir.get());
+  info.appDir.assign(appDir.get());
+  info.appTempDir.assign(tempDirPath.get());
+
+  // These paths are used to whitelist certain directories used by the testing
+  // system. They should not be considered a public API, and are only intended
+  // for use in automation.
+  nsAdoptingCString testingReadPath1 =
+    Preferences::GetCString("security.sandbox.content.mac.testing_read_path1");
+  if (!testingReadPath1.IsEmpty()) {
+    info.testingReadPath1.assign(testingReadPath1.get());
   }
-  info.appTempDir.assign(tempDirPath.get());
+  nsAdoptingCString testingReadPath2 =
+    Preferences::GetCString("security.sandbox.content.mac.testing_read_path2");
+  if (!testingReadPath2.IsEmpty()) {
+    info.testingReadPath2.assign(testingReadPath2.get());
+  }
+  if (developer_repo_dir) {
+    info.testingReadPath3.assign(developer_repo_dir);
+  }
 
   if (profileDir) {
     info.hasSandboxedProfile = true;
     info.profileDir.assign(profileDirPath.get());
   } else {
     info.hasSandboxedProfile = false;
   }
 
--- a/security/sandbox/mac/Sandbox.h
+++ b/security/sandbox/mac/Sandbox.h
@@ -44,28 +44,35 @@ typedef struct _MacSandboxInfo {
   _MacSandboxInfo(const struct _MacSandboxInfo& other)
     : type(other.type), level(other.level),
       hasFilePrivileges(other.hasFilePrivileges),
       hasSandboxedProfile(other.hasSandboxedProfile),
       pluginInfo(other.pluginInfo),
       appPath(other.appPath), appBinaryPath(other.appBinaryPath),
       appDir(other.appDir), appTempDir(other.appTempDir),
       profileDir(other.profileDir), debugWriteDir(other.debugWriteDir),
-      shouldLog(other.shouldLog) {}
+      testingReadPath1(other.testingReadPath1),
+      testingReadPath2(other.testingReadPath2),
+      testingReadPath3(other.testingReadPath3), shouldLog(other.shouldLog) {}
   MacSandboxType type;
   int32_t level;
   bool hasFilePrivileges;
   bool hasSandboxedProfile;
   MacSandboxPluginInfo pluginInfo;
   std::string appPath;
   std::string appBinaryPath;
   std::string appDir;
   std::string appTempDir;
   std::string profileDir;
   std::string debugWriteDir;
+
+  std::string testingReadPath1;
+  std::string testingReadPath2;
+  std::string testingReadPath3;
+
   bool shouldLog;
 } MacSandboxInfo;
 
 namespace mozilla {
 
 bool StartMacSandbox(MacSandboxInfo aInfo, std::string &aErrorMessage);
 
 } // namespace mozilla
--- a/security/sandbox/mac/Sandbox.mm
+++ b/security/sandbox/mac/Sandbox.mm
@@ -173,16 +173,28 @@ bool StartMacSandbox(MacSandboxInfo aInf
       params.push_back("PROFILE_DIR");
       params.push_back(aInfo.profileDir.c_str());
       params.push_back("HOME_PATH");
       params.push_back(getenv("HOME"));
       params.push_back("HAS_SANDBOXED_PROFILE");
       params.push_back(aInfo.hasSandboxedProfile ? "TRUE" : "FALSE");
       params.push_back("HAS_FILE_PRIVILEGES");
       params.push_back(aInfo.hasFilePrivileges ? "TRUE" : "FALSE");
+      if (!aInfo.testingReadPath1.empty()) {
+        params.push_back("TESTING_READ_PATH1");
+        params.push_back(aInfo.testingReadPath1.c_str());
+      }
+      if (!aInfo.testingReadPath2.empty()) {
+        params.push_back("TESTING_READ_PATH2");
+        params.push_back(aInfo.testingReadPath2.c_str());
+      }
+      if (!aInfo.testingReadPath3.empty()) {
+        params.push_back("TESTING_READ_PATH3");
+        params.push_back(aInfo.testingReadPath3.c_str());
+      }
 #ifdef DEBUG
       if (!aInfo.debugWriteDir.empty()) {
         params.push_back("DEBUG_WRITE_DIR");
         params.push_back(aInfo.debugWriteDir.c_str());
       }
 #endif // DEBUG
     } else {
       fprintf(stderr,
--- a/security/sandbox/mac/SandboxPolicies.h
+++ b/security/sandbox/mac/SandboxPolicies.h
@@ -58,16 +58,19 @@ static const char contentSandboxRules[] 
   (define appBinaryPath (param "APP_BINARY_PATH"))
   (define appdir-path (param "APP_DIR"))
   (define appTempDir (param "APP_TEMP_DIR"))
   (define hasProfileDir (param "HAS_SANDBOXED_PROFILE"))
   (define profileDir (param "PROFILE_DIR"))
   (define home-path (param "HOME_PATH"))
   (define hasFilePrivileges (param "HAS_FILE_PRIVILEGES"))
   (define debugWriteDir (param "DEBUG_WRITE_DIR"))
+  (define testingReadPath1 (param "TESTING_READ_PATH1"))
+  (define testingReadPath2 (param "TESTING_READ_PATH2"))
+  (define testingReadPath3 (param "TESTING_READ_PATH3"))
 
   (if (string=? should-log "TRUE")
     (deny default)
     (deny default (with no-log)))
   (debug deny)
 
   ; Allow read access to standard system paths.
   (allow file-read*
@@ -204,16 +207,23 @@ static const char contentSandboxRules[] 
       (home-subpath "/Library/Spelling")
       (home-subpath "/Library/Application Support/Adobe/CoreSync/plugins/livetype")
 
       (subpath appdir-path)
 
       (literal appPath)
       (literal appBinaryPath))
 
+  (when testingReadPath1
+    (allow file-read* (subpath testingReadPath1)))
+  (when testingReadPath2
+    (allow file-read* (subpath testingReadPath2)))
+  (when testingReadPath3
+    (allow file-read* (subpath testingReadPath3)))
+
   (allow file-read-metadata (home-subpath "/Library"))
 
   (allow file-read-metadata
     (literal "/private/var")
     (subpath "/private/var/folders"))
 
 ; bug 1303987
   (if (string? debugWriteDir)