How are child processes sandboxed?

My app is sandboxed (and cannot open or write any file). I was curious what happened to child processes. I had my app execute a bash script (that just writes to a file). The behaviour was expected: the script, launched by my sandboxed app, was sandboxed too.


However, when I tried to have my app launch another app (not mine), the child app was not sandboxed. I was curious what was different?


I launch my script with


[task setLaunchPath: @"/bin/bash"];

[task setArguments:@[@"path/to/script.sh"]];

[task launch];

and my app with


[task setLaunchPath: @"/usr/bin/open"];

[task setArguments:@[@"-a", @"/Applications/some.app"]];

[task launch];


Note that the same problem happens when launching the app with [[NSWorkspace sharedWorkspace] launchApplication:@"/Applications/some.app"]; and with posix_spawn.


Apple's docmentions that child processes should inherit sandbox properties, but also mentions that helper apps should include some entitlements properties to do so.
What behaviour should we see? Also, how could I make child processes inherit from sandbox properties?
Thanks
Thomas

Accepted Reply

You aren't actually doing the same things in those two examples. In the first example, you are running bash with the given script. That runs in your app's sandbox. In the second example, you are running the "open" tool and giving it the path to an app. That is an Apple tool that essentially does the same thing as NSWorkspace. It launches the app as if the user had double-clicked on it. In this situation, it isn't a child process of your app. That means you can't control it like you would a child process. Technically speaking, I think the "open" tool is running under your app's sandbox, but it can call NSWorkspace just like your app can, which gets out of the sandbox.

Replies

The sandbox is called the App Sandbox, and that’s for a reason. As far as public API is concerned, you can only sandbox apps (and app-like things, like app extensions, system extensions, and XPC Services). Things that aren’t apps always inherit the sandbox from the parent process.

If you bundle such a program in your product, you must set:

However, this just marks the program as inheriting its sandbox, it doesn’t actually trigger the inheritance; that’s something that happens by default.

In contrast, if you run an app, it switches to its own sandbox.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

You aren't actually doing the same things in those two examples. In the first example, you are running bash with the given script. That runs in your app's sandbox. In the second example, you are running the "open" tool and giving it the path to an app. That is an Apple tool that essentially does the same thing as NSWorkspace. It launches the app as if the user had double-clicked on it. In this situation, it isn't a child process of your app. That means you can't control it like you would a child process. Technically speaking, I think the "open" tool is running under your app's sandbox, but it can call NSWorkspace just like your app can, which gets out of the sandbox.