Sandbox/Mac/Debugging
Contents
Using the (trace <filename>) Option
~ $ cat test.sb (version 1) (debug all) (trace "trace.sb") (deny default) ~ $ sandbox-exec -f ./test.sb ls /tmp com.apple.launchd.TxO9Zrlk0Y textmate-501.sock com.apple.launchd.Wx9IMgekbf wifi-Uy2Oqp.log ~ $ cat trace.sb (version 1) ; Thu Aug 11 10:46:24 2016 (allow process-exec* (path "/bin/ls")) (allow process-exec* (path "/bin/ls")) (allow file-read-metadata (path "/usr/lib/libutil.dylib")) (allow file-read-metadata (path "/usr/lib/libncurses.5.4.dylib")) (allow file-read-metadata (path "/usr/lib/libSystem.B.dylib")) (allow file-read-metadata (path "/usr/lib/libc++.1.dylib")) (allow file-read-metadata (path "/usr/lib/libc++abi.dylib")) (allow file-read-metadata (path "/usr/lib/system/libcache.dylib")) (allow file-read-metadata (path "/usr/lib/system/libcommonCrypto.dylib")) (allow file-read-metadata (path "/usr/lib/system/libcompiler_rt.dylib")) (allow file-read-metadata (path "/usr/lib/system/libcopyfile.dylib")) (allow file-read-metadata (path "/usr/lib/system/libcorecrypto.dylib")) (allow file-read-metadata (path "/usr/lib/system/libdispatch.dylib")) (allow file-read-metadata (path "/usr/lib/system/libdyld.dylib")) (allow file-read-metadata (path "/usr/lib/system/libkeymgr.dylib")) (allow file-read-metadata (path "/usr/lib/system/liblaunch.dylib")) (allow file-read-metadata (path "/usr/lib/system/libmacho.dylib")) (allow file-read-metadata (path "/usr/lib/system/libquarantine.dylib")) (allow file-read-metadata (path "/usr/lib/system/libremovefile.dylib")) (allow file-read-metadata (path "/usr/lib/system/libsystem_asl.dylib")) (allow file-read-metadata (path "/usr/lib/system/libsystem_blocks.dylib")) (allow file-read-metadata (path "/usr/lib/system/libsystem_c.dylib")) (allow file-read-metadata (path "/usr/lib/system/libsystem_configuration.dylib")) (allow file-read-metadata (path "/usr/lib/system/libsystem_coreservices.dylib")) (allow file-read-metadata (path "/usr/lib/system/libsystem_coretls.dylib")) (allow file-read-metadata (path "/usr/lib/system/libsystem_dnssd.dylib")) (allow file-read-metadata (path "/usr/lib/system/libsystem_info.dylib")) (allow file-read-metadata (path "/usr/lib/system/libsystem_kernel.dylib")) (allow file-read-metadata (path "/usr/lib/system/libsystem_m.dylib")) (allow file-read-metadata (path "/usr/lib/system/libsystem_malloc.dylib")) (allow file-read-metadata (path "/usr/lib/system/libsystem_network.dylib")) (allow file-read-metadata (path "/usr/lib/system/libsystem_networkextension.dylib")) (allow file-read-metadata (path "/usr/lib/system/libsystem_notify.dylib")) (allow file-read-metadata (path "/usr/lib/system/libsystem_platform.dylib")) (allow file-read-metadata (path "/usr/lib/system/libsystem_pthread.dylib")) (allow file-read-metadata (path "/usr/lib/system/libsystem_sandbox.dylib")) (allow file-read-metadata (path "/usr/lib/system/libsystem_secinit.dylib")) (allow file-read-metadata (path "/usr/lib/system/libsystem_trace.dylib")) (allow file-read-metadata (path "/usr/lib/system/libunc.dylib")) (allow file-read-metadata (path "/usr/lib/system/libunwind.dylib")) (allow file-read-metadata (path "/usr/lib/system/libxpc.dylib")) (allow file-read-metadata (path "/usr/lib/libobjc.A.dylib")) (allow file-read-metadata (path "/usr/lib/libauto.dylib")) (allow file-read-metadata (path "/usr/lib/libDiagnosticMessagesClient.dylib")) (allow file-read-data (path "/dev/dtracehelper")) (allow file-write-data (path "/dev/dtracehelper")) (allow file-ioctl (path "/dev/dtracehelper")) (allow sysctl-read (sysctl-name "kern.usrstack64")) (allow file-read-metadata (path "/usr/share/locale/en_US.UTF-8/LC_COLLATE")) (allow file-read-data (path "/usr/share/locale/la_LN.US-ASCII/LC_COLLATE")) (allow file-read-metadata (path "/usr/share/locale/en_US.UTF-8/LC_CTYPE")) (allow file-read-data (path "/usr/share/locale/UTF-8/LC_CTYPE")) (allow file-read-metadata (path "/usr/share/locale/en_US.UTF-8/LC_MONETARY")) (allow file-read-data (path "/usr/share/locale/en_US.ISO8859-1/LC_MONETARY")) (allow file-read-metadata (path "/usr/share/locale/en_US.UTF-8/LC_NUMERIC")) (allow file-read-data (path "/usr/share/locale/en_US.ISO8859-1/LC_NUMERIC")) (allow file-read-metadata (path "/usr/share/locale/en_US.UTF-8/LC_TIME")) (allow file-read-data (path "/usr/share/locale/en_US.ISO8859-1/LC_TIME")) (allow file-read-metadata (path "/usr/share/locale/en_US.UTF-8/LC_MESSAGES/LC_MESSAGES")) (allow file-read-data (path "/usr/share/locale/en_US.ISO8859-1/LC_MESSAGES/LC_MESSAGES")) (allow file-read-metadata (path "/tmp")) (allow file-read-metadata (path "/private/tmp")) (allow file-read-data (path "/Users/haftandilian")) (allow file-read-metadata (path "/tmp")) (allow file-read-data (path "/private/tmp")) (allow sysctl-read (sysctl-name "hw.pagesize_compat")) ~ $
Using opensnoop(1m) to Observe Content Process File I/O
You can use opensnoop(1m) to see what files the content process is opening. For this listing, I had opensnoop running when Nightly was started so some of these opens likely happened before the content process turned on the sandbox. Passing the -t option to opensnoop will get it to print the stack trace of the user program.
~ $ sudo opensnoop -xve -n plugin-container 2>/dev/null ... 2016 Aug 11 11:25:32 501 2745 plugin-container -1 2 /Users/haftandilian/Library/Autosave Information/org.mozilla.plugincontainer.plist 2016 Aug 11 11:25:47 501 2743 plugin-container -1 2 /System/Library/Components/AppleScript.component/Contents/Resources/Base.lproj 2016 Aug 11 11:25:47 501 2743 plugin-container -1 2 /System/Library/Components/AudioCodecs.component/Contents/Resources/Base.lproj 2016 Aug 11 11:25:47 501 2743 plugin-container -1 2 /System/Library/Components/AudioDSP.component/Contents/Resources/en.lproj 2016 Aug 11 11:25:47 501 2743 plugin-container -1 2 /System/Library/Components/AudioDSP.component/Contents/Resources/Base.lproj 2016 Aug 11 11:25:47 501 2743 plugin-container -1 2 /System/Library/Components/AUSpeechSynthesis.component/Contents/Resources 2016 Aug 11 11:25:47 501 2743 plugin-container -1 2 /System/Library/Components/AUSpeechSynthesis.component/Contents/Resources 2016 Aug 11 11:25:47 501 2743 plugin-container -1 2 /System/Library/Components/AUSpeechSynthesis.component/Contents/Resources/English.lproj 2016 Aug 11 11:25:47 501 2743 plugin-container -1 2 /System/Library/Components/AUSpeechSynthesis.component/Contents/Resources/Base.lproj 2016 Aug 11 11:25:47 501 2743 plugin-container -1 2 /System/Library/Components/CoreAudio.component/Contents/Resources/Base.lproj 2016 Aug 11 11:25:47 501 2743 plugin-container -1 2 /System/Library/Components/JavaScript.component/Contents/Resources/Base.lproj 2016 Aug 11 11:25:47 501 2743 plugin-container -1 2 /System/Library/Components/JavaScript.component/Contents/Resources/English.lproj ...
Use launchctl(1) To Learn About com.apple.* Daemons
You can use the launchctl(1) command to learn a bit about daemons and their associated mach services which may appear in the sandbox rules. For example, below we see com.apple.pasteboard.1 is a Mach service from com.apple.pboard.
$ launchctl list PID Status Label - 0 com.apple.CoreAuthentication.daemon 32729 0 com.apple.quicklook - 0 com.apple.parentalcontrols.check 295 0 com.apple.Finder - 0 com.apple.PackageKit.InstallStatus - 0 com.apple.FontWorker 319 0 com.apple.bird - 0 com.apple.familycontrols.useragent - 0 com.apple.aos.migrate - 0 com.apple.universalaccessAuthWarn 328 0 com.apple.nsurlsessiond - 0 com.apple.syncservices.uihandler 341 0 com.apple.iconservices.iconservicesagent - 0 com.apple.ManagedClientAgent.agent - 0 com.apple.screensharing.agent - 0 com.apple.TMHelperAgent.SetupOffer - 0 com.apple.AddressBook.SourceSync - 0 com.apple.familynotificationd 384 0 com.apple.photolibraryd - 0 com.apple.cfnetwork.cfnetworkagent - 0 com.apple.xpc.otherbsd ... $ launchctl list com.apple.pboard { "EnableTransactions" = true; "LimitLoadToSessionType" = "Aqua"; "MachServices" = { "com.apple.pasteboard.1" = mach-port-object; }; "Label" = "com.apple.pboard"; "TimeOut" = 30; "OnDemand" = true; "LastExitStatus" = 0; "PID" = 299; "Program" = "/usr/sbin/pboard"; "ProgramArguments" = ( "/usr/sbin/pboard"; ); };
Dumping The sandbox_init Policy Argument
This section illustrates using the lldb debugger to inspect the policy string argument to sandbox_init.
$ cat lldb-commands set set target.max-string-summary-length 10000 br set -n sandbox_init c
First run the lldb -w command below which will wait for a process named plugin-container to start. Once the lldb command is waiting, in another window, start up Firefox. If it works, lldb will stop at a breakpoint in sandbox_init. run "thread step-out" to stop after sandbox_init returns. Then print the profile string.
~ $ lldb -w -n plugin-container -s ~/lldb-commands (lldb) process attach --name "plugin-container" --waitfor Process 12427 stopped * thread #1: tid = 0x739526, 0x00007fffb83221de libobjc.A.dylib`readClass(objc_class*, bool, bool) + 46, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP frame #0 libobjc.A.dylib`readClass() libobjc.A.dylib`readClass: -> 0x7fffb83221de <+46>: cmpl $0x40000000, (%rax) ; imm = 0x40000000 0x7fffb83221e4 <+52>: jb 0x7fffb83221ea ; <+58> 0x7fffb83221e6 <+54>: movq 0x8(%rax), %rax 0x7fffb83221ea <+58>: addq $0x18, %rax Executable module set to "/Users/haftandilian/r/mozilla-central/obj-nd.noindex/dist/Nightly.app/Contents/MacOS/plugin-container.app/Contents/MacOS/plugin-container". Architecture set to: x86_64h-apple-macosx. (lldb) command source -s 0 '/Users/haftandilian/lldb-commands' Executing commands in '/Users/haftandilian/lldb-commands'. (lldb) set set target.max-string-summary-length 10000 (lldb) br set -n sandbox_init Breakpoint 1: where = libsystem_sandbox.dylib`sandbox_init, address = 0x00007fffb8e31978 (lldb) c Process 12427 resuming Process 12427 stopped * thread #1: tid = 0x739526, 0x00007fffb8e31978 libsystem_sandbox.dylib`sandbox_init, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 frame #0 libsystem_sandbox.dylib`sandbox_init() libsystem_sandbox.dylib`sandbox_init: -> 0x7fffb8e31978 <+0>: pushq %rbp 0x7fffb8e31979 <+1>: movq %rsp, %rbp 0x7fffb8e3197c <+4>: movq %rdx, %rax 0x7fffb8e3197f <+7>: xorl %edx, %edx
(lldb) thread step-out Process 12427 stopped * thread #1: tid = 0x739526, 0x000000011769a19e XUL`mozilla::StartMacSandbox(aInfo=MacSandboxInfo @ 0x00007fff5a7a52f8, aErrorMessage="") + 2974 at Sandbox.mm:460, queue = 'com.apple.main-thread', stop reason = step out frame #0 XUL`mozilla::StartMacSandbox() at Sandbox.mm:460 457 } 458 459 char *errorbuf = NULL; -> 460 int rv = sandbox_init(profile, 0, &errorbuf); 461 if (rv) { 462 if (errorbuf) { 463 char *msg = NULL; (lldb) print rv (int) $0 = 0 (lldb) print profile (char *) $1 = 0x000000011141a000 "(version 1)\n\n(define sandbox-level 2)\n(define macosMinorVersion 12)\n(define appPath \"/Users/haftandilian/r/mozilla-central/obj-nd.noindex/dist/Nightly.app/Contents/MacOS/plugin-container.app\")\n(define appBinaryPath \"/Users/haftandilian/r/mozilla-central/obj-nd.noindex/dist/Nightly.app/Contents/MacOS/plugin-container.app/Contents/MacOS/plugin-container\")\n(define appDir \"/Users/haftandilian/r/mozilla-central/obj-nd.noindex/dist/Nightly.app/Contents/Resources/browser\")\n(define appTempDir \"/private/var/folders/46/188rdfdn49d3zkkfgrgsnx2m0000gn/T/TemporaryItems/Temp-{48211d85-34c4-aa4a-b38b-fa3f9010bd48}\")\n(define hasProfileDir 1)\n(define profileDir \"/Users/haftandilian/Library/Application Support/Firefox/Profiles/xud2ofc6.parentprinting\")\n(define home-path \"/Users/haftandilian\")\n\n; Allow read access to standard system paths.\n(allow file-read*\n (require-all (file-mode #o0004)\n (require-any (subpath \"/Library/Filesystems/NetFSPlugins\")\n (subpath \"/System\")\n (subpath \"/private/var/db/dyld\")\n (subpath \"/usr/lib\")\n (subpath \"/usr/share\"))))\n\n(allow file-read-metadata\n (literal \"/etc\")\n (literal \"/tmp\")\n (literal \"/var\")\n (literal \"/private/etc/localtime\"))\n\n; Allow read access to standard special files.\n(allow file-read*\n (literal \"/dev/autofs_nowait\")\n (literal \"/dev/random\")\n (literal \"/dev/urandom\"))\n\n(allow file-read*\n file-write-data\n (literal \"/dev/null\")\n (literal \"/dev/zero\"))\n\n(allow file-read*\n file-write-data\n file-ioctl\n (literal \"/dev/dtracehelper\"))\n\n; Used to read hw.ncpu, hw.physicalcpu_max, kern.ostype, and others\n(allow sysctl-read)\n\n(begin\n (deny default)\n (debug deny)\n\n (define resolving-literal literal)\n (define resolving-subpath subpath)\n (define resolving-regex regex)\n\n (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 (profile-subpath profile-relative-subpath)\n (resolving-subpath (string-append profileDir profile-relative-subpath)))\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 (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 (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\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\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.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\n; bug 1312273\n (if (= macosMinorVersion 9)\n (allow mach-lookup (global-name \"com.apple.xpcd\")))\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 (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/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\n; Per-user and system-wide Extensions dir\n (allow file-read*\n (home-regex \"/Library/Application Support/[^/]+/Extensions/[^/]/\")\n (resolving-regex \"/Library/Application Support/[^/]+/Extensions/[^/]/\"))\n\n; The following rules impose file access restrictions which get\n; more restrictive in higher levels. When file-origin-specific\n; content processes are used for file:// origin browsing, the\n; global file-read* permission should be removed from each level.\n\n; level 1: global read access permitted, no global write access\n (if (= sandbox-level 1) (allow file-read*))\n\n; level 2: global read access permitted, no global write access,\n; no read/write access to ~/Library,\n; no read/write access to $PROFILE,\n; read access permitted to $PROFILE/{extensions,weave,chrome}\n (if (= sandbox-level 2)\n (if (not (zero? hasProfileDir))\n ; we have a profile dir\n (begin\n (allow file-read* (require-all\n (require-not (home-subpath \"/Library\"))\n (require-not (subpath profileDir))))\n (allow file-read*\n (profile-subpath \"/extensions\")\n (profile-subpath \"/weave\")\n (profile-subpath \"/chrome\")))\n ; we don't have a profile dir\n (allow file-read* (require-not (home-subpath \"/Library\")))))\n\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\n; bug 1201935\n (allow file-read*\n (home-subpath \"/Library/Caches/TemporaryItems\"))\n\n; bug 1237847\n (allow file-read*\n (subpath appTempDir))\n (allow file-write*\n (subpath appTempDir))\n)\n"
TODO: automatically convert that (interpret \n's and \"'s etc.) to a policy that is accepted by sandbox-exec(1).