Seatbelt, also known as sandbox, is a kernel extension that restricts a set of features from being used for some processes.
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
- kSBXProfileNoWriteExceptTemporary (= "write-tmp-only")
- kSBXProfileNoInternet (= "nointernet")
- kSBXProfileNoNetwork (= "nonet")
- kSBXProfileNoWrite (= "nowrite")
- kSBXProfilePureComputation (= "pure-computation")
and 9 undocumented profiles:
- "sandbox-compilerd"
- "mDNSResponder"
- "apsd"
- "AppleDiags"
- "PasteBoard"
- "MobileSafari"
- "MobileMail"
- "MobileMaps"
- "container" (Having the same restriction as AppStore apps.)
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, I haven't successfully compiled any .sb files (kernel emitting error 54), so assume this feature isn't there yet.
Oasis in the sandbox around /var/mobile
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.