Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Launching executable with NSTask - Sandboxing problems?

I have an Mac OSX application that launches a executable located in /Contents/Resources. The application is not intended to be released on App Store and so I don't have sandbox turned on.

The launch code:

toolPath = [[[NSBundle mainBundle] pathForResource:@"myexecutable" ofType:@""] copy];
task = [[NSTask alloc] init];
[task setLaunchPath: toolPath];
pipe = [[NSPipe alloc] init];
[task setArguments:[NSArray arrayWithObjects:@"-someArg", someVariable, nil]];
file = [[NSFileHandle alloc] initWithFileDescriptor:[pipe fileHandleForReading].fileDescriptor];
[task setStandardOutput: stderrPipe];
[task launch];

The thing is - this all works fine when running in Xcode. It also works fine when exporting the application to desktop and running it.

However, if I zip the application, upload it to a webserver, and then download it on the same computer (or dropbox it to another Mac), the task no longer launches! I get no error in the system console or anything.

I researched some on this problem and found that OSX will mark a new applicaton as "quarantined" special permission right. So I investigated the difference between the downloaded app and the exported app:

Permissions on the executable after exporting my application from Xcode:

-rwxr-xr-x  1 Username  staff   65724 21 Jul 16:31 executableName

At this point the app works fine and the executable is launched from a button inside the app.

And after zipping the application, uploaded to server, downloaded, unzipped, and opening the application and accepting the "This application was downloaded from internet" dialogue:

-rwxr-xr-x  1 Username  staff   65724 21 Jul 16:31 executableName
    com.apple.quarantine        26 

At this point nothing happens when I push the button in my app.

If I then run xattr -rd com.apple.quarantine on the whole app, the quarantine notice is removed:

-rwxr-xr-x  1 Username  staff   65724 21 Jul 16:31 executableName

but the executable is still not being launched!

At this point I now have the following permissions on my desktop app:

/Contents/MacOS:

-rwxr-xr-x  1 Username  staff  407728 21 Jul 16:31 appName

/Contents/Resources:

-rwxr-xr-x  1 Username  staff   65724 21 Jul 16:31 executableName

And on the downloaded app which I used xattr -rd on:

/Contents/MacOS:

-rwxr-xr-x  1 Username  staff  407728 21 Jul 16:31 appName

/Contents/Resources:

-rwxr-xr-x  1 Username  staff   65724 21 Jul 16:31 executableName

The first app works fine and the second one never launches the executable. What the heck is going on? It's the same app, on the same computer, with the same permissions, but the downloaded one just doesnt work.

This problem appears across all OSX versions on different computers.

like image 448
Oskar Avatar asked Jul 21 '13 15:07

Oskar


People also ask

Are macOS applications sandboxed?

The App Sandbox is an access control technology that macOS provides and enforces at the kernel level. The sandbox's primary function is to contain damage to the system and the user's data if the user executes a compromised app.

How do I turn off Sandbox on Mac?

Edit the desktop copy of the file with TextEdit. You should find within the file, the text representation (xml) of the Entitlements for the app. Find the Sandbox entitlement flag (usually set to <true/>) and change it to <false/>. You will have to unlock the file when editing.


1 Answers

Adding the com.apple.security.inherit entitlement to the helper app solved this problem for me.

My helper app used to crash with Could not set sandbox profile data: Operation not permitted (1) when I tried to start it with NSTask.

from Apple documentation:

If your app employs a child process created with either the posix_spawn function or the NSTask class, you can configure the child process to inherit the sandbox of its parent. However, using a child process does not provide the security afforded by using an XPC service.

To enable sandbox inheritance, a child target must use exactly two App Sandbox entitlement keys: com.apple.security.app-sandbox and com.apple.security.inherit. If you specify any other App Sandbox entitlement, the system aborts the child process. You can, however, confer other capabilities to a child process by way of iCloud and notification entitlements.

The main app in an Xcode project must never have a YES value for the inherit entitlement.

I hope this solution helps.

like image 145
helioz Avatar answered Nov 12 '22 15:11

helioz