mirror of
https://github.com/Homebrew/brew.git
synced 2026-08-12 22:29:27 +04:00
Merge pull request #23429 from Homebrew/ruby-macho-x86-signing
Use codesign to sign patched binaries on Intel
This commit is contained in:
@@ -64,7 +64,10 @@ module OS
|
||||
check_access_directories
|
||||
]
|
||||
|
||||
# Developer tools are checked when building from source.
|
||||
# We need the developer tools for `codesign` on Intel:
|
||||
# https://github.com/Homebrew/brew/issues/23418
|
||||
checks << "check_for_installed_developer_tools" unless ::Hardware::CPU.arm?
|
||||
|
||||
checks.freeze
|
||||
end
|
||||
|
||||
|
||||
@@ -108,6 +108,43 @@ module OS
|
||||
def codesign_patched_binary(file)
|
||||
return if MacOS.version < :big_sur
|
||||
|
||||
unless ::Hardware::CPU.arm?
|
||||
# Intel macOS rejects ruby-macho's ad-hoc signatures on larger
|
||||
# binaries and does not require unsigned binaries to be signed,
|
||||
# so use `codesign` to re-sign only the binaries whose existing
|
||||
# signature our modifications have just broken:
|
||||
# https://github.com/Homebrew/brew/issues/23418
|
||||
result = system_command("codesign", args: ["--verify", file], print_stderr: false)
|
||||
return unless result.stderr.match?(/invalid signature/i)
|
||||
|
||||
odebug "Codesigning #{file}"
|
||||
return if quiet_system("codesign", "--sign", "-", "--force",
|
||||
"--preserve-metadata=entitlements,requirements,flags,runtime",
|
||||
file)
|
||||
|
||||
# If the codesigning fails, it may be a bug in Apple's codesign utility.
|
||||
# A known workaround is to copy the file to another inode, then move it back
|
||||
# erasing the previous file. Then sign again.
|
||||
Dir::Tmpname.create("workaround") do |tmppath|
|
||||
FileUtils.cp file, tmppath
|
||||
FileUtils.mv tmppath, file, force: true
|
||||
end
|
||||
|
||||
odebug "Codesigning (2nd try) #{file}"
|
||||
result = system_command("codesign", args: [
|
||||
"--sign", "-", "--force",
|
||||
"--preserve-metadata=entitlements,requirements,flags,runtime",
|
||||
file
|
||||
], print_stderr: false)
|
||||
return if result.success?
|
||||
|
||||
onoe <<~EOS
|
||||
Failed applying an ad-hoc signature to #{file}:
|
||||
#{result.stderr}
|
||||
EOS
|
||||
return
|
||||
end
|
||||
|
||||
require "macho"
|
||||
|
||||
odebug "Codesigning #{file}"
|
||||
|
||||
@@ -68,6 +68,12 @@ RSpec.describe Homebrew::Diagnostic::Checks do
|
||||
|
||||
expect(checks.fatal_preinstall_checks).not_to include("check_for_installed_developer_tools")
|
||||
end
|
||||
|
||||
it "requires developer tools on Intel" do
|
||||
allow(Hardware::CPU).to receive(:arm?).and_return(false)
|
||||
|
||||
expect(checks.fatal_preinstall_checks).to include("check_for_installed_developer_tools")
|
||||
end
|
||||
end
|
||||
|
||||
describe "#fatal_build_from_source_checks" do
|
||||
|
||||
@@ -43,12 +43,38 @@ RSpec.describe Keg do
|
||||
allow(MacOS).to receive(:version).and_return(MacOSVersion.new("11"))
|
||||
end
|
||||
|
||||
it "signs patched binaries using ruby-macho" do
|
||||
it "signs patched binaries using ruby-macho on Apple Silicon" do
|
||||
allow(Hardware::CPU).to receive(:arm?).and_return(true)
|
||||
expect(keg).not_to receive(:system_command).with("codesign", any_args)
|
||||
expect(keg).not_to receive(:quiet_system).with("codesign", any_args)
|
||||
expect(MachO).to receive(:codesign!).with(file)
|
||||
|
||||
keg.codesign_patched_binary(file)
|
||||
end
|
||||
|
||||
it "re-signs binaries whose signature has been broken using codesign on Intel" do
|
||||
allow(Hardware::CPU).to receive(:arm?).and_return(false)
|
||||
expect(MachO).not_to receive(:codesign!)
|
||||
expect(keg).to receive(:system_command)
|
||||
.with("codesign", args: ["--verify", file], print_stderr: false)
|
||||
.and_return(instance_double(SystemCommand::Result, stderr: "#{file}: invalid signature"))
|
||||
expect(keg).to receive(:quiet_system)
|
||||
.with("codesign", "--sign", "-", "--force",
|
||||
"--preserve-metadata=entitlements,requirements,flags,runtime", file)
|
||||
.and_return(true)
|
||||
|
||||
keg.codesign_patched_binary(file)
|
||||
end
|
||||
|
||||
it "does not sign unsigned binaries on Intel" do
|
||||
allow(Hardware::CPU).to receive(:arm?).and_return(false)
|
||||
expect(MachO).not_to receive(:codesign!)
|
||||
expect(keg).to receive(:system_command)
|
||||
.with("codesign", args: ["--verify", file], print_stderr: false)
|
||||
.and_return(instance_double(SystemCommand::Result, stderr: "#{file}: code object is not signed at all"))
|
||||
expect(keg).not_to receive(:quiet_system).with("codesign", any_args)
|
||||
|
||||
keg.codesign_patched_binary(file)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user