First and foremost, a warning that's prominently displayed in all sandbox definition files:
WARNING: The sandbox rules [..] currently constitute Apple System Private Interface and are subject to change at any time and
without notice. The contents of this file are also auto-generated and not user editable; it may be overwritten at any time.
The sandbox being a private interface is probably the reason why the sandbox policy files are un-documented. However, in the standard Snow Leopard install there are a bunch of files that define sandboxing policies ( under /System/Library/Sandbox/Profiles/ and /usr/share/sandbox/) that can be used to derive new policy files.
When creating a policy file for HTTP, the most verbose section out of our sandbox definition turns out to be the section for allowing DNS queries.
Our test program runs a couple of functions - a curl based HTTP client and a file read operation.
As expected, once the sandbox is initialized, HTTP requests go through but the file access operation is denied:
Attempts to go out of the sandbox are logged in syslog:
WARNING: The sandbox rules [..] currently constitute Apple System Private Interface and are subject to change at any time and
without notice. The contents of this file are also auto-generated and not user editable; it may be overwritten at any time.
The sandbox being a private interface is probably the reason why the sandbox policy files are un-documented. However, in the standard Snow Leopard install there are a bunch of files that define sandboxing policies ( under /System/Library/Sandbox/Profiles/ and /usr/share/sandbox/) that can be used to derive new policy files.
When creating a policy file for HTTP, the most verbose section out of our sandbox definition turns out to be the section for allowing DNS queries.
http.sb
(version 1)
(debug deny)
;; DNS
(allow file-read-metadata
(literal "/var")
(literal "/etc"))
(allow ipc-posix-shm)
(allow mach-lookup
(global-name "com.apple.SystemConfiguration.configd")
(global-name "com.apple.system.notification_center"))
(allow network-outbound
(remote unix-socket (path-literal "/private/var/run/mDNSResponder")))
;; HTTP traffic
(allow network-outbound (remote ip4 "*:80"))
(deny default)
Our test program runs a couple of functions - a curl based HTTP client and a file read operation.
test.c
#include <sandbox.h>
#include <stdio.h>
#include <curl/curl.h>
size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp)
{
int i=0;
//exit after 80 chars
for(;i<size * nmemb && i < 80;i++)
fprintf(stderr, "%c", (unsigned char)((char *)buffer)[i]);
fprintf(stderr, "[..]\n");
}
int httpRequest()
{
CURL * easyhandle = curl_easy_init();
curl_easy_setopt(easyhandle, CURLOPT_URL, "http://loudhush.ro/changelog.txt");
curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_perform(easyhandle);
}
int readFile()
{
FILE * f = fopen("/etc/passwd", "r");
if(f == NULL)
{
perror("Error opening file");
return 1;
}
char line[1024];
while(fgets(line, 1023, f) != NULL)
fprintf(stdout, "Line: %s", line);
fclose(f);
return 0;
}
int main()
{
char * errbuf;
int retval = sandbox_init("/Users/diciu/Programming/sandbox/http.sb", SANDBOX_NAMED, &errbuf);
if(retval)
{
fprintf(stderr, "Sandbox init error: %s\n", errbuf);
return 1;
}
fprintf(stderr, "--- HTTP request ---\n");
httpRequest();
fprintf(stderr, "\n--- File read request ---\n");
readFile();
}
As expected, once the sandbox is initialized, HTTP requests go through but the file access operation is denied:
cristi:sandbox diciu$ ./a.out
--- HTTP request ---
LoudHush 1.3.21
- Fixed a couple of leaks in AccountController/Management
- Fix[..]
--- File read request ---
Error opening file: Operation not permitted
Attempts to go out of the sandbox are logged in syslog:
Jan 6 14:13:37 cristi sandboxd[59224]: a.out(59222) deny file-read-data /private/etc/passwd