Method for privileged action using Framework

I'm exploring using a handful of frameworks to share code between macOS apps. However, one of these frameworks needs privilege to function. The main app has a helper tool utilizing SMAppService. However, I can't work out if there's a feasible way to use that helper tool to support the framework dependency. Should I be creating a second helper tool for the framework instead? Or am I barking up the wrong tree?

Thanks!

Answered by DTS Engineer in 820340022

Privileges are determined by the process in one of two ways:

  • Some privileges are based on the process’s execution context. The canonical example of this is BSD’s EUID value, which is central to file system permissions.

  • Some privileges are based on the identity of the responsible code. These are the things you see in System Settings > Privacy & Security, like whether you can access camera or microphone.

Regardless, privileges apply to all code running within the process. So, if the process calls code that’s in a framework, that code has the process’s privileges.

Using a framework in a privileged helper tool used to be tricky because the traditional mechanisms for installing such a tool would copy the tool to a new location. That prevented the copy from linking to a framework with an rpath-relative reference, that is, the standard mechanism whereby an app links to frameworks. Instead, you’d have to use a full path, and then you have to install the framework at that path.

Note If you’re curious about the details, I dig into both of these options in Dynamic Library Identification.

However, that’s not a problem with SMAppService. If you install a daemon using SMAppService, it’s typical for the launchd job to reference the executable via the BundleProgram property. That means that your process runs directly from your app’s bundle, so it can reference frameworks embedded in the app bundle in the standard way.

Share and Enjoy

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

Let’s see if I understand this correctly:

  • You have an app.

  • It has an embedded framework.

  • It also has an embedded privileged helper tool that you install with SMAppService.

  • You want the helper tool to be able to use the framework.

Is that right?

Share and Enjoy

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

If the framework will then be able to perform privileged operations, then yes. 😉

Thanks!

Privileges are determined by the process in one of two ways:

  • Some privileges are based on the process’s execution context. The canonical example of this is BSD’s EUID value, which is central to file system permissions.

  • Some privileges are based on the identity of the responsible code. These are the things you see in System Settings > Privacy & Security, like whether you can access camera or microphone.

Regardless, privileges apply to all code running within the process. So, if the process calls code that’s in a framework, that code has the process’s privileges.

Using a framework in a privileged helper tool used to be tricky because the traditional mechanisms for installing such a tool would copy the tool to a new location. That prevented the copy from linking to a framework with an rpath-relative reference, that is, the standard mechanism whereby an app links to frameworks. Instead, you’d have to use a full path, and then you have to install the framework at that path.

Note If you’re curious about the details, I dig into both of these options in Dynamic Library Identification.

However, that’s not a problem with SMAppService. If you install a daemon using SMAppService, it’s typical for the launchd job to reference the executable via the BundleProgram property. That means that your process runs directly from your app’s bundle, so it can reference frameworks embedded in the app bundle in the standard way.

Share and Enjoy

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

There is no default framework search path for the helper tool. As a result, the helper crashes at launch because it can't find the framework. What's the search path to look in the parent directory?

For reference, the crash report includes this:

Library not loaded: @rpath/MyFramework.framework/Versions/A/MyFramework

I think I figured it out. In any event, the helper is no longer crashing. I added

@executable_path/../Frameworks 

to Runpath Search Paths in the helper's build settings.

Thanks!

Method for privileged action using Framework
 
 
Q