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

Add managed MachO signing #108992

Merged
merged 35 commits into from
Nov 12, 2024
Merged

Add managed MachO signing #108992

merged 35 commits into from
Nov 12, 2024

Conversation

jtschuster
Copy link
Member

@jtschuster jtschuster commented Oct 17, 2024

Moving #107378 to a new PR since it now has little shared history.

This signer is byte-for-byte identical to the output of codesign except for padding at the end of the file and the corresponding size fields in the headers.

The MachObjectFile and CodeSignature store all the relevant headers and signature information to add/remove a signature from a Mach Object. Most other files are details regarding header format and reading files with different endianness.

The new signer uses a MemoryMappedViewAccessor instead of a Stream. Since memory mapped files can't be resized, MachObjectFile.CreateAdHocSignature() will write out the headers and load commands to the memory mapped file, but not the signature blob. The signature blob will instead be written to the destination file stream after the rest of the file is copied from the memory mapped file.

The signature is composed of an EmbeddedSignature superblob with an ID and offset of 3 following blobs, followed by a CodeDirectory blob, an empty Requirements blob, and an empty CMS blob. The empty Requirements blob and an empty CMS blob are not strictly required but are added for compatibility with codesign. The CodeDirectory includes the identifier string, hashes of each page of the file and information required to verify the hashes.

The signing process for an unsigned executable extends the __LINKEDIT segment (which is always at the end of the file) to make room for the signature blob, writes the signature blob to that location, and adds a CodeSignature load command that points the the signature. If the executable was already signed, it simply clears the old signature and replaces it, extends or shrinks the existing __LINKEDIT size and updates the existing CodeSignature load command.

- Rename (header, offset) tuples
- Prefix underscore on private fields
- Modify load commands in-place in memory mapped file, and write the
  signature to the output stream since memory mapped file can't grow.
@am11
Copy link
Member

am11 commented Oct 18, 2024

HostActivation.Tests.SelfContainedAppLaunch.RelativeEmbeddedPath is failing on osx-x64:

System.ComponentModel.Win32Exception : An error occurred trying to start process '/Users/runner/work/1/s/artifacts/tests/host/osx.x64.Release/ha/4ishikta.mrd/HelloWorld/sub/HelloWorld' with working directory '/Users/runner/work/1/s/artifacts/bin/HostActivation.Tests/Release/net9.0'. Exec format error

jtschuster and others added 3 commits October 21, 2024 09:51
Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com>
…xtensions.cs

Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com>
…xtensions.cs

Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com>
@agocke
Copy link
Member

agocke commented Oct 21, 2024

Could you add a short description of what ad hoc codesigning actually does?

- Link to Apple open source code for binary formats
- Remove extra Enum values
- Remove binary test data and use test data package
- Don't add signature to test apps that weren't signed before
Copy link
Member

@elinor-fung elinor-fung left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! This looks good to me.

Some things for your list of existing follow-ups:

  • I think the SDK only enables signing when actually running on macOS - with this, I think we can/should update that default.
  • Tests in dotnet/sdk for cross-building for osx-<arch> and signing on non-macOS

…re, move public method above private methods.
@jtschuster
Copy link
Member Author

/ba-g WASM timeout, sporadic failure.

@jtschuster jtschuster merged commit 5d69e2d into dotnet:main Nov 12, 2024
152 of 155 checks passed
mikelle-rogers pushed a commit to mikelle-rogers/runtime that referenced this pull request Dec 10, 2024
Creates a managed implementation of Mach-O object file signing for the apphost.

This signer is byte-for-byte identical to the output of codesign except for padding at the end of the file and the corresponding size fields in the headers.

The MachObjectFile and CodeSignature store all the relevant headers and signature information to add/remove a signature from a Mach Object. Most other files are details regarding header format and reading files with different endianness.

The new signer uses a MemoryMappedViewAccessor instead of a Stream. Since memory mapped files can't be resized, MachObjectFile.CreateAdHocSignature() will write out the headers and load commands to the memory mapped file, but not the signature blob. The signature blob will instead be written to the destination file stream after the rest of the file is copied from the memory mapped file.

The signature is composed of an EmbeddedSignature superblob with an ID and offset of 3 following blobs, followed by a CodeDirectory blob, an empty Requirements blob, and an empty CMS blob. The empty Requirements blob and an empty CMS blob are not strictly required but are added for compatibility with codesign. The CodeDirectory includes the identifier string, hashes of each page of the file and information required to verify the hashes.

The signing process for an unsigned executable extends the __LINKEDIT segment (which is always at the end of the file) to make room for the signature blob, writes the signature blob to that location, and adds a CodeSignature load command that points the the signature. If the executable was already signed, it simply clears the old signature and replaces it, extends or shrinks the existing __LINKEDIT size and updates the existing CodeSignature load command.

Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com>
@github-actions github-actions bot locked and limited conversation to collaborators Dec 13, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-HostModel Microsoft.NET.HostModel issues
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants