Ensuring own Framework continues to be loadable by other apps, which may be Hardened and/or Sandboxed

Hi,


My software installs frameworks in the local domain (/Library/Frameworks) that are accessed from third-party apps. Some of these apps are simply code-signed, others are sandboxed. They are obviously signed by other companies, and so far there have been no problems on the part of DYLD in loading and executing code inside our frameworks. The loader is happy to continue looking for our framework outside the app container, in the case of sandboxed apps.


What changes are necessary to ensure that our frameworks remain accessible from hardened apps? Hardened Runtime, to the best of my understanding, only allows executables to load code that has been code-signed by the same team, or by Apple. I also think that hardened runtime affects only executables, and yet when I enable the ENABLE_HARDENED_RUNTIME setting in Xcode on my framework targets (via xcconfig) it clearly influences the way they are signed, and suddenly these "hardened frameworks" fail to be loaded by third-party apps, even if these apps aren't yet hardened themselves. In what its perhaps the key to solving this issue, how can one mark non-app targets to enable the library-validation exception? Why would a non-hardened app fail to load code whose only difference may be a simple flag (kill,runtime) in its signature?


Maybe I'm wrong to assume that non-app targets deserve any special treatment, but the fact remains that when I enable hardened runtime, our code simply stops being "seen" and loaded by DYLD, with all other variables remaining identical.


Thank you!

Gabe

Replies

Hello,


I'm having the same problem. Built a piece of code as an external framework which can be optionally installed (in Library/Frameworks).


This worked fine until I've enable hardened runtime in my mac os app (even with the "Disable Library Validation" option set).


Both app and framework have the LC_VERSION_MIN set to 10.9, as suggested in this thread:

https://forums.developer.apple.com/thread/115451


Both app and framework are signed by me. The application is not sandboxed.


Any suggestions?

See my response to your other post.

Oh, while I’m here, I thought I’d post an update on this issue…

I worked with FxFactory in a different context to uncover the root cause of their problem. It turns out that this was a

LC_VERSION_MIN
issue, although not one they can fix directly because the libraries in question come from Apple’s own FXPlug SDK. The fix will require Apple to ship an update to the FXPlug SDK, that is, something later than the current version of 3.1.1 (r. 44639232).

Share and Enjoy

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

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

Hey Quinn,


Has the issue been resolved?

I'm trying to enable hardened runtime in FxPlug 4 examples, then notiarize them, and they stop working (disappear from Motion/FCPX). When hardened runtime is not enforced, they work OK.

As a follow up, looks like in my case the problem is related to entitlement: com.apple.security.get-task-allow.

As soon as it is stripped by a codesign it no longer works in Motion/FCPX.

Same happens if I change the build settings to disable "Code Signing Inject Base Entitlements".

From what I'm reading this entitlement is used for debugging, but is it in some way needed by Motion/FCPX to comunicate with the pluginkit? If so, then it means that the plugin cannot be notarized.

Hi hateom,


In most cases, you should never have to explicitly add that entitlement to your targets. AFAIK Xcode automatically injects that entitlement when you begin a Debug session for that target. And since you don't need software that you are debugging to be notarized, this is perfectly fine. (I assume you are already codesigning to run locally)


From my experience, as long as:

- you are using the most recent version of FxPlug and PlugInManager, embedded as appropriate inside your PlugInKit container

- you are codesigning with the hardened runtime flag

- your loadable code is linked against a recent version of the macOS SDK


You should be able to build plugins that are loaded by Final Cut Pro / Motion and that can be notarized.

I agree with everything you mentioned. But, when you download FxPlug 4 - the examples have "Code Signing Inject Base Entitlements" enabled by default (I'm trying FxSimpleColorCorrector), and just by disabling "Code Signing Inject Base Entitlements" the filters no longer work. Filters are not visible by Motion/FCPX. This one build setting change, nothing else, make the filters disappear. Everything else is straight from the FxPlug 4 SDK.

I verified that with "codesign -d --entitlements :- *.pluginkit" command - as long as com.apple.security.get-task-allow entitlement exists Motion sees the filter. Once it's stripped, filter disappears in Motion.

Not sure what I'm doing wrong.

Try re-signing the FxPlug framework with your own identity (the same one you are using to sign the target, which may be different in Debug/Release configuration).


So... disable automatic code signing in the Copy Files phase, where you are probably copying the FxPlug framework to its final location inside your bundle. Next, add a build script which resigns that framework with your own identity:


codesign --force --timestamp --options runtime --sign "${CODE_SIGN_IDENTITY}" "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/FxPlug.framework"


As a side note, I have "Code Signing Inject Base Entitlements" ON in my Debug configuration, and OFF for Release. I'm not sure what’s going on on your system, but I don't think that option is *directly* affecting your ability to load the filters. It is more a case that when you have that option on, a bunch of stuff that doesn't pass GateKeeper validation gets a free pass.

I was finally able to make it work.

Looks like the PluginManager.framework was not embeded and signed properly in the XPC component.

Once I fixed that everything else worked.

Thanks for help!