Bug 1614983 - Create a new sandbox profile for the socket process r=spohl
authorHaik Aftandilian <haftandilian@mozilla.com>
Wed, 11 Mar 2020 22:20:13 +0000
changeset 518272 b9bf352a94d2d41df26dae4a672daadb5185fdce
parent 518271 0c97f79721f66b706bcd2ba5f62a2ced9e1390db
child 518273 71df0e854e4f728d2eade9260fb2ecf44e5ab3d5
push id37206
push useraciure@mozilla.com
push dateThu, 12 Mar 2020 03:57:49 +0000
treeherdermozilla-central@4fd5c458be4c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersspohl
bugs1614983, 1611288
milestone76.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 1614983 - Create a new sandbox profile for the socket process r=spohl Add, but don't enable, a sandbox policy to be used with the socket process. A follow-up fix (bug 1611288) will change the socket process code to use the sandbox. The macOS socket sandbox is similar to the utility sandbox (only used for the RDD process), with additions to allow networking I/O, access to files for DNS resolution, access to certificate stores, and notifications about network configuration changes. Differential Revision: https://phabricator.services.mozilla.com/D64682
security/sandbox/mac/Sandbox.h
security/sandbox/mac/Sandbox.mm
security/sandbox/mac/SandboxPolicySocket.h
--- a/security/sandbox/mac/Sandbox.h
+++ b/security/sandbox/mac/Sandbox.h
@@ -9,16 +9,17 @@
 #include <string>
 
 enum MacSandboxType {
   MacSandboxType_Default = 0,
   MacSandboxType_Content,
   MacSandboxType_Flash,
   MacSandboxType_GMP,
   MacSandboxType_Utility,
+  MacSandboxType_Socket,
   MacSandboxType_Invalid
 };
 
 typedef struct _MacSandboxInfo {
   _MacSandboxInfo()
       : type(MacSandboxType_Default),
         level(0),
         hasFilePrivileges(false),
--- a/security/sandbox/mac/Sandbox.mm
+++ b/security/sandbox/mac/Sandbox.mm
@@ -18,16 +18,17 @@
 #include <sstream>
 #include <vector>
 
 #include "mozilla/Assertions.h"
 #include "SandboxPolicyContent.h"
 #include "SandboxPolicyFlash.h"
 #include "SandboxPolicyGMP.h"
 #include "SandboxPolicyUtility.h"
+#include "SandboxPolicySocket.h"
 
 // XXX There are currently problems with the /usr/include/sandbox.h file on
 // some/all of the Macs in Mozilla's build system. Further,
 // sandbox_init_with_parameters is not included in the header.  For the time
 // being (until this problem is resolved), we refer directly to what we need
 // from it, rather than including it here.
 extern "C" int sandbox_init(const char* profile, uint64_t flags, char** errorbuf);
 extern "C" int sandbox_init_with_parameters(const char* profile, uint64_t flags,
@@ -143,16 +144,17 @@ void MacSandboxInfo::AppendAsParams(std:
       this->AppendAudioParam(aParams);
       this->AppendWindowServerParam(aParams);
       this->AppendReadPathParams(aParams);
 #ifdef DEBUG
       this->AppendDebugWriteDirParam(aParams);
 #endif
       break;
     case MacSandboxType_Utility:
+    case MacSandboxType_Socket:
       break;
     case MacSandboxType_GMP:
       this->AppendPluginPathParam(aParams);
       this->AppendWindowServerParam(aParams);
       this->AppendReadPathParams(aParams);
       break;
     default:
       // Before supporting a new process type, add a case statement
@@ -297,16 +299,28 @@ bool StartMacSandbox(MacSandboxInfo cons
     params.push_back("SHOULD_LOG");
     params.push_back(aInfo.shouldLog ? "TRUE" : "FALSE");
     params.push_back("APP_PATH");
     params.push_back(aInfo.appPath.c_str());
     if (!aInfo.crashServerPort.empty()) {
       params.push_back("CRASH_PORT");
       params.push_back(aInfo.crashServerPort.c_str());
     }
+  } else if (aInfo.type == MacSandboxType_Socket) {
+    profile = const_cast<char*>(SandboxPolicySocket);
+    params.push_back("SHOULD_LOG");
+    params.push_back(aInfo.shouldLog ? "TRUE" : "FALSE");
+    params.push_back("APP_PATH");
+    params.push_back(aInfo.appPath.c_str());
+    if (!aInfo.crashServerPort.empty()) {
+      params.push_back("CRASH_PORT");
+      params.push_back(aInfo.crashServerPort.c_str());
+    }
+    params.push_back("HOME_PATH");
+    params.push_back(getenv("HOME"));
   } else if (aInfo.type == MacSandboxType_GMP) {
     profile = const_cast<char*>(SandboxPolicyGMP);
     params.push_back("SHOULD_LOG");
     params.push_back(aInfo.shouldLog ? "TRUE" : "FALSE");
     params.push_back("APP_PATH");
     params.push_back(aInfo.appPath.c_str());
     params.push_back("PLUGIN_PATH");
     params.push_back(aInfo.pluginPath.c_str());
@@ -405,17 +419,17 @@ bool StartMacSandbox(MacSandboxInfo cons
   }
 
 // In order to avoid relying on any other Mozilla modules (as described at the
 // top of this file), we use our own #define instead of the existing MOZ_LOG
 // infrastructure. This can be used by developers to debug the macOS sandbox
 // policy.
 #define MAC_SANDBOX_PRINT_POLICY 0
 #if MAC_SANDBOX_PRINT_POLICY
-  printf("Sandbox params:\n");
+  printf("Sandbox params for PID %d:\n", getpid());
   for (size_t i = 0; i < params.size() / 2; i++) {
     printf("  %s = %s\n", params[i * 2], params[(i * 2) + 1]);
   }
   printf("Sandbox profile:\n%s\n", profile.c_str());
 #endif
 
   // The parameters array is null terminated.
   params.push_back(nullptr);
@@ -590,16 +604,20 @@ bool GetUtilitySandboxParamsFromArgs(int
     fprintf(stderr, "Utility sandbox disabled due to "
                     "missing sandbox CLI app path parameter.\n");
     return false;
   }
 
   return true;
 }
 
+bool GetSocketSandboxParamsFromArgs(int aArgc, char** aArgv, MacSandboxInfo& aInfo) {
+  return GetUtilitySandboxParamsFromArgs(aArgc, aArgv, aInfo);
+}
+
 bool GetPluginSandboxParamsFromArgs(int aArgc, char** aArgv, MacSandboxInfo& aInfo) {
   // Ensure we find these paramaters in the command
   // line arguments. Return false if any are missing.
   bool foundAppPath = false;
   bool foundPluginPath = false;
 
   // Read access directories used in testing
   int nTestingReadPaths = 0;
@@ -701,16 +719,21 @@ bool StartMacSandboxIfEnabled(const MacS
         return false;
       }
       break;
     case MacSandboxType_Utility:
       if (!GetUtilitySandboxParamsFromArgs(aArgc, aArgv, info)) {
         return false;
       }
       break;
+    case MacSandboxType_Socket:
+      if (!GetSocketSandboxParamsFromArgs(aArgc, aArgv, info)) {
+        return false;
+      }
+      break;
     case MacSandboxType_GMP:
       if (!GetPluginSandboxParamsFromArgs(aArgc, aArgv, info)) {
         return false;
       }
       break;
     default:
       MOZ_RELEASE_ASSERT(false);
       break;
new file mode 100644
--- /dev/null
+++ b/security/sandbox/mac/SandboxPolicySocket.h
@@ -0,0 +1,142 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_SandboxPolicySocket_h
+#define mozilla_SandboxPolicySocket_h
+
+namespace mozilla {
+
+static const char SandboxPolicySocket[] = R"SANDBOX_LITERAL(
+  (version 1)
+
+  (define should-log (param "SHOULD_LOG"))
+  (define app-path (param "APP_PATH"))
+  (define crashPort (param "CRASH_PORT"))
+  (define home-path (param "HOME_PATH"))
+
+  (define (moz-deny feature)
+    (if (string=? should-log "TRUE")
+      (deny feature)
+      (deny feature (with no-log))))
+
+  (define (home-subpath home-relative-subpath)
+    (subpath (string-append home-path home-relative-subpath)))
+  (define (home-literal home-relative-literal)
+    (literal (string-append home-path home-relative-literal)))
+  (define (home-regex home-relative-regex)
+    (regex (string-append "^" (regex-quote home-path) home-relative-regex)))
+
+  (moz-deny default)
+  ; These are not included in (deny default)
+  (moz-deny process-info*)
+  ; This isn't available in some older macOS releases.
+  (if (defined? 'nvram*)
+    (moz-deny nvram*))
+  ; This property requires macOS 10.10+
+  (if (defined? 'file-map-executable)
+    (moz-deny file-map-executable))
+
+  (if (string=? should-log "TRUE")
+    (debug deny))
+
+  ; Needed for things like getpriority()/setpriority()/pthread_setname()
+  (allow process-info-pidinfo process-info-setcontrol (target self))
+
+  (if (defined? 'file-map-executable)
+    (allow file-map-executable file-read*
+      (subpath "/System/Library")
+      (subpath "/usr/lib")
+      (subpath app-path))
+    (allow file-read*
+      (subpath "/System/Library")
+      (subpath "/usr/lib")
+      (subpath app-path)))
+
+  (if (string? crashPort)
+    (allow mach-lookup (global-name crashPort)))
+
+  (allow signal (target self))
+  (allow sysctl-read)
+  (allow file-read*
+    (literal "/dev/random")
+    (literal "/dev/urandom")
+    (subpath "/usr/share/icu"))
+
+  ; For stat and symlink resolution
+  (allow file-read-metadata (subpath "/"))
+
+  ; Timezone
+  (allow file-read*
+    (subpath "/private/var/db/timezone")
+    (subpath "/usr/share/zoneinfo")
+    (subpath "/usr/share/zoneinfo.default")
+    (literal "/private/etc/localtime"))
+
+  ; Needed for some global preferences
+  (allow file-read-data
+    (literal "/Library/Preferences/.GlobalPreferences.plist")
+    (home-literal "/Library/Preferences/.GlobalPreferences.plist")
+    (home-regex #"/Library/Preferences/ByHost/\.GlobalPreferences.*")
+    (home-literal "/Library/Preferences/com.apple.universalaccess.plist"))
+
+  (allow file-read-data (literal "/private/etc/passwd"))
+
+  (allow network-outbound
+    (control-name "com.apple.netsrc")
+    (literal "/private/var/run/mDNSResponder")
+    (remote tcp)
+    (remote udp))
+
+  (allow system-socket
+    (require-all (socket-domain AF_SYSTEM)
+      (socket-protocol 2)) ; SYSPROTO_CONTROL
+      (socket-domain AF_ROUTE))
+
+  (allow network-bind network-inbound
+    (local tcp)
+    (local udp))
+
+  ; Distributed notifications memory.
+  (allow ipc-posix-shm-read-data
+    (ipc-posix-name "apple.shm.notification_center"))
+
+  ; Notification data from the security server database.
+  (allow ipc-posix-shm
+    (ipc-posix-name "com.apple.AppleDatabaseChanged"))
+
+  ; From system.sb
+  (allow mach-lookup
+    (global-name "com.apple.bsd.dirhelper")
+    (global-name "com.apple.coreservices.launchservicesd")
+    (global-name "com.apple.system.notification_center"))
+
+  ; resolv.conf and hosts file
+  (allow file-read*
+    (literal "/")
+    (literal "/etc")
+    (literal "/etc/hosts")
+    (literal "/etc/resolv.conf")
+    (literal "/private")
+    (literal "/private/etc")
+    (literal "/private/etc/hosts")
+    (literal "/private/etc/resolv.conf")
+    (literal "/private/var")
+    (literal "/private/var/run")
+    (literal "/private/var/run/resolv.conf")
+    (literal "/var")
+    (literal "/var/run"))
+
+  ; Certificate databases
+  (allow file-read*
+    (subpath "/private/var/db/mds")
+    (subpath "/Library/Keychains")
+    (subpath "/System/Library/Keychains")
+    (subpath "/System/Library/Security")
+    (home-subpath "/Library/Keychains"))
+)SANDBOX_LITERAL";
+
+}  // namespace mozilla
+
+#endif  // mozilla_SandboxPolicySocket_h