Dev:Seatbelt

From The Apple Wiki

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

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