Bug 1436566 - [Mac] Land disabled-by-default sandboxing for the Flash NPAPI plugin process. r=Alex_Gaynor r=jimm
MozReview-Commit-ID: Es0GbMLKvH5
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1081,16 +1081,20 @@ pref("security.sandbox.gpu.level", 0);
// 3 -> "no global read/write access, read access permitted to
// $PROFILE/{extensions,chrome}"
// This setting is read when the content process is started. On Mac the content
// process is killed when all windows are closed, so a change will take effect
// when the 1st window is opened.
pref("security.sandbox.content.level", 3);
#endif
+#if defined(NIGHTLY_BUILD) && defined(XP_MACOSX) && defined(MOZ_SANDBOX)
+pref("security.sandbox.mac.flash.enabled", false);
+#endif
+
#if defined(XP_LINUX) && defined(MOZ_SANDBOX) && defined(MOZ_CONTENT_SANDBOX)
// This pref is introduced as part of bug 742434, the naming is inspired from
// its Windows/Mac counterpart, but on Linux it's an integer which means:
// 0 -> "no sandbox"
// 1 -> "content sandbox using seccomp-bpf when available"
// 2 -> "seccomp-bpf + write file broker"
// 3 -> "seccomp-bpf + read/write file brokering"
// 4 -> all of the above + network/socket restrictions
--- a/dom/plugins/base/nsPluginTags.cpp
+++ b/dom/plugins/base/nsPluginTags.cpp
@@ -230,16 +230,17 @@ nsPluginTag::nsPluginTag(nsPluginInfo* a
mContentProcessRunningCount(0),
mHadLocalInstance(false),
mLibrary(nullptr),
mIsFlashPlugin(false),
mSupportsAsyncRender(false),
mFullPath(aPluginInfo->fFullPath),
mLastModifiedTime(aLastModifiedTime),
mSandboxLevel(0),
+ mIsSandboxLoggingEnabled(false),
mCachedBlocklistState(nsIBlocklistService::STATE_NOT_BLOCKED),
mCachedBlocklistStateValid(false),
mIsFromExtension(fromExtension)
{
InitMime(aPluginInfo->fMimeTypeArray,
aPluginInfo->fMimeDescriptionArray,
aPluginInfo->fExtensionArray,
aPluginInfo->fVariantCount);
@@ -265,16 +266,17 @@ nsPluginTag::nsPluginTag(const char* aNa
mContentProcessRunningCount(0),
mHadLocalInstance(false),
mLibrary(nullptr),
mIsFlashPlugin(false),
mSupportsAsyncRender(false),
mFullPath(aFullPath),
mLastModifiedTime(aLastModifiedTime),
mSandboxLevel(0),
+ mIsSandboxLoggingEnabled(false),
mCachedBlocklistState(nsIBlocklistService::STATE_NOT_BLOCKED),
mCachedBlocklistStateValid(false),
mIsFromExtension(fromExtension)
{
InitMime(aMimeTypes, aMimeDescriptions, aExtensions,
static_cast<uint32_t>(aVariants));
InitSandboxLevel();
if (!aArgsAreUTF8)
@@ -301,16 +303,17 @@ nsPluginTag::nsPluginTag(uint32_t aId,
aMimeDescriptions, aExtensions),
mId(aId),
mContentProcessRunningCount(0),
mLibrary(nullptr),
mIsFlashPlugin(aIsFlashPlugin),
mSupportsAsyncRender(aSupportsAsyncRender),
mLastModifiedTime(aLastModifiedTime),
mSandboxLevel(aSandboxLevel),
+ mIsSandboxLoggingEnabled(false),
mNiceFileName(),
mCachedBlocklistState(aBlocklistState),
mCachedBlocklistStateValid(true),
mIsFromExtension(aFromExtension)
{
}
nsPluginTag::~nsPluginTag()
@@ -416,16 +419,40 @@ nsPluginTag::InitSandboxLevel()
// As level 2 is now the default NPAPI sandbox level for 64-bit flash, we
// don't want to allow a lower setting. This should be changed if the
// firefox.js pref file is changed.
if (mIsFlashPlugin && mSandboxLevel < 2) {
mSandboxLevel = 2;
}
#endif
#endif
+
+#if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
+ // At present, the Mac Flash NPAPI plugin sandbox is controlled via
+ // a boolean with no support for different levels. When the sandbox
+ // is enabled, we set the level to 1.
+ if (mIsFlashPlugin) {
+ // Allow enabling the sandbox via the pref
+ // security.sandbox.mac.flash.enabled or via the environment variable
+ // MOZ_SANDBOX_MAC_FLASH_FORCE (which is useful while the sandbox is
+ // off by default).
+ if (Preferences::GetBool("security.sandbox.mac.flash.enabled") ||
+ PR_GetEnv("MOZ_SANDBOX_MAC_FLASH_FORCE")) {
+ mSandboxLevel = 1;
+
+ // Enable sandbox logging in the plugin process if it has
+ // been turned on via prefs or environment variables.
+ if (Preferences::GetBool("security.sandbox.logging.enabled") ||
+ PR_GetEnv("MOZ_SANDBOX_LOGGING") ||
+ PR_GetEnv("MOZ_SANDBOX_MAC_FLASH_LOGGING")) {
+ mIsSandboxLoggingEnabled = true;
+ }
+ }
+ }
+#endif
}
#if !defined(XP_WIN) && !defined(XP_MACOSX)
static void
ConvertToUTF8(nsCString& aString)
{
Unused << UTF_8_ENCODING->DecodeWithoutBOMHandling(aString, aString);
}
--- a/dom/plugins/base/nsPluginTags.h
+++ b/dom/plugins/base/nsPluginTags.h
@@ -168,16 +168,17 @@ public:
PRLibrary *mLibrary;
RefPtr<nsNPAPIPlugin> mPlugin;
bool mIsFlashPlugin;
bool mSupportsAsyncRender;
nsCString mFullPath; // UTF-8
int64_t mLastModifiedTime;
nsCOMPtr<nsITimer> mUnloadTimer;
int32_t mSandboxLevel;
+ bool mIsSandboxLoggingEnabled;
void InvalidateBlocklistState();
private:
virtual ~nsPluginTag();
nsCString mNiceFileName; // UTF-8
uint16_t mCachedBlocklistState;
--- a/dom/plugins/ipc/PluginModuleChild.cpp
+++ b/dom/plugins/ipc/PluginModuleChild.cpp
@@ -49,16 +49,20 @@
#include "PluginInterposeOSX.h"
#include "PluginUtilsOSX.h"
#endif
#ifdef MOZ_GECKO_PROFILER
#include "ChildProfilerController.h"
#endif
+#if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
+#include "mozilla/Sandbox.h"
+#endif
+
using namespace mozilla;
using namespace mozilla::ipc;
using namespace mozilla::plugins;
using namespace mozilla::widget;
#if defined(XP_WIN)
const wchar_t * kFlashFullscreenClass = L"ShockwaveFlashFullScreen";
#endif
@@ -94,16 +98,20 @@ PluginModuleChild::PluginModuleChild(boo
#elif defined(MOZ_WIDGET_GTK)
, mNestedLoopTimerId(0)
#endif
#ifdef OS_WIN
, mNestedEventHook(nullptr)
, mGlobalCallWndProcHook(nullptr)
, mAsyncRenderSupport(false)
#endif
+#if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
+ , mEnableFlashSandbox(false)
+ , mEnableFlashSandboxLogging(false)
+#endif
{
memset(&mFunctions, 0, sizeof(mFunctions));
if (mIsChrome) {
MOZ_ASSERT(!gChromeInstance);
gChromeInstance = this;
}
#ifdef XP_MACOSX
@@ -186,16 +194,25 @@ PluginModuleChild::RecvDisableFlashProte
#ifdef XP_WIN
FunctionHook::HookProtectedMode();
#else
MOZ_ASSERT(false, "Should not be called");
#endif
return IPC_OK();
}
+#if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
+void
+PluginModuleChild::EnableFlashSandbox(bool aShouldEnableLogging)
+{
+ mEnableFlashSandbox = true;
+ mEnableFlashSandboxLogging = aShouldEnableLogging;
+}
+#endif
+
bool
PluginModuleChild::InitForChrome(const std::string& aPluginFilename,
base::ProcessId aParentPid,
MessageLoop* aIOLoop,
IPC::Channel* aChannel)
{
NS_ASSERTION(aChannel, "need a channel");
@@ -279,16 +296,32 @@ PluginModuleChild::InitForChrome(const s
(NP_PLUGININIT)PR_FindFunctionSymbol(mLibrary, "NP_Initialize");
NS_ENSURE_TRUE(mInitializeFunc, false);
#else
# error Please copy the initialization code from nsNPAPIPlugin.cpp
#endif
+#if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
+ if (mEnableFlashSandbox) {
+ MacSandboxInfo flashSandboxInfo;
+ flashSandboxInfo.type = MacSandboxType_Plugin;
+ flashSandboxInfo.pluginInfo.type = MacSandboxPluginType_Flash;
+ flashSandboxInfo.pluginInfo.pluginBinaryPath = aPluginFilename;
+ flashSandboxInfo.shouldLog = mEnableFlashSandboxLogging;
+
+ std::string sbError;
+ if (!mozilla::StartMacSandbox(flashSandboxInfo, sbError)) {
+ fprintf(stderr, "Failed to start sandbox:\n%s\n", sbError.c_str());
+ return false;
+ }
+ }
+#endif
+
return true;
}
#if defined(MOZ_WIDGET_GTK)
typedef void (*GObjectDisposeFn)(GObject*);
typedef gboolean (*GtkWidgetScrollEventFn)(GtkWidget*, GdkEventScroll*);
typedef void (*GtkPlugEmbeddedFn)(GtkPlug*);
--- a/dom/plugins/ipc/PluginModuleChild.h
+++ b/dom/plugins/ipc/PluginModuleChild.h
@@ -308,17 +308,27 @@ public: // called by PluginInstanceChild
* is destroyed. This function will remove the object from mObjectMap.
*/
static void DeallocNPObject(NPObject* o);
NPError NPP_Destroy(PluginInstanceChild* instance) {
return mFunctions.destroy(instance->GetNPP(), 0);
}
+#if defined(OS_MACOSX) && defined(MOZ_SANDBOX)
+ void EnableFlashSandbox(bool aShouldEnableLogging);
+#endif
+
private:
+
+#if defined(OS_MACOSX) && defined(MOZ_SANDBOX)
+ bool mEnableFlashSandbox;
+ bool mEnableFlashSandboxLogging;
+#endif
+
#if defined(OS_WIN)
virtual void EnteredCall() override;
virtual void ExitedCall() override;
// Entered/ExitedCall notifications keep track of whether the plugin has
// entered a nested event loop within this interrupt call.
struct IncallFrame
{
--- a/dom/plugins/ipc/PluginModuleParent.cpp
+++ b/dom/plugins/ipc/PluginModuleParent.cpp
@@ -467,17 +467,18 @@ PluginModuleChromeParent::LoadModule(con
{
PLUGIN_LOG_DEBUG_FUNCTION;
nsAutoPtr<PluginModuleChromeParent> parent(
new PluginModuleChromeParent(aFilePath, aPluginId,
aPluginTag->mSandboxLevel));
UniquePtr<LaunchCompleteTask> onLaunchedRunnable(new LaunchedTask(parent));
bool launched = parent->mSubprocess->Launch(Move(onLaunchedRunnable),
- aPluginTag->mSandboxLevel);
+ aPluginTag->mSandboxLevel,
+ aPluginTag->mIsSandboxLoggingEnabled);
if (!launched) {
// We never reached open
parent->mShutdown = true;
return nullptr;
}
parent->mIsFlashPlugin = aPluginTag->mIsFlashPlugin;
uint32_t blocklistState;
nsresult rv = aPluginTag->GetBlocklistState(&blocklistState);
--- a/dom/plugins/ipc/PluginProcessChild.cpp
+++ b/dom/plugins/ipc/PluginProcessChild.cpp
@@ -91,16 +91,26 @@ PluginProcessChild::Init(int aArgc, char
// NB: need to be very careful in ensuring that the first arg
// (after the binary name) here is indeed the plugin module path.
// Keep in sync with dom/plugins/PluginModuleParent.
std::vector<std::string> values = CommandLine::ForCurrentProcess()->argv();
MOZ_ASSERT(values.size() >= 2, "not enough args");
pluginFilename = UnmungePluginDsoPath(values[1]);
+#if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
+ if (values.size() >= 3 && values[2] == "-flashSandbox") {
+ bool enableLogging = false;
+ if (values.size() >= 4 && values[3] == "-flashSandboxLogging") {
+ enableLogging = true;
+ }
+ mPlugin.EnableFlashSandbox(enableLogging);
+ }
+#endif
+
#elif defined(OS_WIN)
std::vector<std::wstring> values =
CommandLine::ForCurrentProcess()->GetLooseValues();
MOZ_ASSERT(values.size() >= 1, "not enough loose args");
if (ShouldProtectPluginCurrentDirectory(values[0].c_str())) {
SanitizeEnvironmentVariables();
SetDllDirectory(L"");
--- a/dom/plugins/ipc/PluginProcessParent.cpp
+++ b/dom/plugins/ipc/PluginProcessParent.cpp
@@ -47,32 +47,47 @@ PluginProcessParent::~PluginProcessParen
sPidSet = nullptr;
}
}
#endif
}
bool
PluginProcessParent::Launch(mozilla::UniquePtr<LaunchCompleteTask> aLaunchCompleteTask,
- int32_t aSandboxLevel)
+ int32_t aSandboxLevel,
+ bool aIsSandboxLoggingEnabled)
{
-#if defined(XP_WIN) && defined(MOZ_SANDBOX)
+#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_SANDBOX)
+ // At present, the Mac Flash plugin sandbox does not support different
+ // levels and is enabled via a boolean pref or environment variable.
+ // On Mac, when |aSandboxLevel| is positive, we enable the sandbox.
+#if defined(XP_WIN)
mSandboxLevel = aSandboxLevel;
+#endif // XP_WIN
#else
if (aSandboxLevel != 0) {
MOZ_ASSERT(false,
"Can't enable an NPAPI process sandbox for platform/build.");
}
#endif
mLaunchCompleteTask = mozilla::Move(aLaunchCompleteTask);
vector<string> args;
args.push_back(MungePluginDsoPath(mPluginFilePath));
+#if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
+ if (aSandboxLevel > 0) {
+ args.push_back("-flashSandbox");
+ if (aIsSandboxLoggingEnabled) {
+ args.push_back("-flashSandboxLogging");
+ }
+ }
+#endif
+
bool result = AsyncLaunch(args);
if (!result) {
mLaunchCompleteTask = nullptr;
}
return result;
}
void
--- a/dom/plugins/ipc/PluginProcessParent.h
+++ b/dom/plugins/ipc/PluginProcessParent.h
@@ -50,19 +50,22 @@ public:
/**
* Launch the plugin process. If the process fails to launch,
* this method will return false.
*
* @param aLaunchCompleteTask Task that is executed on the main
* thread once the asynchonous launch has completed.
* @param aSandboxLevel Determines the strength of the sandbox.
* <= 0 means no sandbox.
+ * @param aIsSandboxLoggingEnabled Indicates if sandbox violation
+ * logging should be enabled for the plugin process.
*/
bool Launch(UniquePtr<LaunchCompleteTask> aLaunchCompleteTask = UniquePtr<LaunchCompleteTask>(),
- int32_t aSandboxLevel = 0);
+ int32_t aSandboxLevel = 0,
+ bool aIsSandboxLoggingEnabled = false);
void Delete();
virtual bool CanShutdown() override
{
return true;
}
--- a/security/sandbox/mac/Sandbox.h
+++ b/security/sandbox/mac/Sandbox.h
@@ -18,16 +18,17 @@ enum MacSandboxType {
};
enum MacSandboxPluginType {
MacSandboxPluginType_Default = 0,
MacSandboxPluginType_GMPlugin_Default, // Any Gecko Media Plugin
MacSandboxPluginType_GMPlugin_OpenH264, // Gecko Media Plugin, OpenH264
MacSandboxPluginType_GMPlugin_EME, // Gecko Media Plugin, EME
MacSandboxPluginType_GMPlugin_EME_Widevine, // Gecko Media Plugin, Widevine
+ MacSandboxPluginType_Flash, // Flash
MacSandboxPluginType_Invalid
};
typedef struct _MacSandboxPluginInfo {
_MacSandboxPluginInfo()
: type(MacSandboxPluginType_Default) {}
_MacSandboxPluginInfo(const struct _MacSandboxPluginInfo& other)
: type(other.type), pluginPath(other.pluginPath),
--- a/security/sandbox/mac/Sandbox.mm
+++ b/security/sandbox/mac/Sandbox.mm
@@ -125,18 +125,66 @@ OSXVersion::GetVersionNumber()
namespace mozilla {
bool StartMacSandbox(MacSandboxInfo const &aInfo, std::string &aErrorMessage)
{
std::vector<const char *> params;
std::string profile;
std::string macOSMinor = std::to_string(OSXVersion::OSXVersionMinor());
- if (aInfo.type == MacSandboxType_Plugin) {
- profile = pluginSandboxRules;
+ // 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_Plugin &&
+ aInfo.pluginInfo.type == MacSandboxPluginType_Flash) {
+ profile = flashPluginSandboxRules;
+
+ params.push_back("SHOULD_LOG");
+ params.push_back(aInfo.shouldLog ? "TRUE" : "FALSE");
+
+ params.push_back("MAC_OS_MINOR");
+ params.push_back(macOSMinor.c_str());
+
+ params.push_back("HOME_PATH");
+ params.push_back(getenv("HOME"));
+
+ params.push_back("PLUGIN_BINARY_PATH");
+ flashPath = realpath(aInfo.pluginInfo.pluginBinaryPath.c_str(), nullptr);
+ if (flashPath.empty()) {
+ return false;
+ }
+ params.push_back(flashPath.c_str());
+
+ // User cache dir
+ params.push_back("DARWIN_USER_CACHE_DIR");
+ char cacheDir[PATH_MAX];
+ if (!confstr(_CS_DARWIN_USER_CACHE_DIR, cacheDir, sizeof(cacheDir))) {
+ return false;
+ }
+ flashCacheDir = realpath(cacheDir, nullptr);
+ if (flashCacheDir.empty()) {
+ return false;
+ }
+ params.push_back(flashCacheDir.c_str());
+
+ // User temp dir
+ params.push_back("DARWIN_USER_TEMP_DIR");
+ char tempDir[PATH_MAX];
+ if (!confstr(_CS_DARWIN_USER_TEMP_DIR, tempDir, sizeof(tempDir))) {
+ return false;
+ }
+ flashTempDir = realpath(tempDir, nullptr);
+ if (flashTempDir.empty()) {
+ return false;
+ }
+ params.push_back(flashTempDir.c_str());
+ }
+ else if (aInfo.type == MacSandboxType_Plugin) {
+ profile = const_cast<char *>(pluginSandboxRules);
params.push_back("SHOULD_LOG");
params.push_back(aInfo.shouldLog ? "TRUE" : "FALSE");
params.push_back("PLUGIN_BINARY_PATH");
params.push_back(aInfo.pluginInfo.pluginBinaryPath.c_str());
params.push_back("APP_PATH");
params.push_back(aInfo.appPath.c_str());
params.push_back("APP_BINARY_PATH");
params.push_back(aInfo.appBinaryPath.c_str());
--- a/security/sandbox/mac/SandboxPolicies.h
+++ b/security/sandbox/mac/SandboxPolicies.h
@@ -3,17 +3,17 @@
* 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_SandboxPolicies_h
#define mozilla_SandboxPolicies_h
namespace mozilla {
-static const char pluginSandboxRules[] = R"(
+static const char pluginSandboxRules[] = R"SANDBOX_LITERAL(
(version 1)
(define should-log (param "SHOULD_LOG"))
(define plugin-binary-path (param "PLUGIN_BINARY_PATH"))
(define app-path (param "APP_PATH"))
(define app-binary-path (param "APP_BINARY_PATH"))
(if (string=? should-log "TRUE")
@@ -30,23 +30,23 @@ static const char pluginSandboxRules[] =
(literal "/usr/share/icu/icudt51l.dat")
(subpath "/System/Library/Displays/Overrides")
(subpath "/System/Library/CoreServices/CoreTypes.bundle")
(subpath "/System/Library/PrivateFrameworks")
(regex #"^/usr/lib/libstdc\+\+\.[^/]*dylib$")
(literal plugin-binary-path)
(literal app-path)
(literal app-binary-path))
-)";
+)SANDBOX_LITERAL";
-static const char widevinePluginSandboxRulesAddend[] = R"(
+static const char widevinePluginSandboxRulesAddend[] = R"SANDBOX_LITERAL(
(allow mach-lookup (global-name "com.apple.windowserver.active"))
-)";
+)SANDBOX_LITERAL";
-static const char contentSandboxRules[] = R"(
+static const char contentSandboxRules[] = 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 macosMinorVersion (string->number (param "MAC_OS_MINOR")))
(define appPath (param "APP_PATH"))
@@ -347,47 +347,345 @@ static const char contentSandboxRules[]
(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"))
-)";
+)SANDBOX_LITERAL";
// These are additional rules that are added to the content process rules for
// file content processes.
-static const char fileContentProcessAddend[] = R"(
+static const char fileContentProcessAddend[] = 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 contentProcessAudioAddend[] = R"(
+static const char contentProcessAudioAddend[] = 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"))
(if (>= macosMinorVersion 13)
(allow mach-lookup
- ; bug 1376163
- (global-name "com.apple.audio.AudioComponentRegistrar")))
+ ; bug 1376163
+ (global-name "com.apple.audio.AudioComponentRegistrar")))
(allow iokit-open (iokit-user-client-class "IOAudioEngineUserClient"))
(allow file-read* (subpath "/Library/Audio/Plug-Ins"))
(allow device-microphone)
-)";
+)SANDBOX_LITERAL";
+
+// The "Safe Mode" Flash NPAPI plugin process profile
+static const char flashPluginSandboxRules[] = R"SANDBOX_LITERAL(
+ (version 1)
+
+ ; Parameters
+ (define shouldLog (param "SHOULD_LOG"))
+ (define macosMinorVersion (string->number (param "MAC_OS_MINOR")))
+ (define homeDir (param "HOME_PATH"))
+ (define cacheDir (param "DARWIN_USER_CACHE_DIR"))
+ (define tempDir (param "DARWIN_USER_TEMP_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")
+ (literal "/private/etc/localtime"))
+ (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"))
+
+ ; 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"))
+
+ ; 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))
+
+ ; macOS 10.9 does not support the |sysctl-name| predicate
+ (if (= macosMinorVersion 9)
+ (allow sysctl-read)
+ (allow sysctl-read
+ (sysctl-name
+ "hw.availcpu"
+ "hw.physicalcpu_max"
+ "hw.ncpu"
+ "hw.model"
+ "hw.busfrequency_max"
+ "hw.cpu64bit_capable"
+ "hw.optional.x86_64"
+ "kern.memorystatus_level"
+ "kern.osrelease"
+ "kern.hostname"
+ "kern.maxfilesperproc"
+ "vm.footprint_suspend")))
+
+ ; Utilities for allowing access to home subdirectories
+ (define home-library-path
+ (string-append homeDir "/Library"))
+
+ (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)))
+
+ ; 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.FontObjectsServer")
+ (global-name "com.apple.fonts")
+ (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.tccd.system")
+ (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"))
+
+ ; 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"))
+
+ (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"))
+
+ ; 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))
+ (allow file-read* file-write* (subpath cacheDir))
+ (allow file-read* file-write* (subpath tempDir))
+
+ ; 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"))
+
+ (deny file-read-xattr
+ (home-library-literal "/Caches")
+ (home-library-preferences-literal "/"))
+
+ (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*
+ (literal "/Library/Application Support/Macromedia/mms.cfg")
+ (home-library-literal "/Application Support/Macromedia/mms.cfg")
+ (home-library-subpath "/Caches/Adobe/Flash Player")
+ (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 network-bind (local ip))
+
+ (deny file-write-create (vnode-type SYMLINK))
+)SANDBOX_LITERAL";
}
#endif // mozilla_SandboxPolicies_h