Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Codesigning on macOS 11 on Apple Silicon #9082

Closed
mistydemeo opened this issue Nov 8, 2020 · 14 comments
Closed

Codesigning on macOS 11 on Apple Silicon #9082

mistydemeo opened this issue Nov 8, 2020 · 14 comments
Labels
discussion Input solicited from others outdated PR was locked due to age

Comments

@mistydemeo
Copy link
Member

Feature suggestion

A detailed description of the proposed feature

On macOS 11 on Apple Silicon, codesigning will be mandatory for binaries to run. This applies to both executables and dylibs. An ad-hoc signature is sufficient, and the linker will automatically apply one when a binary is created. However, our tooling (such as ruby-macho) will break existing code signatures and it's necessary to reapply a signature in order to ensure it will continue to run properly.

I've opened a PR in #9040 to automatically apply code signatures whenever we alter a binary using ruby-macho. Failures in that code signature process are currently ignored. A few details we need to discuss here:

  1. Should we unconditionally apply code signing, or only resign binaries that were already signed when we altered then? We're currently doing the former, which has been suggested to us as the right path. This should not be harmful on other OSs even though it's only required on macOS 11 on Apple Silicon.
  2. Should we ignore codesigning failures, or treat them as fatal? We've encountered a few programs where we are unable to correctly resign their dylibs; from @fxcoudert's research, this appears to be a bug in the system codesign utility.

The motivation for the feature

This is needed to future-proof Homebrew.

How the feature would be relevant to at least 90% of Homebrew users

Code signatures are necessary to run code. 100% of Homebrew users, eventually, will need this.

What alternatives to the feature have been considered

There are no alternatives.

@mistydemeo mistydemeo added the discussion Input solicited from others label Nov 8, 2020
@fxcoudert
Copy link
Member

fxcoudert commented Nov 8, 2020

Should we ignore codesigning failures, or treat them as fatal?

  • If the original Mach-O file was not codesigned, failing to codesign is weird, but probably not an issue. Although if it's a library that will be loaded from a codesign binary, it may be a failure (that would have to be investigated).
  • If the original Mach-O file was codesigned, after we've edited it with ruby_macho it has become invalid: the binary or library cannot be run or loaded anymore. To me that warrants a hard error: we are producing a file that we know is broken.

Should we unconditionally apply code signing?

I don't see the benefit for codesigning on platforms that don't check for signatures. I can see the costs: we're increasing processing time, and increasing risk of breakage.


I would add another question:

  1. Should our codesigning process catch the (relatively rare) codesign bug we are aware of, and apply the known work-around (copy the file, codesign the copy, and replace the original)?

And to that, I would answer yes, because that bug has been around for some time and is currently making our life (well, my life at least!) harder in testing and preparing for the ARM Big Sur release. So I'd say let's implement the workaround, provided it's clearly marked as such as can be easily removed in the future.


In summary, my opinion is that for now a limited intervention based on our needs would be to follow the approach you proposed in #9082, but limited to ARM, and with an extra workaround in apply_ad_hoc_signature. I agree in the long term the logic will have to go into ruby_macho (simply because it makes no sense for ruby_macho to produce invalid Mach-O files!), but currently that's not ready. Also, there are only two call sites involved, so it's not that much of a hack.

@MikeMcQuaid
Copy link
Member

  • If the original Mach-O file was not codesigned, failing to codesign is weird, but probably not an issue. Although if it's a library that will be loaded from a codesign binary, it may be a failure (that would have to be investigated).
  • If the original Mach-O file was codesigned, after we've edited it with ruby_macho it has become invalid: the binary or library cannot be run or loaded anymore. To me that warrants a hard error: we are producing a file that we know is broken.

Agreed 👍🏻

I don't see the benefit for codesigning on platforms that don't check for signatures. I can see the costs: we're increasing processing time, and increasing risk of breakage.

gdb needs code signed to work on macOS, I'm unsure whether that means ad-hoc or not.

We've been told that apparently there is a slight performance bonus from platforms with Gatekeeper from not code-signing hence why we considered doing it globally.

  1. Should our codesigning process catch the (relatively rare) codesign bug we are aware of, and apply the known work-around (copy the file, codesign the copy, and replace the original)?

Ideally, yes 👍🏻

@Bo98
Copy link
Member

Bo98 commented Nov 9, 2020

  1. Should our codesigning process catch the (relatively rare) codesign bug we are aware of, and apply the known work-around (copy the file, codesign the copy, and replace the original)?

I agree this should be the approach we focus on. To my understanding, it should then be not a problem to make codesign failures fatal.

@johnalanwoods
Copy link

Should code-sign eventually not be adhoc-only, should the solution architecture consider this now?

@shepmaster
Copy link

Should our codesigning process catch the (relatively rare) codesign bug we are aware of, and apply the known work-around (copy the file, codesign the copy, and replace the original)?

My word! Is this bug tracked elsewhere? I'm pretty sure I've been seeing it non stop outside of brew: Why does my native arm64 application built using an x86_64 build system report “killed” when executed on Apple Silicon? It looks like copying and signing works...ish:

% arch -x86_64 cc -arch arm64 hello.c -o hello

% ./hello                                     
zsh: killed     ./hello

% cp hello hello4                

% codesign -s - -f -vvvvvv hello4
hello4: replacing existing signature
hello4: signed Mach-O thin (arm64) [hello4-555549440ad8b6d9c6c432f0952280e2f03654f7]

% ./hello4 
Hello, world!

You'll note that I've gotten up to hello4 — it really looks like once you've attempted to execute the file, you can't resign it, even if it's been replaced. A continued transcript:

% arch -x86_64 cc -arch arm64 hello.c -o hello

% cp hello hello4                             

% codesign -s - -f -vvvvvv hello4
hello4: replacing existing signature
hello4: the codesign_allocate helper tool cannot be found or used

@fxcoudert
Copy link
Member

This:

the codesign_allocate helper tool cannot be found or used

is the error we're seeing. If this occurs, you need to change that file's inode (so copying it someplace and back will work). Once you've done that, you can sign and it will work.

@shepmaster
Copy link

Is this bug tracked elsewhere?

I'd like to subscribe to the relevant issue to avoid further cluttering up this issue.

@fxcoudert
Copy link
Member

@shepmaster we don't really have an issue for it, but you can check the code we're using to work around this: #9102

@johnalanwoods
Copy link

@fxcoudert testing this myself, is this only occurring when using x86 compiler targeting ARM through Rosetta2?

If so this is an apple bug, how long you seeing this for?

@fxcoudert
Copy link
Member

@johnalanwoods we're seeing this the native ARM Xcode toolchain (which is what we've been testing most), this is an Apple bug, they are aware

@shepmaster
Copy link

is this only occurring when using x86 compiler targeting ARM through Rosetta2?

This is my case, and it appears to be 100% reproducible in this setup.

this is an Apple bug, they are aware

I don't have any Apple contacts and I've only heard bad things about trying to use Radar. If you have someone on the inside that you talk with, I'd deeply appreciate it if you'd forward this particular wrinkle as part of the existing issue. ❤️

@fxcoudert
Copy link
Member

I've only heard bad things about trying to use Radar

This specific bug is known. But I would still suggest filing bugs with the Feedback Assistant (the new name of the radar)

@johnalanwoods
Copy link

@fxcoudert sounds like it's around a while! (Unfortunately)

@fxcoudert
Copy link
Member

We've implemented the solution discussed here in #9102
It's been working for some time now, so I'm closing this issue.

ManasJayanth added a commit to esy/esy that referenced this issue Dec 18, 2020
 Executables, once tampered with, need to be resigned on BigSur (arm64)
 Ideally, it should be as simple as,

 $ codesign --sign - --force --preserve-metadata=<...properties> /path/to/binary

 However, due to bug in the tool, codesign, the following error is thrown.

 ```
 the codesign_allocate helper tool cannot be found or used
 ```

 (not sure where this is tracked. Ref: Homebrew/brew#9082 (comment))

 To workaround this, interim fix suggested by Homebrew team is to copy the binary to a different folder, and mv it back destroying the original file's inode.
ManasJayanth added a commit to esy/esy that referenced this issue Dec 18, 2020
 Executables, once tampered with, need to be resigned on BigSur (arm64)
 Ideally, it should be as simple as,

 $ codesign --sign - --force --preserve-metadata=<...properties> /path/to/binary

 However, due to bug in the tool, codesign, the following error is thrown.

 ```
 the codesign_allocate helper tool cannot be found or used
 ```

 (not sure where this is tracked. Ref: Homebrew/brew#9082 (comment))

 To workaround this, interim fix suggested by Homebrew team is to copy the binary to a different folder, and mv it back destroying the original file's inode.
ManasJayanth added a commit to esy/esy that referenced this issue Dec 18, 2020
 Executables, once tampered with, need to be resigned on BigSur (arm64)
 Ideally, it should be as simple as,

 $ codesign --sign - --force --preserve-metadata=<...properties> /path/to/binary

 However, due to bug in the tool, codesign, the following error is thrown.

 ```
 the codesign_allocate helper tool cannot be found or used
 ```

 (not sure where this is tracked. Ref: Homebrew/brew#9082 (comment))

 To workaround this, interim fix suggested by Homebrew team is to copy the binary to a different folder, and mv it back destroying the original file's inode.
ManasJayanth added a commit to esy/esy that referenced this issue Dec 18, 2020
* Unit testing setup (with test for getMachOBins)

* Cleanup print_endlines

* Explain the codesigning process

 Executables, once tampered with, need to be resigned on BigSur (arm64)
 Ideally, it should be as simple as,

 $ codesign --sign - --force --preserve-metadata=<...properties> /path/to/binary

 However, due to bug in the tool, codesign, the following error is thrown.

 ```
 the codesign_allocate helper tool cannot be found or used
 ```

 (not sure where this is tracked. Ref: Homebrew/brew#9082 (comment))

 To workaround this, interim fix suggested by Homebrew team is to copy the binary to a different folder, and mv it back destroying the original file's inode.

* fmt
@BrewTestBot BrewTestBot added the outdated PR was locked due to age label Jan 10, 2021
@Homebrew Homebrew locked as resolved and limited conversation to collaborators Jan 10, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
discussion Input solicited from others outdated PR was locked due to age
Projects
None yet
Development

No branches or pull requests

7 participants