Normal view

There are new articles available, click to refresh the page.
Before yesterdayMain stream

Why launch constraints can crash apps

By: hoakley
23 August 2024 at 14:30

Some apps may crash when launched because there’s something wrong in the app. In Ventura and later, that might occur because macOS is refusing to run them because of security rules, specifically launch constraints. These were extended in Sonoma to allow any app to limit the code it runs to what should be there, in launch environment and library constraints. This article explains what these are, and how you can recognise when constraints are applied.

Code without constraints

Launching an app without constraints isn’t as unconstrained as that might suggest. It’s still given an environment to run in, with settings such as the user’s Home folder and some standard paths including a temporary folder buried in /var/folders. If you’re interested to see what those can include, Mints has a button to show you its own launch environment.

On top of those, the app is limited by standard permissions as to what it can access without obtaining elevated privileges, and everything is subject to the privacy restrictions imposed by TCC according to the app’s Privacy & Security Settings.

But the app can be run from pretty well anywhere, and can run code from libraries, frameworks and other places as it wishes.

Launch constraints

The first set of launch constraints became obvious if you tried to copy and run from a different location one of the apps bundled in Ventura. This has had its purposes in the past, for example to run Network Utility after Apple first gutted then removed it. Try that with one of Ventura’s bundled apps, and the copy can’t be run from any location apart from the SSV it’s installed in, as it crashes immediately. Look in its crash report and you’ll see something like
Exception Type: EXC_CRASH (SIGKILL (Code Signature Invalid))
Exception Codes: 0x0000000000000000, 0x0000000000000000
Termination Reason: CODESIGNING 4 Launch Constraint Violation

That’s given in a bit more detail in the main log, for Terminal as
AMFI: Launch Constraint Violation (enforcing), error info: c[1]p[1]m[1]e[2], (Constraint not matched) launching proc[vc: 1 pid: 2440]: /Users/hoakley/Documents/00crypt/Terminal.app/Contents/MacOS/Terminal, launch type 0, failure proc [vc: 1 pid: 2440]: /Users/hoakley/Documents/00crypt/Terminal.app/Contents/MacOS/Terminal
ASP: Security policy would not allow process: 2440, /Users/hoakley/Documents/00crypt/Terminal.app/Contents/MacOS/Terminal
xpcproxy exited due to OS_REASON_CODESIGNING | Launch Constraint Violation, error info: c[1]p[1]m[1]e[2], (Constraint not matched) launch type 0, failure proc [vc: 1]: /Users/hoakley/Documents/00crypt/Terminal.app/Contents/MacOS/Terminal

The same happens if you try running a forbidden command, such as /usr/libexec/periodic-wrapper.

Open the app using Apparency and view its Launch Information, and you’ll see the launch constraints that caused this.

apparency2

For the Chess app, those read
(on-authorized-authapfs-volume or on-system-volume ) and launch-type = 3 /* CS_LAUNCH_TYPE APPLICATION / and validation-category = 1 /* CS_VALIDATION_CATEGORY_PLATFORM */
which should give you a good idea that app can only be run from its standard location in the SSV or System volume. To make this even harder, Sonoma’s Finder tries to stop you from even copying bundled apps to other locations, and you now have to be ingenious to try launch constraints out.

Launch constraints were first described by Csaba Fitzl, and he has since compiled a listing of all those known. Those shown for Chess.app are Category 14, and common to other bundled apps. Their effect is to prevent all copies of that app from being launched from elsewhere.

Trust caches

Instead of macOS looking up each binary’s launch constraints from the binary itself, all those constraints are assembled into Trust Caches, where they’re listed by the code directory’s hash (cdhash). To look up the launch constraints for the Terminal app, the system first calculates the cdhash for its code directory, then looks in the Trust Cache for the launch constraints given for that cdhash.

The System volume contains a static Trust Cache that covers all the executable binaries that come as part of the system. That’s locked into read-only storage during the early kernel boot phase of startup. Additional Trust Caches are authenticated to ensure they haven’t been tampered with, and loaded when required. Apple cites the example of the Trust Cache required by the code within macOS software updates (known as the update brain) that runs the process, allowing it to run with platform privileges, as it requires to perform the update. Apple gives further details on Trust Caches in its Platform Security Guide.

Disabling launch constraints

What if you need to ignore those launch constraints imposed by macOS? Because system executables are laid out in the static Trust Cache, there’s no way to modify that, and no way to override it. All you can do is disable System Integrity Protection (SIP), which is required for launch constraints to operate.

Environment constraints

Launch constraints and the Trust Cache system are complete and fully enforced as of Ventura 13.3, and have been extended for use by third-parties in Sonoma. Developers can build dictionaries containing facts and applying operations to them to improve the security of their apps. Constraint dictionaries are either saved in property lists for launchd, or in those used for signing code. These too are associated with cdhashes, use some categories common to other trust caches, and work similarly to protect third-party code such as helper apps.

While they might appear overkill, they can be used to address known security problems, of which the most prominent must be maintaining trust with privileged helper apps and XPC services, which have often proved weak points in app security. Apple provides two detailed articles, one explaining how to define these constraints, the other how to apply them. I suspect that we’ll be seeing more of these in the future.

How to tell if an app is notarized

By: hoakley
16 August 2024 at 14:30

Given the importance of executable code being signed, and increasing requirements for apps to be notarized as well, it has long puzzled me that macOS is so reluctant to inform us whether an app is notarized, signed, or sandboxed. I have always thought this would be a useful addition to the Finder’s Get Info dialog when opened for an app or executable code, in the same way that an app’s architecture support is given. This article explains how you can discover this information and more.

Apps

The very best utility for discovering everything there is to know about apps and executable code is Apparency, free from Randy Saldinger at Mothers Ruin Software. Not only is it by far the most powerful and comprehensive you could ever wish for, but it’s superbly designed and integrated into macOS.

apparency1

I seldom even have to open the app, as it displays all the key facts about apps, command tools and more in a replacement QuickLook thumbnail, which is duplicated in the Get Info dialog. If you do still need more information, click on the button at the foot.

apparency2

Apparency provides exhaustive information about executable code, even down to details of any launch constraints that have to be satisfied for the code to be run. Launch constraints were only introduced in macOS Sonoma, and are explained here. They are responsible for preventing you from running copies of apps bundled with macOS.

Although I think they’re outclassed in every respect by Apparency, two of my older apps also provide information about signatures and notarization.

taccy11404

Taccy concentrates on settings and features related to TCC privacy protection.

archichect251

ArchiChect is more about architectures and platforms.

If you really can’t find the information in Apparency, then you might in either of those.

Command tool

The standard command to deliver information about notarization is spctl, used as in
spctl -a -vvv -t install MyApp.app
which should return something like
/Applications/Apparency.app: accepted
source=Notarized Developer ID
origin=Developer ID Application: Randy Saldinger (936EB786NH)

Both Taccy and ArchiChect use that to determine notarization status.

You may also come across recommendations to use the stapler command tool supplied with Xcode to check whether the notarization ticket has been stapled to the executable. Not only does that require you to install Xcode’s command tools, but it also answers a different question, whether the ticket has been stapled to the executable, rather than whether it has been notarized.

Information about notarizing code is provided in this article for developers.

❌
❌