Seatbelt
Seatbelt, also known as sandbox, is a kernel extension that restricts a set of features from being used for some processes.
Contents
Applying sandbox to your app
It is a good idea to apply a sandbox to restrict what your app can do, esp. for setuid apps, in case a vulnerability is found (well maybe not needed for iPhoneOS...). The documented way of applying a sandbox is
#include <sandbox.h> char* errbuf; int errcode = sandbox_init("profile", SANDBOX_NAMED, &errbuf); ... sandbox_free_error(errbuf);
Once a sandbox is applied, you cannot jump out from the sandbox anymore.
There are 5 documented profiles
- 0. kSBXProfileNoNetwork (= "nonet")
- 1. kSBXProfileNoInternet (= "nointernet")
- 2. kSBXProfilePureComputation (= "pure-computation")
- 3. kSBXProfileNoWriteExceptTemporary (= "write-tmp-only")
- 4. kSBXProfileNoWrite (= "nowrite")
and 9 undocumented profiles:
- 5. "sandbox-compilerd"
- 6. "mDNSResponder"
- 7. "apsd"
- 8. "AppleDiags"
- 9. "PasteBoard"
- 10. "container" (Having the same restriction as AppStore apps.)
- 11. "MobileSafari"
- 12. "MobileMail"
- 13. "MobileMaps"
Definition of profiles
container
The 2.x .sb template |
---|
(version 1) (deny default) ; Sandbox violations get logged to syslog via kernel logging. (debug deny) (allow sysctl-read) ; Mount / umount commands (deny file-write-mount file-write-umount) ; System is read only (allow file-read*) (deny file-write*) ; NOTE: Later rules override earlier rules. ; Private areas (deny file-write* (regex "^/private/var/mobile/Applications/.*$")) (deny file-read* (regex "^/private/var/mobile/Applications/.*$")) ; SQLite uses /private/var/tmp ; TBR: <rdar://problem/5805879> SQLite doesn't honor the TMPDIR environment variable (allow file-write* (regex "^/private/var/tmp(/|$)")) (allow file-read* (regex "^/private/var/tmp(/|$)")) ; TBR: <rdar://problem/5806524> (allow process-exec (regex "^/private/var/tmp$")) ; TBR: <rdar://problem/5830139> (allow file-write* (regex "^/private/var/tmp/UpdatedSnapshots/$")) ; Permit reading and writing in the App container (allow file-read* (regex "^/private/var/mobile/Applications/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX(/|$)")) (allow file-write* (regex "^/private/var/mobile/Applications/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/(tmp|Library|Documents)(/|$)")) (allow process-exec (regex #"^/private/var/mobile/Applications/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/.*\.app(/|$)")) ; Allow Address book access via filesystem ; This is an SQLite3 database - there is room to make the rules tighter (allow file-write* (regex "^/private/var/mobile/Library/AddressBook(/|$)")) (allow file-read* (regex "^/private/var/mobile/Library/AddressBook(/|$)")) ; Allow keyboard db access via filesystem ; This is a custom file format. There is room to make the rules tighter (allow file-write* (regex "^/private/var/mobile/Library(/Keyboard)?(/|$)")) (allow file-read* (regex "^/private/var/mobile/Library(/Keyboard)?(/|$)")) ; Pictures, but not other media ; Allow photo access via filesystem. There is room to make the rules tighter (deny file-write* (regex "^/private/var/mobile/Media(/|$)")) (deny file-read* (regex "^/private/var/mobile/Media/")) (allow file-write* (regex "^/private/var/mobile/Media/com.apple.itunes.lock_sync$")) (allow file-read* (regex "^/private/var/mobile/Media/com.apple.itunes.lock_sync$")) (allow file-write* (regex "^/private/var/mobile/Media/DCIM(/|$)")) (allow file-read* (regex "^/private/var/mobile/Media/DCIM(/|$)")) (allow file-read* (regex "^/private/var/mobile/Media/Photos(/|$)")) ; Mach lookups. There is room to make the rule tighter. (allow mach-lookup) ;; (global-name "PurpleSystemEventPort") ;; (global-name "com.apple.CARenderServer") ;; (global-name "com.apple.eventpump") ;; (global-name "com.apple.springboard.migserver") ;; (global-name "com.apple.system.notification_center")) (deny process-fork) ; For ASL logs - /var/run/asl_input (XXX: socket can now be named) ; (allow network-outbound) ; (to unix-socket "/private/var/run/asl_input")) (allow network*) ; To allow crash reporter / exceptions to kill the process (allow signal (target self)) |
MobileSafari
Same as MobileMail but /var/mobile/Media/Safari/ is also read/writable.
MobileMail
- UNIX sockets cannot be used.
- The following files and directories cannot be read:
- /var/mobile/Applications/*
- /var/mobile/Media/* (except DCIM/, com.apple.itdbprep.postprocess.lock and com.apple.itunes.lock_sync)
- /var/mobile/Library/Caches/com.apple.mobile.installation.plist
- /usr/sbin/fairplayd
- The filesystem by default is read-only, but the following directories can be written:
- /var/mobile/Library/*
- /var/mobile/Media/DCIM/*
- /tmp/*
MobileMaps
Based on MobileMail but
- /var/logs cannot be read.
- /var/mobile/Library/Caches/com.apple.UIKit.pboard/* cannot be read.
- /var/mobile/Media/* cannot be written.
- /var/mobile/Library/* cannot be written, except:
- /var/mobile/Library/Caches/Maps/*
- /var/mobile/Library/Keyboard/*
- /var/mobile/Library/Maps/*
- /var/mobile/Library/SMS/*
PasteBoard
Everywhere is read-only, except:
- /var/mobile/Library/Caches/com.apple.UIKit.pboard/*
- /tmp/*
AppleDiags
Based on MobileMail but
- /var/mobile/Media/* can be read.
- /var/mobile/Library/Caches/com.apple.mobile.installation.plist can be read.
- /var/mobile/Library/* cannot be written, except:
- /var/mobile/Library/AddressBook/*
- /var/mobile/Library/Keyboard/*
- /var/mobile/Library/Logs/CrashReporter/*
- /var/mobile/Library/Preferences/*
apsd, mDNSResponder
The filesystem cannot be accessed at all.
sandbox-compilerd
Only /var/* can be accessed freely.
Creating your own sandbox definition
A sandbox definition should be a Scheme file with extension .sb. If a non-built-in profile is given, a .sb placed in one of:
- /usr/share/sandbox/*.sb
- /private/var/mobile/Applications/*.sb
shall be compiled and sandboxed by this definition. (You can also provide a complete path.) However, due to the lack of sandboxd the .sb files cannot be compiled, so assume this feature isn't there yet.
Working around the sandbox
While sandbox is a nice security feature, it is sometimes too restrictive for a MobileSubstrate extension. Since the sandbox is implemented as a kernel feature it's impossible to workaround it. For example, an MS extension targeting AppStore app can only write in /var/mobile, but most of the /var/mobile itself is unreadable due to sandboxing. But there are a few places that the sandbox cannot apply, so AppStore apps may store data in these places. They are:
- Anything in the container itself (of course).
- ~/* except the Media and Library subfolders, which only the following directories are readable:
- ~/Media/DCIM/*
- ~/Media/Photos/*
- ~/Library/AddressBook/*
- ~/Library/Keyboard/*
- ~/Library/Preferences/*
An AppStore app itself can also read/write to these folders, even without jailbreaking (in principle), but they must be accessed via a symlink. Doing so allows easy cross-app data sharing, but that may violate the AppStore rules.
Kernel debug messages regarding the sandbox
You can turn on kernel debug messages from the Seatbelt.kext with this command:
sysctl -w security.mac.seatbelt.debug=<integer>
where the integer is a bit-field, with purposes:
- 1 = Memory management (reference counting) messages. Very verbose, do not turn it on.
- 2 = Function hook messages.
- 4, 8, 16, 32, 64, 128 = ???
Set to 0 to turn off everything.