/* -*- 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 #include #include #include #include #include #include #include #include "SandboxPolicyContent.h" #include "SandboxPolicyGMP.h" #include "SandboxPolicyRDD.h" #include "SandboxPolicySocket.h" #include "SandboxPolicyUtility.h" #include "mozilla/Assertions.h" #include "mozilla/GeckoArgs.h" #include "mozilla/ipc/UtilityProcessSandboxing.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& 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& aParams) const { aParams.push_back("-sbStartup"); } void MacSandboxInfo::AppendLoggingParam( std::vector& aParams) const { if (this->shouldLog) { aParams.push_back("-sbLogging"); } } void MacSandboxInfo::AppendAppPathParam( std::vector& aParams) const { aParams.push_back("-sbAppPath"); aParams.push_back(this->appPath); } void MacSandboxInfo::AppendPluginPathParam( std::vector& aParams) const { aParams.push_back("-sbPluginPath"); aParams.push_back(this->pluginPath); } /* static */ void MacSandboxInfo::AppendFileAccessParam(std::vector& aParams, bool aHasFilePrivileges) { if (aHasFilePrivileges) { aParams.push_back("-sbAllowFileAccess"); } } void MacSandboxInfo::AppendLevelParam(std::vector& 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& aParams) const { if (this->hasAudio) { aParams.push_back("-sbAllowAudio"); } } void MacSandboxInfo::AppendWindowServerParam( std::vector& aParams) const { if (this->hasWindowServer) { aParams.push_back("-sbAllowWindowServer"); } } void MacSandboxInfo::AppendReadPathParams( std::vector& 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& 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 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 content process to access to parts of the cache dir. std::string userCacheDir; if (aInfo.type == MacSandboxType_Utility) { profile = const_cast(SandboxPolicyUtility); switch (aInfo.utilityKind) { case ipc::SandboxingKind::GENERIC_UTILITY: // Nothing to do here specifically break; #ifdef MOZ_APPLEMEDIA case ipc::SandboxingKind::UTILITY_AUDIO_DECODING_APPLE_MEDIA: { profile.append(SandboxPolicyUtilityAudioDecoderAppleMediaAddend); params.push_back("MAC_OS_VERSION"); params.push_back(combinedVersion.c_str()); } break; #endif default: MOZ_ASSERT(false, "Invalid SandboxingKind"); break; } 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(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(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(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()); } 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(userCacheDir, confStrBuf)) { return false; } params.push_back(userCacheDir.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, bool aSandboxingKindRequired = true) { // 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 (aSandboxingKindRequired) { Maybe sandboxingKind = geckoargs::sSandboxingKind.Get(aArgc, aArgv, CheckArgFlag::None); if (sandboxingKind.isNothing()) { fprintf(stderr, "Utility sandbox requires a sandboxingKind"); return false; } aInfo.utilityKind = (ipc::SandboxingKind)*sandboxingKind; } 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, false); } 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, false); } /* * 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