Struggling with SMJobBless in a sandboxed app

I've got an app that is sandboxed, and it requires a privileged helper. I've worked through the EBAS sample app with various updates to conform with current systems. After a lot of work, I've got to a point where I'm stumped.

The Python script SMJobBlessUtil.py returns this error, and I don't know what to do to correct it:

<path to helper tool>: tool __TEXT / __info_plist section dump malformed (2)

I've gone over the various settings numerous times. It doesn't fail for the EBAS sample, but does for my app. Looking at the binary, the __info_plist sections look identical apart from identifiers. This is what mine looks like (identifiers deleted):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>CFBundleIdentifier</key>
        <string>***</string>
        <key>CFBundleInfoDictionaryVersion</key>
        <string>6.0</string>
        <key>CFBundleName</key>
        <string>***</string>
        <key>CFBundleVersion</key>
        <string>1.0</string>
        <key>SMAuthorizedClients</key>
        <array>
                <string>anchor apple generic and identifier "***" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "***")</string>
        </array>
</dict>
</plist>

I must be missing something, but I've run out of ideas on where to find it. Anybody got a pointer?

One potential workaround is to add the -v flag, which causes otool to print the property list as text.

I just discovered another potential workaround here, namely to use segedit with extract the __TEXT / __info_plist section. This is not without its complications though. See the segedit man page for the details.

Share and Enjoy

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

@mikeyh

Updated SMJobBlessUtil-python3.py with workaround for otool arm64 weirdness: https://gist.github.com/mikeyh/89a1e2ecc6849ff6056b7391c5216799

I tried your latest version of the SMJobBlessUtil-python3.py tool (thank you for it, btw!), but I get the following error:

tool __TEXT / __info_plist section dump malformed (1)

implying that the output of the otool command is empty, which indeed I find:

> otool -V -arch arm64 -s __TEXT __info_plist <helper tool>
>

Whereas, if I use x86:

> otool -V -arch x86_64 -s __TEXT __info_plist <helper tool>
(__TEXT,__info_plist) section
<?xml version="1.0" encoding="UTF-8"?>
...
</plist>

In the previous script version, it was extracting the hex dump, which I get with this (same without the -arch option)

> otool -arch x86_64 -s __TEXT __info_plist <helper tool>
Contents of (__TEXT,__info_plist) section
0000000100003b06	3c 3f  ...
...

So your previous version of the script works for me, but not the latest one with the arm64 weirdness fix. I conclude this is because the helper tool is only being built for x86_64, but I am on an M1 MacBook. So I may not be in the same situation as the original person who asked the question, but I think the script may need a modification to handle this case.

After a long hiatus, I am back working on this application. I have got to the point where the plists are set up correctly, as far as I can tell, and running SMJobBlessUtil-python3.py check doesn't report any errors. However, the call to SMJobBless fails with Error Domain=CFErrorDomainLaunchd Code=2. Searching for this leads to problems with the location of the helper tool, but it is exactly where it is supposed to be.

I've gone through everything that I can think of to verify that it looks like the EBAS sample code, which is working on my system (macOS 14.2.1, Xcode 15.2, M1 mac). Does anyone have any specific pointers to places that I can check further? Or, if more information is needed, what should I provide/

I’m not entirely sure what’s going wrong with SMJobBless, but:

  • Just to be clear, you can’t use SMJobBless from a sandboxed app.

  • SMJobBless has largely been replaced by SMAppService, which can install a daemon.

SMAppService has two benefits:

  • It’s much (much much much) easier to use.

  • It can be used for in a sandboxed app, even when installing a daemon [1].

Give it a whirl!

Share and Enjoy

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

[1] The caveat here is that, starting with macOS 14.2, the daemon itself must be sandboxed.

Just to be clear, you can’t use SMJobBless from a sandboxed app.

Yes, this is using a non-sandboxed XPC service (essentially the EBAS code), so it shouldn't be running into that sort of problem.

SMJobBless has largely been replaced by SMAppService, which can install a daemon.

I was hoping to still support macOS 12, while SMAppService is macOS 13 and later. But if I have to switch, I can.

[1] The caveat here is that, starting with macOS 14.2, the daemon itself must be sandboxed.

That probably nukes my use-case, unfortunately. The daemon has to be able to move files and folders (well, bundles) into and out of specific folders within /Library, which is presumably not allowed in a sandboxed daemon.

I was given an entitlement to allow secure file system access, but you can't move folders with that, and so I was thrown back to SMJobBless, but even that avenue looks like it's closing.

The daemon has to be able to move files and folders (well, bundles) into and out of specific folders within /Library, which is presumably not allowed in a sandboxed daemon.

You can use a temporary exception entitlement for that.

ps To be clear, “temporary” might not mean what you think it means. See here.

Share and Enjoy

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

Struggling with SMJobBless in a sandboxed app
 
 
Q