Apple Silicon Macs will require signed code

Although it will be a while before anyone other than select developers are writing code for Apple Silicon Macs, Apple has just revealed one important change which affects everyone who intends creating executable code to run on them: when Big Sur is asked to run ARM code, it requires it to be properly signed. Apple hinted that this change was coming over a year ago, and has now warned developers that it’s happening.

Currently, if you create executable code to run on an Intel Mac, it doesn’t require any form of signature, and that isn’t intended to change for the time being. Delivering unsigned code over the Internet can make it harder for others to run, of course: chances are that it will attract a quarantine flag when it arrives on their Mac, which will make it awkward to get through Gatekeeper in more recent versions of macOS, but experienced users should be able to take that in their stride. Jeff Johnson has recently looked at this in detail, and I commend his account to anyone considering this.

In session 701 of WWDC 2019, Apple’s Garrett Jacobson warned: “the security of the platform has become increasingly reliant on the validity of code signatures. And this means that if an app has no signature, it’s impossible to detect tampering. And further, if a bundle signature has become broken at runtime, it’s very difficult to differentiate malicious tampering from mundane tampering when [an app] modifies itself at runtime. And in a future version of macOS, unsigned code will not run by default anymore.”

That future version is Big Sur, when running native code on Apple Silicon.

This is announced in the developer release notes for Universal Apps beta 4:
“New in macOS 11 on Apple silicon Mac computers, and starting in the next macOS Big Sur 11 beta, the operating system will enforce that any executable must be signed with a valid signature before it’s allowed to run. There isn’t a specific identity requirement for this signature: a simple ad-hoc signature issued locally is sufficient, which includes signatures which are now generated automatically by the linker. This new behavior doesn’t change the long-established policy that our users and developers can run arbitrary code on their Macs, and is designed to simplify the execution policies on Apple silicon Mac computers and enable the system to better detect code modifications.
This new policy doesn’t apply to translated x86 binaries running under Rosetta, nor does it apply to macOS 11 running on Intel platforms.”

Two important points need to be reiterated: you don’t need a developer signature, and can use an ad-hoc one, even one generated on the fly during the build process, and this only applies to ARM native executables.

The requirement for signed code isn’t about the level of security afforded by developer signing and notarization, but to ensure that macOS can check that the code hasn’t been tampered with or damaged, by comparing it against its hash. This doesn’t involve validating the signing certificate, for example, as what’s important are the hashes stored in the /Contents/_CodeSignature/CodeResources file in the app bundle (or similar).

codesigning

Xcode now provides a convenient way of applying ad-hoc code signing when building apps, when you select the Sign to Run Locally option for Signing Certificate. It’s also available using command tools such as clang or ld, and can be called manually using
codesign -s - filename
where the hyphen applies an ad-hoc signature.

Unlike developer signing and notarization, this isn’t intended to prevent any modifications being made to executable code. Malicious software could always re-sign modified code using another signature, although in doing so it would lose access to resources which were tied to the original signing identity, of course. But it’s intended to significantly reduce the surface area of attacks.

In addition to Apple’s developer release notes and documentation for tools such as clang, ld, and codesign itself, Jeff Johnson’s article is worth reading, as is Michael Tsai’s article and its comments.

I am, as ever, grateful for discussion with @rosyna, @mjtsai, and others.