From e34aaaed00e386b1010c647d25453208713e605e Mon Sep 17 00:00:00 2001 From: tannevaled Date: Fri, 29 May 2026 11:25:44 +0200 Subject: [PATCH] fix(fix-machos): preserve adhoc flag when re-signing entitled binaries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `--preserve-metadata=entitlements,requirements,flags,runtime` does NOT preserve the adhoc flag (0x2) when re-signing. codesign treats the adhoc bit as identity-derived rather than a preservable flag, so the result is a signed-but-not-adhoc binary (flags=0x0(none)). This breaks any binary that needs Virtualization.framework entitlements on macOS: the OS rejects `com.apple.security.virtualization` access if the binary isn't properly ad-hoc signed. Most visible symptom: lima's `limactl start ` with `vmType: vz` silently exits with no error when run from pkgx, while the same version from brew works fine. See pkgxdev/pantry#7853. Fix: when signing ad-hoc (signing_id == "-") AND the binary has entitlements, take the strip-and-re-sign path directly. That path uses `--entitlements ` instead of `--preserve-metadata`, which produces a clean signature with flags=0x2(adhoc) — matching what `codesign -s -` from the binary's own Makefile would produce. Extracted the strip-and-re-sign path into a helper to keep the two codepaths from drifting. Diagnostic before/after on a pkgx-installed limactl: before: CodeDirectory v=20400 flags=0x0(none) location=embedded after: CodeDirectory v=20400 flags=0x2(adhoc) location=embedded --- lib/bin/fix-machos.rb | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/bin/fix-machos.rb b/lib/bin/fix-machos.rb index 3d051504..f5e552db 100755 --- a/lib/bin/fix-machos.rb +++ b/lib/bin/fix-machos.rb @@ -76,6 +76,23 @@ def codesign!(filename) entitlements_xml, _, _ = Open3.capture3("codesign", "-d", "--entitlements", ":-", filename) has_entitlements = !entitlements_xml.strip.empty? + # `--preserve-metadata=flags` does NOT preserve the adhoc flag (0x2) + # when re-signing — codesign treats the adhoc bit as identity-derived + # rather than a preservable flag. The result is a signed-but-not-adhoc + # binary (flags=0x0) which macOS Virtualization.framework rejects when + # the binary needs `com.apple.security.virtualization` entitlement + # (eg. lima's limactl). See pkgxdev/pantry#7853. + # + # Fix: when signing ad-hoc (signing_id == "-") and the binary has + # entitlements we care about, take the remove+re-sign path directly. + # That path uses `--entitlements ` instead of --preserve-metadata, + # which produces a clean signature with flags=0x2(adhoc) — matching + # what `codesign -s -` from the binary's own Makefile would produce. + if signing_id == "-" and has_entitlements + resign_with_entitlements!(filename, signing_id, entitlements_xml) + return + end + _, stderr_str, status = Open3.capture3("codesign", "--sign", signing_id, "--force", "--preserve-metadata=entitlements,requirements,flags,runtime", filename) @@ -90,9 +107,13 @@ def codesign!(filename) # some binaries end up in a state where --preserve-metadata fails # strip the signature entirely and re-sign from scratch puts "fix-macho: re-signing #{filename} (preserve-metadata failed)" + resign_with_entitlements!(filename, signing_id, has_entitlements ? entitlements_xml : nil) + end + + def resign_with_entitlements!(filename, signing_id, entitlements_xml) Open3.capture3("codesign", "--remove-signature", filename) - if has_entitlements + if entitlements_xml and !entitlements_xml.strip.empty? # write entitlements to a tmpfile and re-sign with them require 'tempfile' tmp = Tempfile.new(['entitlements', '.xml'])