summaryrefslogtreecommitdiffstats
path: root/security/sandbox/mac
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /security/sandbox/mac
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'security/sandbox/mac')
-rw-r--r--security/sandbox/mac/Sandbox.h89
-rw-r--r--security/sandbox/mac/Sandbox.mm806
-rw-r--r--security/sandbox/mac/SandboxPolicyContent.h396
-rw-r--r--security/sandbox/mac/SandboxPolicyFlash.h407
-rw-r--r--security/sandbox/mac/SandboxPolicyGMP.h101
-rw-r--r--security/sandbox/mac/SandboxPolicyRDD.h199
-rw-r--r--security/sandbox/mac/SandboxPolicySocket.h146
-rw-r--r--security/sandbox/mac/SandboxPolicyUtility.h73
-rw-r--r--security/sandbox/mac/moz.build20
9 files changed, 2237 insertions, 0 deletions
diff --git a/security/sandbox/mac/Sandbox.h b/security/sandbox/mac/Sandbox.h
new file mode 100644
index 0000000000..b78a2feeaa
--- /dev/null
+++ b/security/sandbox/mac/Sandbox.h
@@ -0,0 +1,89 @@
+/* -*- 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_Sandbox_h
+#define mozilla_Sandbox_h
+
+#include <string>
+
+enum MacSandboxType {
+ MacSandboxType_Default = 0,
+ MacSandboxType_Content,
+ MacSandboxType_Flash,
+ MacSandboxType_GMP,
+ MacSandboxType_RDD,
+ MacSandboxType_Socket,
+ MacSandboxType_Utility,
+ MacSandboxType_Invalid
+};
+
+typedef struct _MacSandboxInfo {
+ _MacSandboxInfo()
+ : type(MacSandboxType_Default),
+ level(0),
+ hasFilePrivileges(false),
+ hasSandboxedProfile(false),
+ hasAudio(false),
+ hasWindowServer(false),
+ shouldLog(false) {}
+ _MacSandboxInfo(const struct _MacSandboxInfo& other) = default;
+
+ void AppendAsParams(std::vector<std::string>& aParams) const;
+ static void AppendFileAccessParam(std::vector<std::string>& aParams,
+ bool aHasFilePrivileges);
+
+ private:
+ void AppendStartupParam(std::vector<std::string>& aParams) const;
+ void AppendLoggingParam(std::vector<std::string>& aParams) const;
+ void AppendAppPathParam(std::vector<std::string>& aParams) const;
+ void AppendPluginPathParam(std::vector<std::string>& aParams) const;
+ void AppendLevelParam(std::vector<std::string>& aParams) const;
+ void AppendAudioParam(std::vector<std::string>& aParams) const;
+ void AppendWindowServerParam(std::vector<std::string>& aParams) const;
+ void AppendReadPathParams(std::vector<std::string>& aParams) const;
+#ifdef DEBUG
+ void AppendDebugWriteDirParam(std::vector<std::string>& aParams) const;
+#endif
+
+ public:
+ MacSandboxType type;
+ int32_t level;
+ bool hasFilePrivileges;
+ bool hasSandboxedProfile;
+ bool hasAudio;
+ bool hasWindowServer;
+
+ std::string appPath;
+ std::string appBinaryPath;
+ std::string appDir;
+ std::string profileDir;
+ std::string debugWriteDir;
+
+ std::string pluginPath;
+ std::string pluginBinaryPath;
+
+ std::string testingReadPath1;
+ std::string testingReadPath2;
+ std::string testingReadPath3;
+ std::string testingReadPath4;
+
+ std::string crashServerPort;
+
+ bool shouldLog;
+} MacSandboxInfo;
+
+namespace mozilla {
+
+bool StartMacSandbox(MacSandboxInfo const& aInfo, std::string& aErrorMessage);
+bool StartMacSandboxIfEnabled(MacSandboxType aSandboxType, int aArgc,
+ char** aArgv, std::string& aErrorMessage);
+bool IsMacSandboxStarted();
+#ifdef DEBUG
+void AssertMacSandboxEnabled();
+#endif /* DEBUG */
+
+} // namespace mozilla
+
+#endif // mozilla_Sandbox_h
diff --git a/security/sandbox/mac/Sandbox.mm b/security/sandbox/mac/Sandbox.mm
new file mode 100644
index 0000000000..c53c5d5c1f
--- /dev/null
+++ b/security/sandbox/mac/Sandbox.mm
@@ -0,0 +1,806 @@
+/* -*- 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/. */
+
+// The Mac sandbox module is a static library (a Library in moz.build terms)
+// that can be linked into any binary (for example plugin-container or XUL).
+// It must not have dependencies on any other Mozilla module. This is why,
+// for example, it has its own OS X version detection code, rather than
+// linking to nsCocoaFeatures.mm in XUL.
+
+#include "Sandbox.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
+
+#include <iostream>
+#include <sstream>
+#include <vector>
+
+#include "SandboxPolicyContent.h"
+#include "SandboxPolicyFlash.h"
+#include "SandboxPolicyGMP.h"
+#include "SandboxPolicyRDD.h"
+#include "SandboxPolicySocket.h"
+#include "SandboxPolicyUtility.h"
+#include "mozilla/Assertions.h"
+
+// Undocumented sandbox setup routines.
+extern "C" int sandbox_init_with_parameters(const char* profile, uint64_t flags,
+ const char* const parameters[], char** errorbuf);
+extern "C" void sandbox_free_error(char* errorbuf);
+extern "C" int sandbox_check(pid_t pid, const char* operation, int type, ...);
+
+// Note about "major", "minor" and "bugfix" in the following code:
+//
+// The code decomposes an OS X version number into these components, and in
+// doing so follows Apple's terminology in Gestalt.h. But this is very
+// misleading, because in other contexts Apple uses the "minor" component of
+// an OS X version number to indicate a "major" release (for example the "9"
+// in OS X 10.9.5), and the "bugfix" component to indicate a "minor" release
+// (for example the "5" in OS X 10.9.5).
+class OSXVersion {
+ public:
+ static void Get(int32_t& aMajor, int32_t& aMinor);
+
+ private:
+ static void GetSystemVersion(int32_t& aMajor, int32_t& aMinor, int32_t& aBugFix);
+ static bool mCached;
+ static int32_t mOSXVersionMajor;
+ static int32_t mOSXVersionMinor;
+};
+
+bool OSXVersion::mCached = false;
+int32_t OSXVersion::mOSXVersionMajor;
+int32_t OSXVersion::mOSXVersionMinor;
+
+void OSXVersion::Get(int32_t& aMajor, int32_t& aMinor) {
+ if (!mCached) {
+ int32_t major, minor, bugfix;
+ GetSystemVersion(major, minor, bugfix);
+ mOSXVersionMajor = major;
+ mOSXVersionMinor = minor;
+ mCached = true;
+ }
+ aMajor = mOSXVersionMajor;
+ aMinor = mOSXVersionMinor;
+}
+
+void OSXVersion::GetSystemVersion(int32_t& aMajor, int32_t& aMinor, int32_t& aBugFix) {
+ SInt32 major = 0, minor = 0, bugfix = 0;
+
+ CFURLRef url = CFURLCreateWithString(
+ kCFAllocatorDefault, CFSTR("file:///System/Library/CoreServices/SystemVersion.plist"), NULL);
+ CFReadStreamRef stream = CFReadStreamCreateWithFile(kCFAllocatorDefault, url);
+ CFReadStreamOpen(stream);
+ CFDictionaryRef sysVersionPlist = (CFDictionaryRef)CFPropertyListCreateWithStream(
+ kCFAllocatorDefault, stream, 0, kCFPropertyListImmutable, NULL, NULL);
+ CFReadStreamClose(stream);
+ CFRelease(stream);
+ CFRelease(url);
+
+ CFStringRef versionString =
+ (CFStringRef)CFDictionaryGetValue(sysVersionPlist, CFSTR("ProductVersion"));
+ CFArrayRef versions =
+ CFStringCreateArrayBySeparatingStrings(kCFAllocatorDefault, versionString, CFSTR("."));
+ CFIndex count = CFArrayGetCount(versions);
+ if (count > 0) {
+ CFStringRef component = (CFStringRef)CFArrayGetValueAtIndex(versions, 0);
+ major = CFStringGetIntValue(component);
+ if (count > 1) {
+ component = (CFStringRef)CFArrayGetValueAtIndex(versions, 1);
+ minor = CFStringGetIntValue(component);
+ if (count > 2) {
+ component = (CFStringRef)CFArrayGetValueAtIndex(versions, 2);
+ bugfix = CFStringGetIntValue(component);
+ }
+ }
+ }
+ CFRelease(sysVersionPlist);
+ CFRelease(versions);
+
+ if (major < 10) {
+ // If 'major' isn't what we expect, assume 10.6.
+ aMajor = 10;
+ aMinor = 6;
+ aBugFix = 0;
+ } else if ((major == 10) && (minor >= 16)) {
+ // Account for SystemVersionCompat.plist being used which is
+ // automatically used for builds using older SDK versions and
+ // results in 11.0 being reported as 10.16. Assume the compat
+ // version will increase in step with the correct version.
+ aMajor = 11;
+ aMinor = minor - 16;
+ aBugFix = bugfix;
+ } else {
+ aMajor = major;
+ aMinor = minor;
+ aBugFix = bugfix;
+ }
+}
+
+bool GetRealPath(std::string& aOutputPath, const char* aInputPath) {
+ char* resolvedPath = realpath(aInputPath, nullptr);
+ if (resolvedPath == nullptr) {
+ return false;
+ }
+
+ aOutputPath = resolvedPath;
+ free(resolvedPath);
+
+ return !aOutputPath.empty();
+}
+
+/*
+ * Returns true if the process is running under Rosetta translation. Returns
+ * false if running natively or if an error was encountered. To be called
+ * before enabling the sandbox therefore not requiring the sysctl be allowed
+ * by the sandbox policy. We use the `sysctl.proc_translated` sysctl which is
+ * documented by Apple to be used for this purpose.
+ */
+bool ProcessIsRosettaTranslated() {
+ int ret = 0;
+ size_t size = sizeof(ret);
+ if (sysctlbyname("sysctl.proc_translated", &ret, &size, NULL, 0) == -1) {
+ if (errno != ENOENT) {
+ fprintf(stderr, "Failed to check for translation environment\n");
+ }
+ return false;
+ }
+ return (ret == 1);
+}
+
+void MacSandboxInfo::AppendAsParams(std::vector<std::string>& aParams) const {
+ this->AppendStartupParam(aParams);
+ this->AppendLoggingParam(aParams);
+ this->AppendAppPathParam(aParams);
+
+ switch (this->type) {
+ case MacSandboxType_Content:
+ this->AppendLevelParam(aParams);
+ this->AppendAudioParam(aParams);
+ this->AppendWindowServerParam(aParams);
+ this->AppendReadPathParams(aParams);
+#ifdef DEBUG
+ this->AppendDebugWriteDirParam(aParams);
+#endif
+ break;
+ case MacSandboxType_RDD:
+ case MacSandboxType_Socket:
+ case MacSandboxType_Utility:
+ 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
+ // here to append any neccesary process-type-specific params.
+ MOZ_RELEASE_ASSERT(false);
+ break;
+ }
+}
+
+void MacSandboxInfo::AppendStartupParam(std::vector<std::string>& aParams) const {
+ aParams.push_back("-sbStartup");
+}
+
+void MacSandboxInfo::AppendLoggingParam(std::vector<std::string>& aParams) const {
+ if (this->shouldLog) {
+ aParams.push_back("-sbLogging");
+ }
+}
+
+void MacSandboxInfo::AppendAppPathParam(std::vector<std::string>& aParams) const {
+ aParams.push_back("-sbAppPath");
+ aParams.push_back(this->appPath);
+}
+
+void MacSandboxInfo::AppendPluginPathParam(std::vector<std::string>& aParams) const {
+ aParams.push_back("-sbPluginPath");
+ aParams.push_back(this->pluginPath);
+}
+
+/* static */
+void MacSandboxInfo::AppendFileAccessParam(std::vector<std::string>& aParams,
+ bool aHasFilePrivileges) {
+ if (aHasFilePrivileges) {
+ aParams.push_back("-sbAllowFileAccess");
+ }
+}
+
+void MacSandboxInfo::AppendLevelParam(std::vector<std::string>& aParams) const {
+ std::ostringstream os;
+ os << this->level;
+ std::string levelString = os.str();
+ aParams.push_back("-sbLevel");
+ aParams.push_back(levelString);
+}
+
+void MacSandboxInfo::AppendAudioParam(std::vector<std::string>& aParams) const {
+ if (this->hasAudio) {
+ aParams.push_back("-sbAllowAudio");
+ }
+}
+
+void MacSandboxInfo::AppendWindowServerParam(std::vector<std::string>& aParams) const {
+ if (this->hasWindowServer) {
+ aParams.push_back("-sbAllowWindowServer");
+ }
+}
+
+void MacSandboxInfo::AppendReadPathParams(std::vector<std::string>& aParams) const {
+ if (!this->testingReadPath1.empty()) {
+ aParams.push_back("-sbTestingReadPath");
+ aParams.push_back(this->testingReadPath1.c_str());
+ }
+ if (!this->testingReadPath2.empty()) {
+ aParams.push_back("-sbTestingReadPath");
+ aParams.push_back(this->testingReadPath2.c_str());
+ }
+ if (!this->testingReadPath3.empty()) {
+ aParams.push_back("-sbTestingReadPath");
+ aParams.push_back(this->testingReadPath3.c_str());
+ }
+ if (!this->testingReadPath4.empty()) {
+ aParams.push_back("-sbTestingReadPath");
+ aParams.push_back(this->testingReadPath4.c_str());
+ }
+}
+
+#ifdef DEBUG
+void MacSandboxInfo::AppendDebugWriteDirParam(std::vector<std::string>& aParams) const {
+ if (!this->debugWriteDir.empty()) {
+ aParams.push_back("-sbDebugWriteDir");
+ aParams.push_back(this->debugWriteDir.c_str());
+ }
+}
+#endif
+
+namespace mozilla {
+
+bool StartMacSandbox(MacSandboxInfo const& aInfo, std::string& aErrorMessage) {
+ std::vector<const char*> params;
+ std::string profile;
+
+ // Use a combined version number to simplify version check logic
+ // in sandbox policies. For example, 10.14 becomes "1014".
+ int32_t major = 0, minor = 0;
+ OSXVersion::Get(major, minor);
+ MOZ_ASSERT(minor >= 0 && minor < 100);
+ std::string combinedVersion = std::to_string((major * 100) + minor);
+
+ params.push_back("IS_ROSETTA_TRANSLATED");
+ params.push_back(ProcessIsRosettaTranslated() ? "TRUE" : "FALSE");
+
+ // Used for the Flash sandbox. Declared here so that they
+ // stay in scope until sandbox_init_with_parameters is called.
+ std::string flashCacheDir, flashTempDir, flashPath;
+
+ if (aInfo.type == MacSandboxType_Flash) {
+ profile = SandboxPolicyFlash;
+
+ params.push_back("SHOULD_LOG");
+ params.push_back(aInfo.shouldLog ? "TRUE" : "FALSE");
+
+ params.push_back("SANDBOX_LEVEL_1");
+ params.push_back(aInfo.level == 1 ? "TRUE" : "FALSE");
+ params.push_back("SANDBOX_LEVEL_2");
+ params.push_back(aInfo.level == 2 ? "TRUE" : "FALSE");
+
+ params.push_back("MAC_OS_VERSION");
+ params.push_back(combinedVersion.c_str());
+
+ params.push_back("HOME_PATH");
+ params.push_back(getenv("HOME"));
+
+ params.push_back("PLUGIN_BINARY_PATH");
+ if (!GetRealPath(flashPath, aInfo.pluginBinaryPath.c_str())) {
+ return false;
+ }
+ params.push_back(flashPath.c_str());
+
+ // User cache dir
+ params.push_back("DARWIN_USER_CACHE_DIR");
+ char confStrBuf[PATH_MAX];
+ if (!confstr(_CS_DARWIN_USER_CACHE_DIR, confStrBuf, sizeof(confStrBuf))) {
+ return false;
+ }
+ if (!GetRealPath(flashCacheDir, confStrBuf)) {
+ return false;
+ }
+ params.push_back(flashCacheDir.c_str());
+
+ // User temp dir
+ params.push_back("DARWIN_USER_TEMP_DIR");
+ if (!confstr(_CS_DARWIN_USER_TEMP_DIR, confStrBuf, sizeof(confStrBuf))) {
+ return false;
+ }
+ if (!GetRealPath(flashTempDir, confStrBuf)) {
+ return false;
+ }
+ params.push_back(flashTempDir.c_str());
+ } else if (aInfo.type == MacSandboxType_Utility) {
+ profile = const_cast<char*>(SandboxPolicyUtility);
+ 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_RDD) {
+ profile = const_cast<char*>(SandboxPolicyRDD);
+ params.push_back("SHOULD_LOG");
+ params.push_back(aInfo.shouldLog ? "TRUE" : "FALSE");
+ params.push_back("MAC_OS_VERSION");
+ params.push_back(combinedVersion.c_str());
+ params.push_back("APP_PATH");
+ params.push_back(aInfo.appPath.c_str());
+ params.push_back("HOME_PATH");
+ params.push_back(getenv("HOME"));
+ 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());
+ if (!aInfo.pluginBinaryPath.empty()) {
+ params.push_back("PLUGIN_BINARY_PATH");
+ params.push_back(aInfo.pluginBinaryPath.c_str());
+ }
+ params.push_back("HAS_WINDOW_SERVER");
+ params.push_back(aInfo.hasWindowServer ? "TRUE" : "FALSE");
+ if (!aInfo.crashServerPort.empty()) {
+ params.push_back("CRASH_PORT");
+ params.push_back(aInfo.crashServerPort.c_str());
+ }
+ 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());
+ }
+ } else if (aInfo.type == MacSandboxType_Content) {
+ MOZ_ASSERT(aInfo.level >= 1);
+ if (aInfo.level >= 1) {
+ profile = SandboxPolicyContent;
+ params.push_back("SHOULD_LOG");
+ params.push_back(aInfo.shouldLog ? "TRUE" : "FALSE");
+ params.push_back("SANDBOX_LEVEL_1");
+ params.push_back(aInfo.level == 1 ? "TRUE" : "FALSE");
+ params.push_back("SANDBOX_LEVEL_2");
+ params.push_back(aInfo.level == 2 ? "TRUE" : "FALSE");
+ params.push_back("SANDBOX_LEVEL_3");
+ params.push_back(aInfo.level == 3 ? "TRUE" : "FALSE");
+ params.push_back("MAC_OS_VERSION");
+ params.push_back(combinedVersion.c_str());
+ params.push_back("APP_PATH");
+ params.push_back(aInfo.appPath.c_str());
+ 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_WINDOW_SERVER");
+ params.push_back(aInfo.hasWindowServer ? "TRUE" : "FALSE");
+ if (!aInfo.crashServerPort.empty()) {
+ params.push_back("CRASH_PORT");
+ params.push_back(aInfo.crashServerPort.c_str());
+ }
+ 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());
+ }
+ if (!aInfo.testingReadPath4.empty()) {
+ params.push_back("TESTING_READ_PATH4");
+ params.push_back(aInfo.testingReadPath4.c_str());
+ }
+#ifdef DEBUG
+ if (!aInfo.debugWriteDir.empty()) {
+ params.push_back("DEBUG_WRITE_DIR");
+ params.push_back(aInfo.debugWriteDir.c_str());
+ }
+#endif // DEBUG
+
+ if (aInfo.hasFilePrivileges) {
+ profile.append(SandboxPolicyContentFileAddend);
+ }
+ if (aInfo.hasAudio) {
+ profile.append(SandboxPolicyContentAudioAddend);
+ }
+ } else {
+ fprintf(stderr, "Content sandbox disabled due to sandbox level setting\n");
+ return false;
+ }
+ } else {
+ char* msg = NULL;
+ asprintf(&msg, "Unexpected sandbox type %u", aInfo.type);
+ if (msg) {
+ aErrorMessage.assign(msg);
+ free(msg);
+ }
+ return false;
+ }
+
+ if (profile.empty()) {
+ fprintf(stderr, "Out of memory in StartMacSandbox()!\n");
+ return false;
+ }
+
+// 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 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);
+
+ char* errorbuf = NULL;
+ int rv = sandbox_init_with_parameters(profile.c_str(), 0, params.data(), &errorbuf);
+ if (rv) {
+ if (errorbuf) {
+ char* msg = NULL;
+ asprintf(&msg, "sandbox_init() failed with error \"%s\"", errorbuf);
+ if (msg) {
+ aErrorMessage.assign(msg);
+ free(msg);
+ }
+ fprintf(stderr, "profile: %s\n", profile.c_str());
+ sandbox_free_error(errorbuf);
+ }
+ }
+ if (rv) {
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ * Fill |aInfo| with content sandbox params parsed from the provided
+ * command line arguments. Return false if any sandbox parameters needed
+ * for early startup of the sandbox are not present in the arguments.
+ */
+bool GetContentSandboxParamsFromArgs(int aArgc, char** aArgv, MacSandboxInfo& aInfo) {
+ // Ensure we find these paramaters in the command
+ // line arguments. Return false if any are missing.
+ bool foundSandboxLevel = false;
+ bool foundValidSandboxLevel = false;
+ bool foundAppPath = false;
+
+ // Read access directories used in testing
+ int nTestingReadPaths = 0;
+ std::string testingReadPaths[MAX_CONTENT_TESTING_READ_PATHS] = {};
+
+ // Collect sandbox params from CLI arguments
+ for (int i = 0; i < aArgc; i++) {
+ if ((strcmp(aArgv[i], "-sbLevel") == 0) && (i + 1 < aArgc)) {
+ std::stringstream ss(aArgv[i + 1]);
+ int level = 0;
+ ss >> level;
+ foundSandboxLevel = true;
+ aInfo.level = level;
+ foundValidSandboxLevel = level > 0 && level <= 3 ? true : false;
+ if (!foundValidSandboxLevel) {
+ break;
+ }
+ i++;
+ continue;
+ }
+
+ if (strcmp(aArgv[i], "-sbLogging") == 0) {
+ aInfo.shouldLog = true;
+ continue;
+ }
+
+ if (strcmp(aArgv[i], "-sbAllowFileAccess") == 0) {
+ aInfo.hasFilePrivileges = true;
+ continue;
+ }
+
+ if (strcmp(aArgv[i], "-sbAllowAudio") == 0) {
+ aInfo.hasAudio = true;
+ continue;
+ }
+
+ if (strcmp(aArgv[i], "-sbAllowWindowServer") == 0) {
+ aInfo.hasWindowServer = true;
+ continue;
+ }
+
+ if ((strcmp(aArgv[i], "-sbAppPath") == 0) && (i + 1 < aArgc)) {
+ foundAppPath = true;
+ aInfo.appPath.assign(aArgv[i + 1]);
+ i++;
+ continue;
+ }
+
+ if ((strcmp(aArgv[i], "-sbTestingReadPath") == 0) && (i + 1 < aArgc)) {
+ if (nTestingReadPaths >= MAX_CONTENT_TESTING_READ_PATHS) {
+ MOZ_CRASH("Too many content process -sbTestingReadPath arguments");
+ }
+ testingReadPaths[nTestingReadPaths] = aArgv[i + 1];
+ nTestingReadPaths++;
+ i++;
+ continue;
+ }
+
+ if ((strcmp(aArgv[i], "-profile") == 0) && (i + 1 < aArgc)) {
+ aInfo.hasSandboxedProfile = true;
+ aInfo.profileDir.assign(aArgv[i + 1]);
+ i++;
+ continue;
+ }
+
+#ifdef DEBUG
+ if ((strcmp(aArgv[i], "-sbDebugWriteDir") == 0) && (i + 1 < aArgc)) {
+ aInfo.debugWriteDir.assign(aArgv[i + 1]);
+ i++;
+ continue;
+ }
+#endif // DEBUG
+
+ // Handle crash server positional argument
+ if (strstr(aArgv[i], "gecko-crash-server-pipe") != NULL) {
+ aInfo.crashServerPort.assign(aArgv[i]);
+ continue;
+ }
+ }
+
+ if (!foundSandboxLevel) {
+ fprintf(stderr, "Content sandbox disabled due to "
+ "missing sandbox CLI level parameter.\n");
+ return false;
+ }
+
+ if (!foundValidSandboxLevel) {
+ fprintf(stderr,
+ "Content sandbox disabled due to invalid"
+ "sandbox level (%d)\n",
+ aInfo.level);
+ return false;
+ }
+
+ if (!foundAppPath) {
+ fprintf(stderr, "Content sandbox disabled due to "
+ "missing sandbox CLI app path parameter.\n");
+ return false;
+ }
+
+ aInfo.testingReadPath1 = testingReadPaths[0];
+ aInfo.testingReadPath2 = testingReadPaths[1];
+ aInfo.testingReadPath3 = testingReadPaths[2];
+ aInfo.testingReadPath4 = testingReadPaths[3];
+
+ return true;
+}
+
+bool GetUtilitySandboxParamsFromArgs(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;
+
+ // Collect sandbox params from CLI arguments
+ for (int i = 0; i < aArgc; i++) {
+ if (strcmp(aArgv[i], "-sbLogging") == 0) {
+ aInfo.shouldLog = true;
+ continue;
+ }
+
+ if ((strcmp(aArgv[i], "-sbAppPath") == 0) && (i + 1 < aArgc)) {
+ foundAppPath = true;
+ aInfo.appPath.assign(aArgv[i + 1]);
+ i++;
+ continue;
+ }
+
+ // Handle crash server positional argument
+ if (strstr(aArgv[i], "gecko-crash-server-pipe") != NULL) {
+ aInfo.crashServerPort.assign(aArgv[i]);
+ continue;
+ }
+ }
+
+ if (!foundAppPath) {
+ 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;
+ std::string testingReadPaths[MAX_GMP_TESTING_READ_PATHS] = {};
+
+ // Collect sandbox params from CLI arguments
+ for (int i = 0; i < aArgc; i++) {
+ if (strcmp(aArgv[i], "-sbLogging") == 0) {
+ aInfo.shouldLog = true;
+ continue;
+ }
+
+ if ((strcmp(aArgv[i], "-sbAppPath") == 0) && (i + 1 < aArgc)) {
+ foundAppPath = true;
+ aInfo.appPath.assign(aArgv[i + 1]);
+ i++;
+ continue;
+ }
+
+ if ((strcmp(aArgv[i], "-sbPluginPath") == 0) && (i + 1 < aArgc)) {
+ foundPluginPath = true;
+ aInfo.pluginPath.assign(aArgv[i + 1]);
+ i++;
+ continue;
+ }
+
+ if (strcmp(aArgv[i], "-sbAllowWindowServer") == 0) {
+ aInfo.hasWindowServer = true;
+ continue;
+ }
+
+ if ((strcmp(aArgv[i], "-sbTestingReadPath") == 0) && (i + 1 < aArgc)) {
+ if (nTestingReadPaths >= MAX_GMP_TESTING_READ_PATHS) {
+ MOZ_CRASH("Too many GMP process -sbTestingReadPath arguments");
+ }
+ testingReadPaths[nTestingReadPaths] = aArgv[i + 1];
+ nTestingReadPaths++;
+ i++;
+ continue;
+ }
+
+ // Handle crash server positional argument
+ if (strstr(aArgv[i], "gecko-crash-server-pipe") != NULL) {
+ aInfo.crashServerPort.assign(aArgv[i]);
+ continue;
+ }
+ }
+
+ if (!foundPluginPath) {
+ fprintf(stderr, "GMP sandbox disabled due to "
+ "missing sandbox CLI plugin path parameter.\n");
+ return false;
+ }
+
+ if (!foundAppPath) {
+ fprintf(stderr, "GMP sandbox disabled due to "
+ "missing sandbox CLI app path parameter.\n");
+ return false;
+ }
+
+ aInfo.testingReadPath1 = testingReadPaths[0];
+ aInfo.testingReadPath2 = testingReadPaths[1];
+
+ return true;
+}
+
+bool GetRDDSandboxParamsFromArgs(int aArgc, char** aArgv, MacSandboxInfo& aInfo) {
+ return GetUtilitySandboxParamsFromArgs(aArgc, aArgv, aInfo);
+}
+
+/*
+ * Returns true if no errors were encountered or if early sandbox startup is
+ * not enabled for this process. Returns false if an error was encountered.
+ */
+bool StartMacSandboxIfEnabled(const MacSandboxType aSandboxType, int aArgc, char** aArgv,
+ std::string& aErrorMessage) {
+ bool earlyStartupEnabled = false;
+
+ // Check for the -sbStartup CLI parameter which
+ // indicates we should start the sandbox now.
+ for (int i = 0; i < aArgc; i++) {
+ if (strcmp(aArgv[i], "-sbStartup") == 0) {
+ earlyStartupEnabled = true;
+ break;
+ }
+ }
+
+ // The sandbox will be started later when/if parent
+ // sends the sandbox startup message. Return true
+ // indicating no errors occurred.
+ if (!earlyStartupEnabled) {
+ return true;
+ }
+
+ MacSandboxInfo info;
+ info.type = aSandboxType;
+
+ // For now, early start is only implemented
+ // for content and utility sandbox types.
+ switch (aSandboxType) {
+ case MacSandboxType_Content:
+ if (!GetContentSandboxParamsFromArgs(aArgc, aArgv, info)) {
+ return false;
+ }
+ break;
+ case MacSandboxType_GMP:
+ if (!GetPluginSandboxParamsFromArgs(aArgc, aArgv, info)) {
+ return false;
+ }
+ break;
+ case MacSandboxType_RDD:
+ if (!GetRDDSandboxParamsFromArgs(aArgc, aArgv, info)) {
+ return false;
+ }
+ break;
+ case MacSandboxType_Socket:
+ if (!GetSocketSandboxParamsFromArgs(aArgc, aArgv, info)) {
+ return false;
+ }
+ break;
+ case MacSandboxType_Utility:
+ if (!GetUtilitySandboxParamsFromArgs(aArgc, aArgv, info)) {
+ return false;
+ }
+ break;
+ default:
+ MOZ_RELEASE_ASSERT(false);
+ break;
+ }
+
+ return StartMacSandbox(info, aErrorMessage);
+}
+
+bool IsMacSandboxStarted() { return sandbox_check(getpid(), NULL, 0) == 1; }
+
+#ifdef DEBUG
+// sandbox_check returns 1 if the specified process is sandboxed
+void AssertMacSandboxEnabled() { MOZ_ASSERT(sandbox_check(getpid(), NULL, 0) == 1); }
+#endif /* DEBUG */
+
+} // namespace mozilla
diff --git a/security/sandbox/mac/SandboxPolicyContent.h b/security/sandbox/mac/SandboxPolicyContent.h
new file mode 100644
index 0000000000..d9e09f3d1c
--- /dev/null
+++ b/security/sandbox/mac/SandboxPolicyContent.h
@@ -0,0 +1,396 @@
+/* -*- 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_SandboxPolicyContent_h
+#define mozilla_SandboxPolicyContent_h
+
+#define MAX_CONTENT_TESTING_READ_PATHS 4
+
+namespace mozilla {
+
+static const char SandboxPolicyContent[] = R"SANDBOX_LITERAL(
+ (version 1)
+
+ (define should-log (param "SHOULD_LOG"))
+ (define sandbox-level-1 (param "SANDBOX_LEVEL_1"))
+ (define sandbox-level-2 (param "SANDBOX_LEVEL_2"))
+ (define sandbox-level-3 (param "SANDBOX_LEVEL_3"))
+ (define macosVersion (string->number (param "MAC_OS_VERSION")))
+ (define appPath (param "APP_PATH"))
+ (define hasProfileDir (param "HAS_SANDBOXED_PROFILE"))
+ (define profileDir (param "PROFILE_DIR"))
+ (define hasWindowServer (param "HAS_WINDOW_SERVER"))
+ (define home-path (param "HOME_PATH"))
+ (define debugWriteDir (param "DEBUG_WRITE_DIR"))
+ (define testingReadPath1 (param "TESTING_READ_PATH1"))
+ (define testingReadPath2 (param "TESTING_READ_PATH2"))
+ (define testingReadPath3 (param "TESTING_READ_PATH3"))
+ (define testingReadPath4 (param "TESTING_READ_PATH4"))
+ (define crashPort (param "CRASH_PORT"))
+ (define isRosettaTranslated (param "IS_ROSETTA_TRANSLATED"))
+
+ (define (moz-deny feature)
+ (if (string=? should-log "TRUE")
+ (deny feature)
+ (deny feature (with no-log))))
+
+ (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*))
+ ; The next two properties both require macOS 10.10+
+ (if (defined? 'iokit-get-properties)
+ (moz-deny iokit-get-properties))
+ (if (defined? 'file-map-executable)
+ (moz-deny file-map-executable))
+
+ (if (string=? should-log "TRUE")
+ (debug deny))
+
+ (if (defined? 'file-map-executable)
+ (begin
+ (if (string=? isRosettaTranslated "TRUE")
+ (allow file-map-executable (subpath "/private/var/db/oah")))
+ (allow file-map-executable file-read*
+ (subpath "/System")
+ (subpath "/usr/lib")
+ (subpath "/Library/GPUBundles")
+ (subpath appPath)))
+ (allow file-read*
+ (subpath "/System")
+ (subpath "/usr/lib")
+ (subpath "/Library/GPUBundles")
+ (subpath appPath)))
+
+ ; Allow read access to standard system paths.
+ (allow file-read*
+ (require-all (file-mode #o0004)
+ (require-any
+ (subpath "/Library/Filesystems/NetFSPlugins")
+ (subpath "/usr/share"))))
+
+ ; 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"))
+
+ ; Allow read access to standard special files.
+ (allow file-read*
+ (literal "/dev/autofs_nowait")
+ (literal "/dev/random")
+ (literal "/dev/urandom"))
+
+ (allow file-read*
+ file-write-data
+ (literal "/dev/null")
+ (literal "/dev/zero"))
+
+ (allow file-read*
+ file-write-data
+ file-ioctl
+ (literal "/dev/dtracehelper"))
+
+ ; Needed for things like getpriority()/setpriority()
+ (allow process-info-pidinfo process-info-setcontrol (target self))
+
+ (allow sysctl-read
+ (sysctl-name-regex #"^sysctl\.")
+ (sysctl-name "kern.ostype")
+ (sysctl-name "kern.osversion")
+ (sysctl-name "kern.osrelease")
+ (sysctl-name "kern.version")
+ (sysctl-name "kern.tcsm_available")
+ (sysctl-name "kern.tcsm_enable")
+ ; TODO: remove "kern.hostname". Without it the tests hang, but the hostname
+ ; is arguably sensitive information, so we should see what can be done about
+ ; removing it.
+ (sysctl-name "kern.hostname")
+ (sysctl-name "hw.machine")
+ (sysctl-name "hw.memsize")
+ (sysctl-name "hw.model")
+ (sysctl-name "hw.ncpu")
+ (sysctl-name "hw.activecpu")
+ (sysctl-name "hw.byteorder")
+ (sysctl-name "hw.pagesize_compat")
+ (sysctl-name "hw.logicalcpu_max")
+ (sysctl-name "hw.physicalcpu_max")
+ (sysctl-name "hw.busfrequency_compat")
+ (sysctl-name "hw.busfrequency_max")
+ (sysctl-name "hw.cpufrequency")
+ (sysctl-name "hw.cpufrequency_compat")
+ (sysctl-name "hw.cpufrequency_max")
+ (sysctl-name "hw.l2cachesize")
+ (sysctl-name "hw.l3cachesize")
+ (sysctl-name "hw.cachelinesize")
+ (sysctl-name "hw.cachelinesize_compat")
+ (sysctl-name "hw.tbfrequency_compat")
+ (sysctl-name "hw.vectorunit")
+ (sysctl-name "hw.optional.sse2")
+ (sysctl-name "hw.optional.sse3")
+ (sysctl-name "hw.optional.sse4_1")
+ (sysctl-name "hw.optional.sse4_2")
+ (sysctl-name "hw.optional.avx1_0")
+ (sysctl-name "hw.optional.avx2_0")
+ (sysctl-name "hw.optional.avx512f")
+ (sysctl-name "machdep.cpu.vendor")
+ (sysctl-name "machdep.cpu.family")
+ (sysctl-name "machdep.cpu.model")
+ (sysctl-name "machdep.cpu.stepping")
+ (sysctl-name "debug.intel.gstLevelGST")
+ (sysctl-name "debug.intel.gstLoaderControl"))
+ (allow sysctl-write
+ (sysctl-name "kern.tcsm_enable"))
+
+ (define (home-regex home-relative-regex)
+ (regex (string-append "^" (regex-quote home-path) home-relative-regex)))
+ (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 (profile-subpath profile-relative-subpath)
+ (subpath (string-append profileDir profile-relative-subpath)))
+
+ (define (allow-shared-list domain)
+ (allow file-read*
+ (home-regex (string-append "/Library/Preferences/" (regex-quote domain)))))
+
+ (allow ipc-posix-shm-read-data ipc-posix-shm-write-data
+ (ipc-posix-name-regex #"^CFPBS:"))
+
+ (allow signal (target self))
+ (if (string? crashPort)
+ (allow mach-lookup (global-name crashPort)))
+ (if (string=? hasWindowServer "TRUE")
+ (allow mach-lookup (global-name "com.apple.windowserver.active")))
+ (allow mach-lookup
+ (global-name "com.apple.system.opendirectoryd.libinfo")
+ (global-name "com.apple.CoreServices.coreservicesd")
+ (global-name "com.apple.coreservices.launchservicesd")
+ (global-name "com.apple.lsd.mapdb"))
+
+ (if (>= macosVersion 1013)
+ (allow mach-lookup
+ ; bug 1392988
+ (xpc-service-name "com.apple.coremedia.videodecoder")
+ (xpc-service-name "com.apple.coremedia.videoencoder")))
+
+ (if (>= macosVersion 1100)
+ (allow mach-lookup
+ ; bug 1655655
+ (global-name "com.apple.trustd.agent")))
+
+ (allow iokit-open
+ (iokit-user-client-class "IOHIDParamUserClient"))
+
+ ; Only supported on macOS 10.10+
+ (if (defined? 'iokit-get-properties)
+ (allow iokit-get-properties
+ (iokit-property "board-id")
+ (iokit-property "class-code")
+ (iokit-property "vendor-id")
+ (iokit-property "device-id")
+ (iokit-property "IODVDBundleName")
+ (iokit-property "IOGLBundleName")
+ (iokit-property "IOGVACodec")
+ (iokit-property "IOGVAHEVCDecode")
+ (iokit-property "IOGVAHEVCEncode")
+ (iokit-property "IOGVAXDecode")
+ (iokit-property "IOPCITunnelled")
+ (iokit-property "IOVARendererID")
+ (iokit-property "MetalPluginName")
+ (iokit-property "MetalPluginClassName")))
+
+ ; depending on systems, the 1st, 2nd or both rules are necessary
+ (allow user-preference-read (preference-domain "com.apple.HIToolbox"))
+ (allow file-read-data (literal "/Library/Preferences/com.apple.HIToolbox.plist"))
+
+ (allow user-preference-read (preference-domain "com.apple.ATS"))
+
+ ; Needed for some global preferences (such as scrolling behavior)
+ (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 mach-lookup
+ (global-name "com.apple.cfprefsd.agent")
+ (global-name "com.apple.cfprefsd.daemon"))
+ (allow ipc-posix-shm-read-data
+ (ipc-posix-name-regex #"^apple\.cfprefs\..*"))
+
+ (allow file-read*
+ (subpath "/Library/ColorSync/Profiles")
+ (subpath "/Library/Spelling")
+ (literal "/")
+ (literal "/private/tmp")
+ (literal "/private/var/tmp")
+ (home-literal "/.CFUserTextEncoding")
+ (home-literal "/Library/Preferences/com.apple.DownloadAssessment.plist")
+ (home-subpath "/Library/Colors")
+ (home-subpath "/Library/ColorSync/Profiles")
+ (home-subpath "/Library/Keyboard Layouts")
+ (home-subpath "/Library/Input Methods")
+ (home-subpath "/Library/Spelling"))
+
+ (if (defined? 'file-map-executable)
+ (begin
+ (when testingReadPath1
+ (allow file-read* file-map-executable (subpath testingReadPath1)))
+ (when testingReadPath2
+ (allow file-read* file-map-executable (subpath testingReadPath2)))
+ (when testingReadPath3
+ (allow file-read* file-map-executable (subpath testingReadPath3)))
+ (when testingReadPath4
+ (allow file-read* file-map-executable (subpath testingReadPath4))))
+ (begin
+ (when testingReadPath1
+ (allow file-read* (subpath testingReadPath1)))
+ (when testingReadPath2
+ (allow file-read* (subpath testingReadPath2)))
+ (when testingReadPath3
+ (allow file-read* (subpath testingReadPath3)))
+ (when testingReadPath4
+ (allow file-read* (subpath testingReadPath4)))))
+
+ ; bug 1303987
+ (if (string? debugWriteDir)
+ (begin
+ (allow file-write-data (subpath debugWriteDir))
+ (allow file-write-create
+ (require-all
+ (subpath debugWriteDir)
+ (vnode-type REGULAR-FILE)))))
+
+ (allow-shared-list "org.mozilla.plugincontainer")
+
+; Per-user and system-wide Extensions dir
+ (allow file-read*
+ (home-regex "/Library/Application Support/[^/]+/Extensions/")
+ (regex "^/Library/Application Support/[^/]+/Extensions/"))
+
+; bug 1393805
+ (allow file-read*
+ (home-subpath "/Library/Application Support/Mozilla/SystemExtensionsDev"))
+
+; The following rules impose file access restrictions which get
+; more restrictive in higher levels. When file-origin-specific
+; content processes are used for file:// origin browsing, the
+; global file-read* permission should be removed from each level.
+
+; level 1: global read access permitted, no global write access
+ (if (string=? sandbox-level-1 "TRUE") (allow file-read*))
+
+; level 2: global read access permitted, no global write access,
+; no read/write access to ~/Library,
+; no read/write access to $PROFILE,
+; read access permitted to $PROFILE/{extensions,chrome}
+ (if (string=? sandbox-level-2 "TRUE")
+ (begin
+ ; bug 1201935
+ (allow file-read* (home-subpath "/Library/Caches/TemporaryItems"))
+ (if (string=? hasProfileDir "TRUE")
+ ; we have a profile dir
+ (allow file-read* (require-all
+ (require-not (home-subpath "/Library"))
+ (require-not (subpath profileDir))))
+ ; we don't have a profile dir
+ (allow file-read* (require-not (home-subpath "/Library"))))))
+
+ ; level 3: Does not have any of it's own rules. The global rules provide:
+ ; no global read/write access,
+ ; read access permitted to $PROFILE/{extensions,chrome}
+
+ (if (string=? hasProfileDir "TRUE")
+ ; we have a profile dir
+ (allow file-read*
+ (profile-subpath "/extensions")
+ (profile-subpath "/chrome")))
+
+; accelerated graphics
+ (allow user-preference-read (preference-domain "com.apple.opengl"))
+ (allow user-preference-read (preference-domain "com.nvidia.OpenGL"))
+ (allow mach-lookup
+ (global-name "com.apple.cvmsServ"))
+ (if (>= macosVersion 1014)
+ (allow mach-lookup
+ (global-name "com.apple.MTLCompilerService")))
+ (allow iokit-open
+ (iokit-connection "IOAccelerator")
+ (iokit-user-client-class "IOAccelerationUserClient")
+ (iokit-user-client-class "IOSurfaceRootUserClient")
+ (iokit-user-client-class "IOSurfaceSendRight")
+ (iokit-user-client-class "IOFramebufferSharedUserClient")
+ (iokit-user-client-class "AGPMClient")
+ (iokit-user-client-class "AppleGraphicsControlClient"))
+
+; bug 1153809
+ (allow iokit-open
+ (iokit-user-client-class "NVDVDContextTesla")
+ (iokit-user-client-class "Gen6DVDContext"))
+
+ ; Fonts
+ (allow file-read*
+ (subpath "/Library/Fonts")
+ (subpath "/Library/Application Support/Apple/Fonts")
+ (home-subpath "/Library/Fonts")
+ ; Allow read access to paths allowed via sandbox extensions.
+ ; This is needed for fonts in non-standard locations normally
+ ; due to third party font managers. The extensions are
+ ; automatically issued by the font server in response to font
+ ; API calls.
+ (extension "com.apple.app-sandbox.read"))
+ ; Fonts may continue to work without explicitly allowing these
+ ; services because, at present, connections are made to the services
+ ; before the sandbox is enabled as a side-effect of some API calls.
+ (allow mach-lookup
+ (global-name "com.apple.fonts")
+ (global-name "com.apple.FontObjectsServer"))
+
+ (if (>= macosVersion 1013)
+ (allow mach-lookup
+ ; bug 1565575
+ (global-name "com.apple.audio.AudioComponentRegistrar")))
+)SANDBOX_LITERAL";
+
+// These are additional rules that are added to the content process rules for
+// file content processes.
+static const char SandboxPolicyContentFileAddend[] = R"SANDBOX_LITERAL(
+ ; This process has blanket file read privileges
+ (allow file-read*)
+
+ ; File content processes need access to iconservices to draw file icons in
+ ; directory listings
+ (allow mach-lookup (global-name "com.apple.iconservices"))
+)SANDBOX_LITERAL";
+
+// These are additional rules that are added to the content process rules when
+// audio remoting is not enabled. (Once audio remoting is always used these
+// will be deleted.)
+static const char SandboxPolicyContentAudioAddend[] = R"SANDBOX_LITERAL(
+ (allow ipc-posix-shm-read* ipc-posix-shm-write-data
+ (ipc-posix-name-regex #"^AudioIO"))
+
+ (allow mach-lookup
+ (global-name "com.apple.audio.coreaudiod")
+ (global-name "com.apple.audio.audiohald"))
+
+ (allow iokit-open (iokit-user-client-class "IOAudioEngineUserClient"))
+
+ (allow file-read* (subpath "/Library/Audio/Plug-Ins"))
+
+ (allow device-microphone)
+)SANDBOX_LITERAL";
+
+} // namespace mozilla
+
+#endif // mozilla_SandboxPolicyContent_h
diff --git a/security/sandbox/mac/SandboxPolicyFlash.h b/security/sandbox/mac/SandboxPolicyFlash.h
new file mode 100644
index 0000000000..242c8f14c7
--- /dev/null
+++ b/security/sandbox/mac/SandboxPolicyFlash.h
@@ -0,0 +1,407 @@
+/* -*- 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_SandboxPolicyFlash_h
+#define mozilla_SandboxPolicyFlash_h
+
+namespace mozilla {
+
+// Flash NPAPI plugin process profile
+static const char SandboxPolicyFlash[] = R"SANDBOX_LITERAL(
+ (version 1)
+
+ ; Parameters
+ (define shouldLog (param "SHOULD_LOG"))
+ (define sandbox-level-1 (param "SANDBOX_LEVEL_1"))
+ (define sandbox-level-2 (param "SANDBOX_LEVEL_2"))
+ (define macosVersion (string->number (param "MAC_OS_VERSION")))
+ (define homeDir (param "HOME_PATH"))
+ (define tempDir (param "DARWIN_USER_TEMP_DIR"))
+ (define cacheDir (param "DARWIN_USER_CACHE_DIR"))
+ (define pluginPath (param "PLUGIN_BINARY_PATH"))
+
+ (if (string=? shouldLog "TRUE")
+ (deny default)
+ (deny default (with no-log)))
+ (debug deny)
+ (allow system-audit file-read-metadata)
+ ; These are not included in (deny default)
+ (deny process-info*)
+ ; This isn't available in some older macOS releases.
+ (if (defined? 'nvram*)
+ (deny nvram*))
+
+ ; Allow read access to standard system paths.
+ (allow file-read*
+ (require-all (file-mode #o0004)
+ (require-any
+ (subpath "/System")
+ (subpath "/usr/lib")
+ (subpath "/Library/Filesystems/NetFSPlugins")
+ (subpath "/Library/GPUBundles")
+ (subpath "/usr/share"))))
+ (allow file-read-metadata
+ (literal "/etc")
+ (literal "/tmp")
+ (literal "/var"))
+ (allow file-read*
+ (literal "/dev/autofs_nowait")
+ (literal "/dev/random")
+ (literal "/dev/urandom"))
+ (allow file-read*
+ file-write-data
+ (literal "/dev/null")
+ (literal "/dev/zero"))
+ (allow file-read*
+ file-write-data
+ file-ioctl
+ (literal "/dev/dtracehelper"))
+
+ ; Timezone
+ (allow file-read*
+ (subpath "/private/var/db/timezone")
+ (subpath "/usr/share/zoneinfo")
+ (subpath "/usr/share/zoneinfo.default")
+ (literal "/private/etc/localtime"))
+
+ ; Graphics
+ (allow user-preference-read
+ (preference-domain "com.apple.opengl")
+ (preference-domain "com.nvidia.OpenGL"))
+ (allow mach-lookup
+ (global-name "com.apple.cvmsServ"))
+ (allow iokit-open
+ (iokit-connection "IOAccelerator")
+ (iokit-user-client-class "IOAccelerationUserClient")
+ (iokit-user-client-class "IOSurfaceRootUserClient")
+ (iokit-user-client-class "IOSurfaceSendRight"))
+ (allow iokit-open
+ (iokit-user-client-class "AppleIntelMEUserClient")
+ (iokit-user-client-class "AppleSNBFBUserClient"))
+ (allow iokit-open
+ (iokit-user-client-class "AGPMClient")
+ (iokit-user-client-class "AppleGraphicsControlClient")
+ (iokit-user-client-class "AppleGraphicsPolicyClient"))
+ ; Camera access
+ (allow iokit-open
+ (iokit-user-client-class "IOUSBDeviceUserClientV2")
+ (iokit-user-client-class "IOUSBInterfaceUserClientV2"))
+
+ ; Network
+ (allow file-read*
+ (literal "/Library/Preferences/com.apple.networkd.plist"))
+ (allow mach-lookup
+ (global-name "com.apple.SystemConfiguration.PPPController")
+ (global-name "com.apple.SystemConfiguration.SCNetworkReachability")
+ (global-name "com.apple.nehelper")
+ (global-name "com.apple.networkd")
+ (global-name "com.apple.nsurlstorage-cache")
+ (global-name "com.apple.symptomsd")
+ (global-name "com.apple.usymptomsd"))
+ (allow network-outbound
+ (control-name "com.apple.netsrc")
+ (control-name "com.apple.network.statistics"))
+ (allow system-socket
+ (require-all (socket-domain AF_SYSTEM)
+ (socket-protocol 2)) ; SYSPROTO_CONTROL
+ (socket-domain AF_ROUTE))
+ (allow network-outbound
+ (literal "/private/var/run/mDNSResponder")
+ (literal "/private/var/run/asl_input")
+ (literal "/private/var/run/syslog")
+ (remote tcp)
+ (remote udp))
+ (allow network-inbound
+ (local udp))
+
+ (allow process-info-pidinfo)
+ (allow process-info-setcontrol (target self))
+
+ (allow sysctl-read
+ (sysctl-name
+ "hw.activecpu"
+ "hw.availcpu"
+ "hw.busfrequency_max"
+ "hw.cpu64bit_capable"
+ "hw.cputype"
+ "hw.physicalcpu_max"
+ "hw.logicalcpu_max"
+ "hw.machine"
+ "hw.model"
+ "hw.ncpu"
+ "hw.optional.avx1_0"
+ "hw.optional.avx2_0"
+ "hw.optional.sse2"
+ "hw.optional.sse3"
+ "hw.optional.sse4_1"
+ "hw.optional.sse4_2"
+ "hw.optional.x86_64"
+ "kern.hostname"
+ "kern.maxfilesperproc"
+ "kern.memorystatus_level"
+ "kern.osrelease"
+ "kern.ostype"
+ "kern.osvariant_status"
+ "kern.osversion"
+ "kern.safeboot"
+ "kern.version"
+ "vm.footprint_suspend"))
+
+ ; Utilities for allowing access to home subdirectories
+ (define home-library-path
+ (string-append homeDir "/Library"))
+
+ (define (home-subpath home-relative-subpath)
+ (subpath (string-append homeDir home-relative-subpath)))
+
+ (define home-library-prefs-path
+ (string-append homeDir "/Library" "/Preferences"))
+
+ (define (home-literal home-relative-literal)
+ (literal (string-append homeDir home-relative-literal)))
+
+ (define (home-library-regex home-library-relative-regex)
+ (regex (string-append "^" (regex-quote home-library-path))
+ home-library-relative-regex))
+
+ (define (home-library-subpath home-library-relative-subpath)
+ (subpath (string-append home-library-path home-library-relative-subpath)))
+
+ (define (home-library-literal home-library-relative-literal)
+ (literal (string-append home-library-path home-library-relative-literal)))
+
+ (define (home-library-preferences-literal
+ home-library-preferences-relative-literal)
+ (literal (string-append home-library-prefs-path
+ home-library-preferences-relative-literal)))
+
+ ; Utility for allowing access to a temp dir subdirectory
+ (define (tempDir-regex tempDir-relative-regex)
+ (regex (string-append "^" (regex-quote tempDir)) tempDir-relative-regex))
+
+ ; Utility for allowing access to specific files within the cache dir
+ (define (cache-literal cache-relative-literal)
+ (literal (string-append cacheDir cache-relative-literal)))
+
+ ; Read-only paths
+ (allow file-read*
+ (literal "/")
+ (literal "/private/etc/services")
+ (literal "/private/etc/resolv.conf")
+ (literal "/private/var/run/resolv.conf")
+ (subpath "/Library/Frameworks")
+ (subpath "/Library/Managed Preferences")
+ (home-literal "/.CFUserTextEncoding")
+ (home-library-subpath "/Audio")
+ (home-library-subpath "/ColorPickers")
+ (home-library-subpath "/ColorSync")
+ (subpath "/Library/Components")
+ (home-library-subpath "/Components")
+ (subpath "/Library/Contextual Menu Items")
+ (subpath "/Library/Input Methods")
+ (home-library-subpath "/Input Methods")
+ (subpath "/Library/InputManagers")
+ (home-library-subpath "/InputManagers")
+ (home-library-subpath "/KeyBindings")
+ (subpath "/Library/Keyboard Layouts")
+ (home-library-subpath "/Keyboard Layouts")
+ (subpath "/Library/Spelling")
+ (home-library-subpath "/Spelling")
+ (home-library-literal "/Caches/com.apple.coreaudio.components.plist")
+ (subpath "/Library/Audio/Sounds")
+ (subpath "/Library/Audio/Plug-Ins/Components")
+ (home-library-subpath "/Audio/Plug-Ins/Components")
+ (subpath "/Library/Audio/Plug-Ins/HAL")
+ (subpath "/Library/CoreMediaIO/Plug-Ins/DAL")
+ (subpath "/Library/QuickTime")
+ (home-library-subpath "/QuickTime")
+ (subpath "/Library/Video/Plug-Ins")
+ (home-library-subpath "/Caches/QuickTime")
+ (subpath "/Library/ColorSync")
+ (home-literal "/Library/Preferences/com.apple.lookup.shared.plist"))
+
+ (allow iokit-open
+ (iokit-user-client-class "IOAudioControlUserClient")
+ (iokit-user-client-class "IOAudioEngineUserClient")
+ (iokit-user-client-class "IOHIDParamUserClient")
+ (iokit-user-client-class "RootDomainUserClient"))
+
+ ; Services
+ (allow mach-lookup
+ (global-name "com.apple.audio.AudioComponentRegistrar")
+ (global-name "com.apple.DiskArbitration.diskarbitrationd")
+ (global-name "com.apple.ImageCaptureExtension2.presence")
+ (global-name "com.apple.PowerManagement.control")
+ (global-name "com.apple.SecurityServer")
+ (global-name "com.apple.SystemConfiguration.PPPController")
+ (global-name "com.apple.SystemConfiguration.configd")
+ (global-name "com.apple.UNCUserNotification")
+ (global-name "com.apple.audio.audiohald")
+ (global-name "com.apple.audio.coreaudiod")
+ (global-name "com.apple.cfnetwork.AuthBrokerAgent")
+ (global-name "com.apple.lsd.mapdb")
+ (global-name "com.apple.pasteboard.1") ; Allows paste into input field
+ (global-name "com.apple.dock.server")
+ (global-name "com.apple.dock.fullscreen")
+ (global-name "com.apple.coreservices.appleevents")
+ (global-name "com.apple.coreservices.launchservicesd")
+ (global-name "com.apple.window_proxies")
+ (local-name "com.apple.tsm.portname")
+ (global-name "com.apple.axserver")
+ (global-name "com.apple.pbs.fetch_services")
+ (global-name "com.apple.tsm.uiserver")
+ (global-name "com.apple.inputmethodkit.launchagent")
+ (global-name "com.apple.inputmethodkit.launcher")
+ (global-name "com.apple.inputmethodkit.getxpcendpoint")
+ (global-name "com.apple.decalog4.incoming")
+ (global-name "com.apple.windowserver.active")
+ (global-name "com.apple.trustd.agent")
+ (global-name "com.apple.ocspd"))
+ ; Required for camera access
+ (allow mach-lookup
+ (global-name "com.apple.tccd")
+ (global-name "com.apple.tccd.system")
+ (global-name "com.apple.cmio.AppleCameraAssistant")
+ (global-name "com.apple.cmio.IIDCVideoAssistant")
+ (global-name "com.apple.cmio.AVCAssistant")
+ (global-name "com.apple.cmio.VDCAssistant"))
+ (if (>= macosVersion 1015)
+ (allow mach-lookup
+ (global-name "com.apple.ViewBridgeAuxiliary")
+ (global-name "com.apple.appkit.xpc.openAndSavePanelService")
+ (global-name "com.apple.MTLCompilerService")))
+
+ ; Fonts
+ (allow file-read*
+ (subpath "/Library/Fonts")
+ (subpath "/Library/Application Support/Apple/Fonts")
+ (home-library-subpath "/Fonts")
+ ; Allow read access to paths allowed via sandbox extensions.
+ ; This is needed for fonts in non-standard locations normally
+ ; due to third party font managers. The extensions are
+ ; automatically issued by the font server in response to font
+ ; API calls.
+ (extension "com.apple.app-sandbox.read"))
+ ; Fonts may continue to work without explicitly allowing these
+ ; services because, at present, connections are made to the services
+ ; before the sandbox is enabled as a side-effect of some API calls.
+ (allow mach-lookup
+ (global-name "com.apple.fonts")
+ (global-name "com.apple.FontObjectsServer"))
+
+ ; level 1: global read access permitted, no global write access
+ (if (string=? sandbox-level-1 "TRUE") (allow file-read*))
+
+ ; level 2: read access via file dialog exceptions, no global write access
+ (if (or (string=? sandbox-level-2 "TRUE")
+ (string=? sandbox-level-1 "TRUE")) (begin
+ ; Open file dialogs
+ (allow mach-lookup
+ ; needed for the dialog sidebar
+ (global-name "com.apple.coreservices.sharedfilelistd.xpc")
+ ; bird(8) -- "Documents in the Cloud"
+ ; needed to avoid iCloud error dialogs and to display iCloud files
+ (global-name "com.apple.bird")
+ (global-name "com.apple.bird.token")
+ ; needed for icons in the file dialog
+ (global-name "com.apple.iconservices"))
+ ; Needed for read access to files selected by the user with the
+ ; file dialog. The extensions are granted when the dialog is
+ ; displayed. Unfortunately (testing revealed) that displaying
+ ; the file dialog grants access to all files within the directory
+ ; displayed by the file dialog--a small improvement compared
+ ; to global read access.
+ (allow file-read*
+ (extension "com.apple.app-sandbox.read-write"))))
+
+ (allow ipc-posix-shm*
+ (ipc-posix-name-regex #"^AudioIO")
+ (ipc-posix-name-regex #"^CFPBS:"))
+
+ (allow ipc-posix-shm-read*
+ (ipc-posix-name-regex #"^/tmp/com\.apple\.csseed\.")
+ (ipc-posix-name "FNetwork.defaultStorageSession")
+ (ipc-posix-name "apple.shm.notification_center"))
+
+ ; Printing
+ (allow network-outbound (literal "/private/var/run/cupsd"))
+ (allow mach-lookup
+ (global-name "com.apple.printuitool.agent")
+ (global-name "com.apple.printtool.agent")
+ (global-name "com.apple.printtool.daemon"))
+ (allow file-read*
+ (subpath "/Library/Printers")
+ (home-literal "/.cups/lpoptions")
+ (home-literal "/.cups/client.conf")
+ (literal "/private/etc/cups/client.conf")
+ (literal "/private/etc/cups/lpoptions")
+ (subpath "/private/etc/cups/ppd")
+ (literal "/private/var/run/cupsd"))
+ (allow user-preference-read
+ (preference-domain "org.cups.PrintingPrefs"))
+ ; Temporary files read/written here during printing
+ (allow file-read* file-write-create file-write-data
+ (tempDir-regex "/FlashTmp"))
+
+ ; Camera/Mic
+ (allow device-camera)
+ (allow device-microphone)
+
+ ; Path to the plugin binary, user cache dir, and user temp dir
+ (allow file-read* (subpath pluginPath))
+
+ ; Per Adobe, needed for Flash LocalConnection functionality
+ (allow ipc-posix-sem
+ (ipc-posix-name "MacromediaSemaphoreDig"))
+
+ ; Flash debugger and enterprise deployment config files
+ (allow file-read*
+ (home-literal "/mm.cfg")
+ (home-literal "/mms.cfg"))
+
+ (allow file-read* file-write-create file-write-mode file-write-owner
+ (home-library-literal "/Caches/Adobe")
+ (home-library-preferences-literal "/Macromedia"))
+
+ (allow file-read* file-write-create file-write-data
+ (literal "/Library/Application Support/Macromedia/mms.cfg")
+ (home-library-literal "/Application Support/Macromedia/mms.cfg")
+ (home-library-subpath "/Caches/Adobe/Flash Player"))
+ (allow file-read* file-write-create file-write-data file-write-unlink
+ (home-library-subpath "/Preferences/Macromedia/Flash Player"))
+
+ (allow file-read*
+ (literal "/Library/PreferencePanes/Flash Player.prefPane")
+ (home-library-literal "/PreferencePanes/Flash Player.prefPane")
+ (home-library-regex "/Application Support/Macromedia/ss\.(cfg|cfn|sgn)$"))
+
+ (allow file-read*
+ (literal "/Library/Preferences/com.apple.security.plist")
+ (subpath "/private/var/db/mds"))
+
+ ; Additional read/write paths needed for encrypted video playback.
+ ; Tests revealed file-write-{data,create,flags} are required for the
+ ; accesses to the mds files. file-write-{data,create,mode,unlink}
+ ; required for CertStore.dat access. Allow file-write* to match system
+ ; profiles and for better compatibilty.
+ (allow file-read* file-write*
+ (require-all
+ (vnode-type REGULAR-FILE)
+ (require-any
+ (cache-literal "/mds/mds.lock")
+ (cache-literal "/mds/mdsDirectory.db")
+ (cache-literal "/mds/mdsDirectory.db_")
+ (cache-literal "/mds/mdsObject.db")
+ (cache-literal "/mds/mdsObject.db_")
+ (tempDir-regex "/TemporaryItems/[^/]+/CertStore.dat"))))
+
+ (allow network-bind (local ip))
+
+ (deny file-write-create (vnode-type SYMLINK))
+)SANDBOX_LITERAL";
+
+} // namespace mozilla
+
+#endif // mozilla_SandboxPolicyFlash_h
diff --git a/security/sandbox/mac/SandboxPolicyGMP.h b/security/sandbox/mac/SandboxPolicyGMP.h
new file mode 100644
index 0000000000..344721f946
--- /dev/null
+++ b/security/sandbox/mac/SandboxPolicyGMP.h
@@ -0,0 +1,101 @@
+/* -*- 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_SandboxPolicyGMP_h
+#define mozilla_SandboxPolicyGMP_h
+
+#define MAX_GMP_TESTING_READ_PATHS 2
+
+namespace mozilla {
+
+static const char SandboxPolicyGMP[] = R"SANDBOX_LITERAL(
+ (version 1)
+
+ (define should-log (param "SHOULD_LOG"))
+ (define app-path (param "APP_PATH"))
+ (define plugin-path (param "PLUGIN_PATH"))
+ (define plugin-binary-path (param "PLUGIN_BINARY_PATH"))
+ (define crashPort (param "CRASH_PORT"))
+ (define hasWindowServer (param "HAS_WINDOW_SERVER"))
+ (define testingReadPath1 (param "TESTING_READ_PATH1"))
+ (define testingReadPath2 (param "TESTING_READ_PATH2"))
+ (define isRosettaTranslated (param "IS_ROSETTA_TRANSLATED"))
+
+ (define (moz-deny feature)
+ (if (string=? should-log "TRUE")
+ (deny feature)
+ (deny feature (with no-log))))
+
+ (moz-deny default)
+ ; These are not included in (deny default)
+ (moz-deny process-info*)
+ (allow process-info-pidinfo (target self))
+ ; 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))
+
+ ; Needed for things like getpriority()/setpriority()/pthread_setname()
+ (allow process-info-pidinfo process-info-setcontrol (target self))
+
+ (if (defined? 'file-map-executable)
+ (begin
+ (if (string=? isRosettaTranslated "TRUE")
+ (allow file-map-executable (subpath "/private/var/db/oah")))
+ (allow file-map-executable file-read*
+ (subpath "/System/Library")
+ (subpath "/usr/lib")
+ (subpath plugin-path)
+ (subpath app-path)))
+ (allow file-read*
+ (subpath "/System/Library")
+ (subpath "/usr/lib")
+ (subpath plugin-path)
+ (subpath app-path)))
+
+ (if (defined? 'file-map-executable)
+ (begin
+ (when plugin-binary-path
+ (allow file-read* file-map-executable (subpath plugin-binary-path)))
+ (when testingReadPath1
+ (allow file-read* file-map-executable (subpath testingReadPath1)))
+ (when testingReadPath2
+ (allow file-read* file-map-executable (subpath testingReadPath2))))
+ (begin
+ (when plugin-binary-path
+ (allow file-read* (subpath plugin-binary-path)))
+ (when testingReadPath1
+ (allow file-read* (subpath testingReadPath1)))
+ (when testingReadPath2
+ (allow file-read* (subpath testingReadPath2)))))
+
+ (if (string? crashPort)
+ (allow mach-lookup (global-name crashPort)))
+
+ (allow signal (target self))
+ (allow sysctl-read)
+ (allow iokit-open (iokit-user-client-class "IOHIDParamUserClient"))
+ (allow file-read*
+ (literal "/etc")
+ (literal "/dev/random")
+ (literal "/dev/urandom")
+ (literal "/usr/share/icu/icudt51l.dat"))
+
+ ; Timezone
+ (allow file-read*
+ (subpath "/private/var/db/timezone")
+ (subpath "/usr/share/zoneinfo")
+ (subpath "/usr/share/zoneinfo.default")
+ (literal "/private/etc/localtime"))
+
+ (if (string=? hasWindowServer "TRUE")
+ (allow mach-lookup (global-name "com.apple.windowserver.active")))
+)SANDBOX_LITERAL";
+
+} // namespace mozilla
+
+#endif // mozilla_SandboxPolicyGMP_h
diff --git a/security/sandbox/mac/SandboxPolicyRDD.h b/security/sandbox/mac/SandboxPolicyRDD.h
new file mode 100644
index 0000000000..b5ab50da23
--- /dev/null
+++ b/security/sandbox/mac/SandboxPolicyRDD.h
@@ -0,0 +1,199 @@
+/* -*- 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_SandboxPolicyRDD_h
+#define mozilla_SandboxPolicyRDD_h
+
+namespace mozilla {
+
+static const char SandboxPolicyRDD[] = R"SANDBOX_LITERAL(
+ (version 1)
+
+ (define should-log (param "SHOULD_LOG"))
+ (define macosVersion (string->number (param "MAC_OS_VERSION")))
+ (define app-path (param "APP_PATH"))
+ (define home-path (param "HOME_PATH"))
+ (define crashPort (param "CRASH_PORT"))
+ (define isRosettaTranslated (param "IS_ROSETTA_TRANSLATED"))
+
+ (define (moz-deny feature)
+ (if (string=? should-log "TRUE")
+ (deny feature)
+ (deny feature (with no-log))))
+
+ (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*))
+ ; The next two properties both require macOS 10.10+
+ (if (defined? 'iokit-get-properties)
+ (moz-deny iokit-get-properties))
+ (if (defined? 'file-map-executable)
+ (moz-deny file-map-executable))
+
+ ; Needed for things like getpriority()/setpriority()/pthread_setname()
+ (allow process-info-pidinfo process-info-setcontrol (target self))
+
+ (if (defined? 'file-map-executable)
+ (begin
+ (if (string=? isRosettaTranslated "TRUE")
+ (allow file-map-executable (subpath "/private/var/db/oah")))
+ (allow file-map-executable file-read*
+ (subpath "/System")
+ (subpath "/usr/lib")
+ (subpath "/Library/GPUBundles")
+ (subpath app-path)))
+ (allow file-read*
+ (subpath "/System")
+ (subpath "/usr/lib")
+ (subpath "/Library/GPUBundles")
+ (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"))
+
+ ; Timezone
+ (allow file-read*
+ (subpath "/private/var/db/timezone")
+ (subpath "/usr/share/zoneinfo")
+ (subpath "/usr/share/zoneinfo.default")
+ (literal "/private/etc/localtime"))
+
+ (allow sysctl-read
+ (sysctl-name-regex #"^sysctl\.")
+ (sysctl-name "kern.ostype")
+ (sysctl-name "kern.osversion")
+ (sysctl-name "kern.osrelease")
+ (sysctl-name "kern.osproductversion")
+ (sysctl-name "kern.version")
+ ; TODO: remove "kern.hostname". Without it the tests hang, but the hostname
+ ; is arguably sensitive information, so we should see what can be done about
+ ; removing it.
+ (sysctl-name "kern.hostname")
+ (sysctl-name "hw.machine")
+ (sysctl-name "hw.memsize")
+ (sysctl-name "hw.model")
+ (sysctl-name "hw.ncpu")
+ (sysctl-name "hw.activecpu")
+ (sysctl-name "hw.byteorder")
+ (sysctl-name "hw.pagesize_compat")
+ (sysctl-name "hw.logicalcpu_max")
+ (sysctl-name "hw.physicalcpu_max")
+ (sysctl-name "hw.busfrequency_compat")
+ (sysctl-name "hw.busfrequency_max")
+ (sysctl-name "hw.cpufrequency")
+ (sysctl-name "hw.cpufrequency_compat")
+ (sysctl-name "hw.cpufrequency_max")
+ (sysctl-name "hw.l2cachesize")
+ (sysctl-name "hw.l3cachesize")
+ (sysctl-name "hw.cachelinesize")
+ (sysctl-name "hw.cachelinesize_compat")
+ (sysctl-name "hw.tbfrequency_compat")
+ (sysctl-name "hw.vectorunit")
+ (sysctl-name "hw.optional.sse2")
+ (sysctl-name "hw.optional.sse3")
+ (sysctl-name "hw.optional.sse4_1")
+ (sysctl-name "hw.optional.sse4_2")
+ (sysctl-name "hw.optional.avx1_0")
+ (sysctl-name "hw.optional.avx2_0")
+ (sysctl-name "hw.optional.avx512f")
+ (sysctl-name "machdep.cpu.vendor")
+ (sysctl-name "machdep.cpu.family")
+ (sysctl-name "machdep.cpu.model")
+ (sysctl-name "machdep.cpu.stepping")
+ (sysctl-name "debug.intel.gstLevelGST")
+ (sysctl-name "debug.intel.gstLoaderControl"))
+
+ (define (home-regex home-relative-regex)
+ (regex (string-append "^" (regex-quote home-path) home-relative-regex)))
+ (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 (allow-shared-list domain)
+ (allow file-read*
+ (home-regex (string-append "/Library/Preferences/" (regex-quote domain)))))
+
+ (allow ipc-posix-shm-read-data ipc-posix-shm-write-data
+ (ipc-posix-name-regex #"^CFPBS:"))
+
+ (allow mach-lookup
+ (global-name "com.apple.CoreServices.coreservicesd")
+ (global-name "com.apple.coreservices.launchservicesd")
+ (global-name "com.apple.lsd.mapdb"))
+
+ (allow file-read*
+ (subpath "/Library/ColorSync/Profiles")
+ (literal "/")
+ (literal "/private/tmp")
+ (literal "/private/var/tmp")
+ (home-subpath "/Library/Colors")
+ (home-subpath "/Library/ColorSync/Profiles"))
+
+ (if (>= macosVersion 1013)
+ (allow mach-lookup
+ ; bug 1392988
+ (xpc-service-name "com.apple.coremedia.videodecoder")
+ (xpc-service-name "com.apple.coremedia.videoencoder")))
+
+ (if (>= macosVersion 1100)
+ (allow mach-lookup
+ ; bug 1655655
+ (global-name "com.apple.trustd.agent")))
+
+ ; Only supported on macOS 10.10+
+ (if (defined? 'iokit-get-properties)
+ (allow iokit-get-properties
+ (iokit-property "board-id")
+ (iokit-property "class-code")
+ (iokit-property "vendor-id")
+ (iokit-property "device-id")
+ (iokit-property "IODVDBundleName")
+ (iokit-property "IOGLBundleName")
+ (iokit-property "IOGVACodec")
+ (iokit-property "IOGVAHEVCDecode")
+ (iokit-property "IOAVDHEVCDecodeCapabilities")
+ (iokit-property "IOGVAHEVCEncode")
+ (iokit-property "IOGVAXDecode")
+ (iokit-property "IOPCITunnelled")
+ (iokit-property "IOVARendererID")
+ (iokit-property "MetalPluginName")
+ (iokit-property "MetalPluginClassName")))
+
+; accelerated graphics
+ (allow user-preference-read (preference-domain "com.apple.opengl"))
+ (allow user-preference-read (preference-domain "com.nvidia.OpenGL"))
+ (allow mach-lookup
+ (global-name "com.apple.cvmsServ"))
+ (if (>= macosVersion 1014)
+ (allow mach-lookup
+ (global-name "com.apple.MTLCompilerService")))
+ (allow iokit-open
+ (iokit-connection "IOAccelerator")
+ (iokit-user-client-class "IOAccelerationUserClient")
+ (iokit-user-client-class "IOSurfaceRootUserClient")
+ (iokit-user-client-class "IOSurfaceSendRight")
+ (iokit-user-client-class "IOFramebufferSharedUserClient")
+ (iokit-user-client-class "AGPMClient")
+ (iokit-user-client-class "AppleGraphicsControlClient"))
+
+ (if (>= macosVersion 1013)
+ (allow mach-lookup
+ ; bug 1565575
+ (global-name "com.apple.audio.AudioComponentRegistrar")))
+)SANDBOX_LITERAL";
+
+} // namespace mozilla
+
+#endif // mozilla_SandboxPolicyRDD_h
diff --git a/security/sandbox/mac/SandboxPolicySocket.h b/security/sandbox/mac/SandboxPolicySocket.h
new file mode 100644
index 0000000000..18033f7034
--- /dev/null
+++ b/security/sandbox/mac/SandboxPolicySocket.h
@@ -0,0 +1,146 @@
+/* -*- 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 isRosettaTranslated (param "IS_ROSETTA_TRANSLATED"))
+
+ (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)
+ (begin
+ (if (string=? isRosettaTranslated "TRUE")
+ (allow file-map-executable (subpath "/private/var/db/oah")))
+ (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
diff --git a/security/sandbox/mac/SandboxPolicyUtility.h b/security/sandbox/mac/SandboxPolicyUtility.h
new file mode 100644
index 0000000000..4e54d94276
--- /dev/null
+++ b/security/sandbox/mac/SandboxPolicyUtility.h
@@ -0,0 +1,73 @@
+/* -*- 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_SandboxPolicyUtility_h
+#define mozilla_SandboxPolicyUtility_h
+
+namespace mozilla {
+
+static const char SandboxPolicyUtility[] = R"SANDBOX_LITERAL(
+ (version 1)
+
+ (define should-log (param "SHOULD_LOG"))
+ (define app-path (param "APP_PATH"))
+ (define crashPort (param "CRASH_PORT"))
+ (define isRosettaTranslated (param "IS_ROSETTA_TRANSLATED"))
+
+ (define (moz-deny feature)
+ (if (string=? should-log "TRUE")
+ (deny feature)
+ (deny feature (with no-log))))
+
+ (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))
+
+ ; Needed for things like getpriority()/setpriority()/pthread_setname()
+ (allow process-info-pidinfo process-info-setcontrol (target self))
+
+ (if (defined? 'file-map-executable)
+ (begin
+ (if (string=? isRosettaTranslated "TRUE")
+ (allow file-map-executable (subpath "/private/var/db/oah")))
+ (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"))
+
+ ; Timezone
+ (allow file-read*
+ (subpath "/private/var/db/timezone")
+ (subpath "/usr/share/zoneinfo")
+ (subpath "/usr/share/zoneinfo.default")
+ (literal "/private/etc/localtime"))
+
+ (allow mach-lookup
+ (global-name "com.apple.coreservices.launchservicesd"))
+)SANDBOX_LITERAL";
+
+} // namespace mozilla
+
+#endif // mozilla_SandboxPolicyUtility_h
diff --git a/security/sandbox/mac/moz.build b/security/sandbox/mac/moz.build
new file mode 100644
index 0000000000..adda8e7076
--- /dev/null
+++ b/security/sandbox/mac/moz.build
@@ -0,0 +1,20 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+EXPORTS.mozilla += [
+ "Sandbox.h",
+ "SandboxPolicyContent.h",
+ "SandboxPolicyFlash.h",
+ "SandboxPolicyGMP.h",
+ "SandboxPolicyRDD.h",
+ "SandboxPolicyUtility.h",
+]
+
+SOURCES += [
+ "Sandbox.mm",
+]
+
+Library("mozsandbox")