Sandbox/Mac/Debugging

From MozillaWiki
< Sandbox‎ | Mac
Jump to: navigation, search


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).