Sandbox/OS X Rule Set
References
References | |
---|---|
1 |
Apple's Sandbox Guide v1.0 13-09-2011 |
Glossary
References | |
---|---|
~ |
Refers to the full path to the home directory of the user. On OS X this is /Users/<username>. |
Notes
- One of the confusing things about the Mac file-system related rules is the redundancy. The rules start out with a (default deny) which means that unless something is explicitly allowed, it is denied. Then we have several filesystem rules to allow read access to specific locations on the system. But later we have a general rule that allows access to anything that is not in ~/Library (i.e., access to ~/Library is blocked) making many of the specific rules redundant. Lastly we have rules allowing access to specific directories in ~/Library. Bug 1083344 "Tighten rules for Mac OS content process sandbox on 10.9 and 10.10" documents how this came to be -- not allowing access to ~ broke too many things.
- An allow rule doesn't bypass OS filesystem permissions that would otherwise block a user's access.
- Because of the redundancy, we could remove most filesystem rules and replace them with rules that equate to (allow everything, but don't allow ~/Library except for a few subdirectories in ~/Library).
- Use of file* in the rules includes all of file-read, file-write, file-read-metadata, and file-write-metadata.
Annotated Rules
Rule | Description |
---|---|
static const char contentSandboxRules[] = | |
(version 1) |
References[1] states only version 1 is supported. I tried with version=2 and sandbox_init failed due to "unsupported version". |
(define sandbox-level %d) (define macosMinorVersion %d) (define appPath \"%s\") (define appBinaryPath \"%s\") (define appDir \"%s\") (define appTempDir \"%s\") (define home-path \"%s\")
(if (< sandbox-level 2) (allow file* (require-not (home-subpath \"/Library\"))) ;else (allow file* (require-all (subpath home-path) (require-not (home-subpath \"/Library\")))))
|
These setup some macros to be used later in the policy. See the next row for examples of what they evaulate to on a Nightly build. |
Full paths abbreviated. (define sandbox-level 1) (define macosMinorVersion 11) (define appPath "/.../NightlyDebug.app/Contents/MacOS/plugin-container.app") (define appBinaryPath "/.../NightlyDebug.app/Contents/MacOS/plugin-container.app/Contents/MacOS/plugin-container") (define appDir "/.../NightlyDebug.app/Contents/Resources/browser") (define appTempDir "/Users/<USERNAME>/Library/Caches/TemporaryItems/Temp-{62ac76fa-73fd-8f46-bd2b-12c4d53aa1cc}") (define home-path "/Users/<USERNAME>") | |
;;; Allow read access to standard system paths. (allow file-read* (require-all (file-mode #o0004) (require-any (subpath "/Library/Filesystems/NetFSPlugins") (subpath "/System") (subpath "/private/var/db/dyld") (subpath "/usr/lib") (subpath "/usr/share")))) (allow file-read-metadata (literal "/etc") (literal "/tmp") (literal "/var") (literal "/private/etc/localtime")) ;;; Allow 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")) (allow network-outbound (literal "/private/var/run/asl_input") (literal "/private/var/run/syslog")) (allow mach-lookup (global-name "com.apple.appsleep") (global-name "com.apple.bsd.dirhelper") (global-name "com.apple.cfprefsd.agent") (global-name "com.apple.cfprefsd.daemon") (global-name "com.apple.diagnosticd") (global-name "com.apple.espd") (global-name "com.apple.secinitd") (global-name "com.apple.system.DirectoryService.libinfo_v1") (global-name "com.apple.system.logger") (global-name "com.apple.system.notification_center") (global-name "com.apple.system.opendirectoryd.libinfo") (global-name "com.apple.system.opendirectoryd.membership") (global-name "com.apple.trustd") (global-name "com.apple.trustd.agent") (global-name "com.apple.xpc.activity.unmanaged") (global-name "com.apple.xpcd") (local-name "com.apple.cfprefsd.agent")) ; Used to read hw.ncpu, hw.physicalcpu_max, kern.ostype, and others (allow sysctl-read) |
A subset of the rules originally from /System/Library/Sandbox/Profiles/system.sb which ships with OS X. |
" (begin\n" " (deny default)\n" |
By default, we deny. i.e., for any capability not explicitly allowed here, do not allow it to be used. |
" (debug deny)\n" "\n" |
For any rule that causes an action to be denied, log something in system.log. These log entries are easily viewed using the OS X "Console" application and filtering on "sandbox". |
" (define resolving-literal literal)\n" " (define resolving-subpath subpath)\n" " (define resolving-regex regex)\n" |
Shortcut macros. |
" (define container-path appPath)\n" " (define appdir-path appDir)\n" " (define var-folders-re \"^/private/var/folders/[^/][^/]\")\n" " (define var-folders2-re (string-append var-folders-re \"/[^/]+/[^/]\"))\n" "\n" " (define (home-regex home-relative-regex)\n" " (resolving-regex (string-append \"^\" (regex-quote home-path) home-relative-regex)))\n" " (define (home-subpath home-relative-subpath)\n" " (resolving-subpath (string-append home-path home-relative-subpath)))\n" " (define (home-literal home-relative-literal)\n" " (resolving-literal (string-append home-path home-relative-literal)))\n" "\n" " (define (container-regex container-relative-regex)\n" " (resolving-regex (string-append \"^\" (regex-quote container-path) container-relative-regex)))\n" " (define (container-subpath container-relative-subpath)\n" " (resolving-subpath (string-append container-path container-relative-subpath)))\n" " (define (container-literal container-relative-literal)\n" " (resolving-literal (string-append container-path container-relative-literal)))\n" "\n" " (define (var-folders-regex var-folders-relative-regex)\n" " (resolving-regex (string-append var-folders-re var-folders-relative-regex)))\n" " (define (var-folders2-regex var-folders2-relative-regex)\n" " (resolving-regex (string-append var-folders2-re var-folders2-relative-regex)))\n" "\n" " (define (appdir-regex appdir-relative-regex)\n" " (resolving-regex (string-append \"^\" (regex-quote appdir-path) appdir-relative-regex)))\n" " (define (appdir-subpath appdir-relative-subpath)\n" " (resolving-subpath (string-append appdir-path appdir-relative-subpath)))\n" " (define (appdir-literal appdir-relative-literal)\n" " (resolving-literal (string-append appdir-path appdir-relative-literal)))\n" "\n" " (define (allow-shared-preferences-read domain)\n" " (begin\n" " (if (defined? `user-preference-read)\n" " (allow user-preference-read (preference-domain domain)))\n" " (allow file-read*\n" " (home-literal (string-append \"/Library/Preferences/\" domain \".plist\"))\n" " (home-regex (string-append \"/Library/Preferences/ByHost/\" (regex-quote domain) \"\\..*\\.plist$\")))\n" " ))\n" "\n" " (define (allow-shared-list domain)\n" " (allow file-read*\n" " (home-regex (string-append \"/Library/Preferences/\" (regex-quote domain)))))\n" "\n" |
Text substitution macros for dealing with paths. |
" (allow file-read-metadata)\n" |
Does this allow file-read-metadata for all files? |
"\n" " (allow ipc-posix-shm\n" " (ipc-posix-name-regex \"^/tmp/com.apple.csseed:\")\n" " (ipc-posix-name-regex \"^CFPBS:\")\n" " (ipc-posix-name-regex \"^AudioIO\"))\n" |
IPC shared memory? |
"\n" " (allow file-read-metadata\n" " (literal \"/home\")\n" " (literal \"/net\")\n" " (regex \"^/private/tmp/KSInstallAction\\.\")\n" " (var-folders-regex \"/\")\n" " (home-subpath \"/Library\"))\n" |
Allow reading of file metadata for this directories and files. Is this redundant give the above "(allow file-read-metadata)" rule. |
"\n" " (allow signal (target self))\n" " (allow job-creation (literal \"/Library/CoreMediaIO/Plug-Ins/DAL\"))\n" " (allow iokit-set-properties (iokit-property \"IOAudioControlValue\"))\n" "\n" " (allow mach-lookup\n" " (global-name \"com.apple.coreservices.launchservicesd\")\n" " (global-name \"com.apple.coreservices.appleevents\")\n" " (global-name \"com.apple.pasteboard.1\")\n" " (global-name \"com.apple.window_proxies\")\n" " (global-name \"com.apple.windowserver.active\")\n" " (global-name \"com.apple.audio.coreaudiod\")\n" " (global-name \"com.apple.audio.audiohald\")\n" " (global-name \"com.apple.PowerManagement.control\")\n" " (global-name \"com.apple.cmio.VDCAssistant\")\n" " (global-name \"com.apple.SystemConfiguration.configd\")\n" " (global-name \"com.apple.iconservices\")\n" " (global-name \"com.apple.cookied\")\n" " (global-name \"com.apple.printuitool.agent\")\n" " (global-name \"com.apple.printtool.agent\")\n" " (global-name \"com.apple.cache_delete\")\n" " (global-name \"com.apple.pluginkit.pkd\")\n" " (global-name \"com.apple.bird\")\n" " (global-name \"com.apple.ocspd\")\n" " (global-name \"com.apple.cmio.AppleCameraAssistant\")\n" " (global-name \"com.apple.DesktopServicesHelper\")\n" " (global-name \"com.apple.printtool.daemon\"))\n" "\n" " (allow iokit-open\n" " (iokit-user-client-class \"IOHIDParamUserClient\")\n" " (iokit-user-client-class \"IOAudioControlUserClient\")\n" " (iokit-user-client-class \"IOAudioEngineUserClient\")\n" " (iokit-user-client-class \"IGAccelDevice\")\n" " (iokit-user-client-class \"nvDevice\")\n" " (iokit-user-client-class \"nvSharedUserClient\")\n" " (iokit-user-client-class \"nvFermiGLContext\")\n" " (iokit-user-client-class \"IGAccelGLContext\")\n" " (iokit-user-client-class \"IGAccelSharedUserClient\")\n" " (iokit-user-client-class \"IGAccelVideoContextMain\")\n" " (iokit-user-client-class \"IGAccelVideoContextMedia\")\n" " (iokit-user-client-class \"IGAccelVideoContextVEBox\")\n" " (iokit-user-client-class \"RootDomainUserClient\")\n" " (iokit-user-client-class \"IOUSBDeviceUserClientV2\")\n" " (iokit-user-client-class \"IOUSBInterfaceUserClientV2\"))\n" "\n" "; depending on systems, the 1st, 2nd or both rules are necessary\n" " (allow-shared-preferences-read \"com.apple.HIToolbox\")\n" " (allow file-read-data (literal \"/Library/Preferences/com.apple.HIToolbox.plist\"))\n" "\n" " (allow-shared-preferences-read \"com.apple.ATS\")\n" " (allow file-read-data (literal \"/Library/Preferences/.GlobalPreferences.plist\"))\n" "\n" " (allow file-read*\n" " (subpath \"/Library/Fonts\")\n" " (subpath \"/Library/Audio/Plug-Ins\")\n" " (subpath \"/Library/CoreMediaIO/Plug-Ins/DAL\")\n" " (subpath \"/Library/Spelling\")\n" " (subpath \"/private/etc/cups/ppd\")\n" " (subpath \"/private/var/run/cupsd\")\n" " (literal \"/\")\n" " (literal \"/private/tmp\")\n" " (literal \"/private/var/tmp\")\n" "\n" " (home-literal \"/.CFUserTextEncoding\")\n" " (home-literal \"/Library/Preferences/com.apple.DownloadAssessment.plist\")\n" " (home-subpath \"/Library/Colors\")\n" " (home-subpath \"/Library/Fonts\")\n" " (home-subpath \"/Library/FontCollections\")\n" " (home-subpath \"/Library/Keyboard Layouts\")\n" " (home-subpath \"/Library/Input Methods\")\n" " (home-subpath \"/Library/PDF Services\")\n" " (home-subpath \"/Library/Spelling\")\n" "\n" " (subpath appdir-path)\n" "\n" " (literal appPath)\n" " (literal appBinaryPath))\n" "\n" " (allow-shared-list \"org.mozilla.plugincontainer\")\n" "\n" "; the following 2 rules should be removed when microphone and camera access\n" "; are brokered through the content process\n" " (allow device-microphone)\n" " (allow device-camera)\n" "\n" " (allow file* (var-folders2-regex \"/com\\.apple\\.IntlDataCache\\.le$\"))\n" " (allow file-read*\n" " (var-folders2-regex \"/com\\.apple\\.IconServices/\")\n" " (var-folders2-regex \"/[^/]+\\.mozrunner/extensions/[^/]+/chrome/[^/]+/content/[^/]+\\.j(s|ar)$\"))\n" "\n" " (allow file-write* (var-folders2-regex \"/org\\.chromium\\.[a-zA-Z0-9]*$\"))\n" " (allow file-read*\n" " (home-regex \"/Library/Application Support/[^/]+/Extensions/[^/]/\")\n" " (resolving-regex \"/Library/Application Support/[^/]+/Extensions/[^/]/\")\n" " (home-regex \"/Library/Application Support/Firefox/Profiles/[^/]+/extensions/\")\n" " (home-regex \"/Library/Application Support/Firefox/Profiles/[^/]+/weave/\"))\n" "\n" "; the following rules should be removed when printing and \n" "; opening a file from disk are brokered through the main process\n" " (if\n" " (< sandbox-level 2)\n" " (allow file*\n" " (require-not\n" " (home-subpath \"/Library\")))\n" " (allow file*\n" " (require-all\n" " (subpath home-path)\n" " (require-not\n" " (home-subpath \"/Library\")))))\n" "\n" |
TODO |
"; printing\n" " (allow authorization-right-obtain\n" " (right-name \"system.print.operator\")\n" " (right-name \"system.printingmanager\"))\n" " (allow mach-lookup\n" " (global-name \"com.apple.printuitool.agent\")\n" " (global-name \"com.apple.printtool.agent\")\n" " (global-name \"com.apple.printtool.daemon\")\n" " (global-name \"com.apple.sharingd\")\n" " (global-name \"com.apple.metadata.mds\")\n" " (global-name \"com.apple.mtmd.xpc\")\n" " (global-name \"com.apple.FSEvents\")\n" " (global-name \"com.apple.locum\")\n" " (global-name \"com.apple.ImageCaptureExtension2.presence\"))\n" " (allow file-read*\n" " (home-literal \"/.cups/lpoptions\")\n" " (home-literal \"/.cups/client.conf\")\n" " (literal \"/private/etc/cups/lpoptions\")\n" " (literal \"/private/etc/cups/client.conf\")\n" " (subpath \"/private/etc/cups/ppd\")\n" " (literal \"/private/var/run/cupsd\"))\n" " (allow-shared-preferences-read \"org.cups.PrintingPrefs\")\n" " (allow-shared-preferences-read \"com.apple.finder\")\n" " (allow-shared-preferences-read \"com.apple.LaunchServices\")\n" " (allow-shared-preferences-read \".GlobalPreferences\")\n" " (allow network-outbound\n" " (literal \"/private/var/run/cupsd\")\n" " (literal \"/private/var/run/mDNSResponder\"))\n" "\n" |
Printing |
"; print preview\n" " (if (> macosMinorVersion 9)\n" " (allow lsopen))\n" " (allow file-write* file-issue-extension (var-folders2-regex \"/\"))\n" " (allow file-read-xattr (literal \"/Applications/Preview.app\"))\n" " (allow mach-task-name)\n" " (allow mach-register)\n" " (allow file-read-data\n" " (regex \"^/Library/Printers/[^/]+/PDEs/[^/]+.plugin\")\n" " (subpath \"/Library/PDF Services\")\n" " (subpath \"/Applications/Preview.app\")\n" " (home-literal \"/Library/Preferences/com.apple.ServicesMenu.Services.plist\"))\n" " (allow mach-lookup\n" " (global-name \"com.apple.pbs.fetch_services\")\n" " (global-name \"com.apple.tsm.uiserver\")\n" " (global-name \"com.apple.ls.boxd\")\n" " (global-name \"com.apple.coreservices.quarantine-resolver\")\n" " (global-name-regex \"_OpenStep$\"))\n" " (allow appleevent-send\n" " (appleevent-destination \"com.apple.preview\")\n" " (appleevent-destination \"com.apple.imagecaptureextension2\"))\n" |
Print preview |
"\n" "; accelerated graphics\n" " (allow-shared-preferences-read \"com.apple.opengl\")\n" " (allow-shared-preferences-read \"com.nvidia.OpenGL\")\n" " (allow mach-lookup\n" " (global-name \"com.apple.cvmsServ\"))\n" " (allow iokit-open\n" " (iokit-connection \"IOAccelerator\")\n" " (iokit-user-client-class \"IOAccelerationUserClient\")\n" " (iokit-user-client-class \"IOSurfaceRootUserClient\")\n" " (iokit-user-client-class \"IOSurfaceSendRight\")\n" " (iokit-user-client-class \"IOFramebufferSharedUserClient\")\n" " (iokit-user-client-class \"AppleSNBFBUserClient\")\n" " (iokit-user-client-class \"AGPMClient\")\n" " (iokit-user-client-class \"AppleGraphicsControlClient\")\n" " (iokit-user-client-class \"AppleGraphicsPolicyClient\"))\n" "\n" "; bug 1153809\n" " (allow iokit-open\n" " (iokit-user-client-class \"NVDVDContextTesla\")\n" " (iokit-user-client-class \"Gen6DVDContext\"))\n" |
Graphics |
"\n" "; bug 1190032\n" " (allow file*\n" " (home-regex \"/Library/Caches/TemporaryItems/plugtmp.*\"))\n" |
Read and write access to anything matching ~/Library/Caches/TemporaryItems/plugtmp.* |
"\n" "; bug 1201935\n" " (allow file-read*\n" " (home-subpath \"/Library/Caches/TemporaryItems\"))\n" "\n" |
Read-only access to anything in ~/Library/Caches/TemporaryItems |
"; bug 1237847\n" " (allow file-read*\n" " (home-subpath appTempDir))\n" " (allow file-write*\n" " (home-subpath appTempDir))\n" " )\n" ")\n"; |
Allow full reads and writes to appTempDir which (in this example) is "/Users/<USERNAME>/Library/Caches/TemporaryItems/Temp-{62ac76fa-73fd-8f46-bd2b-12c4d53aa1cc}". The directory is reset each time Firefox starts. |