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.

A brief history of kernel panics

By: hoakley
27 July 2024 at 15:00

Classic Mac OS didn’t have an operating system kernel as such, so on paper at least it couldn’t suffer kernel panics. Instead, the system simply crashed or froze, and the only way out was to force the Mac to restart or shut down. In those days before the HFS+ file system gained journalling (only added to OS X 10.2.2 in 2002), that was usually followed by checking and repairing the startup disk, as the file system there was often damaged in the process.

If you were really unlucky, when your Mac tried to start up again it would display a flashing question mark indicating that the system was too damaged to be run. That’s when you reached for the startup disk or CD-ROM, or a special disk you had ready to recover your Mac and restore the system. Recovery disks were almost essential, as app crashes often brought the whole system down with them.

Mac OS X brought a big change to that, with its kernel architecture to ensure that crashing apps were less likely to cause the whole system to collapse, although early versions of the kernel and its extensions often proved less stable that we’d hoped. In the first couple of versions of Mac OS X, handling of panics was fairly basic, with lines of text displayed, and the Mac left unresponsive for the user to force it to restart.

With Mac OS X 10.2 Jaguar came the well-known panic display, in which a transparent grey curtain dropped down the display to reveal a multi-language message instructing the user to restart the Mac.

panic
A traditional kernel panic prior to OS X 10.8.

From 10.2 in 2002 through 10.7 in 2011, minor variations were made to that panic display, including additional translations of its text. Because of the practical difficulties of getting a real screenshot of this event, that shown above is a slight cheat created by overlaying the display image stored in the system on a normal screenshot, but it’s a faithful reproduction of what we saw then.

This all changed in OS X Mountain Lion, in 2012, when the panic display disappeared and the user was informed of the panic only after their Mac had restarted automatically. Apple took to referring to them not as kernel panics, but in the euphemism unexpected restarts, and then removed the multi-language message altogether.

Instead, what was intended to happen was, shortly after the user had logged back into the automatically restarted Mac, a panic alert would appear, containing the panic log. Users were encouraged to send that to Apple, and most assumed that an engineer there would review it, and perhaps even respond to it if appropriate. In reality, panic logs were automatically and anonymously processed to provide Apple with overall statistics, and it seems extremely unlikely that any human read any of them individually unless they accompanied a bug report.

Kernel panics tended to break out in small epidemics confined to specific models. My own period of purgatory lasted six months, between the release of OS X 10.11.4 on 21 March 2016 and the upgrade to Sierra on 20 September that autumn/fall. Throughout that period, many newer MacBook Pros and iMacs suffered frequent kernel panics, in my iMac’s case every 2-5 days. Those may well have resulted from bugs in their graphics drivers, but were never fixed in El Capitan, as far as I’m aware.

Despite their frequency in the past, Apple has been remarkably reluctant to admit to them in its documentation. That for users avoids all mention of the term, merely referring to them as unexpected restarts “because of a problem”. Even that for developers buries them away in an ancient Tech Note from 14 August 2008, and still contains details for PowerPC models.

Maybe we’ve just been imagining them all those years.

Reference

Wikipedia

❌
❌