Multiple Executables in a Single Bundle Fails to Launch Others After Codesign

We have a rather complex network of dependencies for our application stack and, from it, we create multiple unique executables that are placed into the Contents/MacOS directory of our bundle.

MyApp.app
`- Contents/
`- Frameworks/...
`- MacOS/
`- exec_a
`- exec_b
`- Resources/...

Both executables require the same dependencies (and use the same shared .dylib files built as targets in the same project) so it makes sense for them to be in the same place rather than in their own .app folder as I understand it.

Qt Libs -> core_lib.dylib -> gui_lib.dylib -> exec_a
`-> exec_b

etc.

We've confirmed build artifacts are correct and the rpath/dependencies are all clean. When in development, all executables run as expected and we can command exec_a (the executable we're listing in the primary Info.plist) to launch exec_b at any time.

Once the bundle is signed, however, we cannot get exec_b to launch in any capacity. Even lldb dies right away because it can't attach to anything. We assume this is something in the gatekeeper area of blocking these additional executables.

We get the following when trying to run those additional exes in any way:

Trace/BPT trap: 5

We're using macdeployqt to finalize the bundle and bring in the correct packages - perhaps something it's doing is causing the additional executables to fail or we're missing an entitlement.

We've submitted the app to TestFlights successfully even with these invalid executables to see if there was something the processing of the app would find but so far nothing.

We've seen other example of applications with multiple executables in the same MacOS directory and are wondering what the difference is. Any hints or guidance would be great. Thank you!

Answered by DTS Engineer in 831614022

It should be possible to get this setup working.

You mentioned TestFlight, which suggests you’re targeting the Mac App Store. If so, all your executables must be sandboxed. If you plan to spawn exec_a as a child process of exec_b then exec_b has to use sandbox inheritance. See Resolving App Sandbox Inheritance Problems.

The other potential gotcha is entitlements. If exec_a uses restricted entitlements [1] then those entitlements get authorised by the provisioning profile embedded in the app bundle. If exec_b also needs restricted entitlements then things get trickier. So, does exec_b need any restricted entitlements?

A restricted entitlement is one that must be authorised by a profile, as explained in TN3125 Inside Code Signing: Provisioning Profiles.

Finally, I have a bunch of hints and tips on this topic in Resolving Trusted Execution Problems.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Which it’ll need for a TestFlight deployment, as explained in •.

It should be possible to get this setup working.

You mentioned TestFlight, which suggests you’re targeting the Mac App Store. If so, all your executables must be sandboxed. If you plan to spawn exec_a as a child process of exec_b then exec_b has to use sandbox inheritance. See Resolving App Sandbox Inheritance Problems.

The other potential gotcha is entitlements. If exec_a uses restricted entitlements [1] then those entitlements get authorised by the provisioning profile embedded in the app bundle. If exec_b also needs restricted entitlements then things get trickier. So, does exec_b need any restricted entitlements?

A restricted entitlement is one that must be authorised by a profile, as explained in TN3125 Inside Code Signing: Provisioning Profiles.

Finally, I have a bunch of hints and tips on this topic in Resolving Trusted Execution Problems.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Which it’ll need for a TestFlight deployment, as explained in •.

Quinn! Thank you for your efforts and details. Your posts on this forum have been a lifesaver for those of us new to the world of Apple development/deployment.

Current Entitlements

Each of our executables require the same entitlements:

  • com.apple.security.app-sandbox
  • com.apple.security.cs.disable-library-validation
  • com.apple.security.files.user-selected.read-write
  • com.apple.security.network.client
  • com.apple.security.network.server

From the research into the articles you posted, it seems like these are all safe to inherit but I could be wrong about that! And if it's all going to TestFlight then I suppose it's restricted? The lib validation is disabled because we include a plugin ecosystem through Qt.

I've tried adding the com.apple.security.inherit in our entitlements but am still seeing the same issue.

Here's the entitlements for the exec_b (and exec_a)

> codesign -d --entitlements - exec_b
Executable=/Users/foo/src/SomeApp.app/Contents/MacOS/exec_b
[Dict]
[Key] com.apple.security.app-sandbox
[Value]
[Bool] true
[Key] com.apple.security.cs.disable-library-validation
[Value]
[Bool] true
[Key] com.apple.security.files.user-selected.read-write
[Value]
[Bool] true
[Key] com.apple.security.inherit
[Value]
[Bool] true
[Key] com.apple.security.network.client
[Value]
[Bool] true
[Key] com.apple.security.network.server
[Value]
[Bool] true

Syslog

I then moved through the Console.app and found that, upon launching the errant executable from the command line, this form of error is logged:

Unable to get bundle identifier for container id exec_b: Unable to get bundle identifier because Info.plist from code signature information has no value for kCFBundleIdentifierKey.

I assume this is due to trying to launch the non-default application in the bundle. Is there any means of spelling out this is a valid application without a snarly bundle and symlink web?

Cheers

Written by mmccartney in 831680022
Each of our executables require the same entitlements:

This is potentially confusing, so let’s go to a table:

Entitlement App Child
----------- --- -----
….app-sandbox true true
….inherit - true
….cs.disable-library-validation true true
….files.user-selected.read-write true -
….network.client true -
….network.server true -

In this table:

  • App is your main application and Child is any program is spawns as a child process.

  • - indicates that the entitlement shouldn’t be claimed at all. In general, you shouldn’t claim an entitlement with a false value, that just causes confusion.

For the last three rows, you don’t need to, and mustn’t claim, the entitlement because these are part of your static sandboxed, which is what the second row is about.

Written by mmccartney in 831680022
And if it's all going to TestFlight then I suppose it's restricted?

None of the above entitlements are restricted.

To deploy to TestFlight you’ll need to:

  • Add com.apple.application-identifier and com.apple.developer.team-identifier to your App.

  • Embed a profile in your App.

That should be sufficient given your current setup. The Child programs don’t need their own App ID because they don’t claim any restricted entitlements. If they did, things would get more complex.

See TestFlight, Provisioning Profiles, and the Mac App Store for more about the TestFlight side of this.

Written by mmccartney in 831680022
I then moved through the Console.app and found that, upon launching the errant executable from the command line

Right. Because Terminal has no sandbox, and thus there’s nothing for com.apple.security.inherit to inherit. When embedding a tool in a Mac App Store app, you must apply com.apple.security.app-sandbox. After that you have a stark choice:

  • If you want to spawn that tool as a child process of your app, apply com.apple.security.inherit. Such tools can’t be executed from Terminal.

  • If you want to run the tool some other way, don’t apply com.apple.security.inherit. You won’t be able spawn the tool as a child process of your app. Rather, it’ll start with its own sandbox.

My understanding is that you only care about the first case. If so, we’re done. If you need the second case as well, lemme know because there are further steps necessary.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Multiple Executables in a Single Bundle Fails to Launch Others After Codesign
 
 
Q