mirror of
https://github.com/Homebrew/brew.git
synced 2026-10-28 09:34:42 +08:00
Merge pull request #24325 from Homebrew/keg-codesign-temporary-copy
Sign temporary keg copies before restoring them
This commit is contained in:
2 files changed
+48
-11
No files matched your search
@@ -120,20 +120,22 @@ module OS
|
||||
"--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.
|
||||
# If codesigning fails, retry on a new inode at a different path.
|
||||
# Sign before moving it back, as macOS may restore com.apple.provenance
|
||||
# at the original path.
|
||||
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)
|
||||
odebug "Codesigning (2nd try) #{file}"
|
||||
result = system_command("codesign", args: [
|
||||
"--sign", "-", "--force",
|
||||
"--preserve-metadata=entitlements,requirements,flags,runtime",
|
||||
tmppath
|
||||
], print_stderr: false)
|
||||
FileUtils.mv tmppath, file if result.success?
|
||||
ensure
|
||||
FileUtils.rm_f tmppath
|
||||
end
|
||||
return if result.success?
|
||||
|
||||
onoe <<~EOS
|
||||
|
||||
@@ -96,6 +96,41 @@ RSpec.describe Keg do
|
||||
|
||||
keg.codesign_patched_binary(file)
|
||||
end
|
||||
|
||||
it "signs a temporary copy when the original path rejects signing on Intel" do
|
||||
Pathname(file).dirname.mkpath
|
||||
File.write(file, "unsigned")
|
||||
allow(Hardware::CPU).to receive(:arm?).and_return(false)
|
||||
allow(SystemCommand).to receive(:quiet_system).and_return(false)
|
||||
allow(keg).to receive(:system_command) do |_, args:, **|
|
||||
if args.first == "--verify"
|
||||
instance_double(SystemCommand::Result, stderr: "#{file}: invalid signature")
|
||||
elsif args.last == file
|
||||
instance_double(SystemCommand::Result, success?: false, stderr: "#{file}: detritus not allowed")
|
||||
else
|
||||
File.write(args.last, "signed")
|
||||
instance_double(SystemCommand::Result, success?: true)
|
||||
end
|
||||
end
|
||||
|
||||
keg.codesign_patched_binary(file)
|
||||
|
||||
expect(File.read(file)).to eq("signed")
|
||||
end
|
||||
|
||||
it "raises when replacing the binary after a successful signing retry fails on Intel" do
|
||||
Pathname(file).dirname.mkpath
|
||||
touch file
|
||||
allow(Hardware::CPU).to receive(:arm?).and_return(false)
|
||||
allow(SystemCommand).to receive(:quiet_system).and_return(false)
|
||||
allow(keg).to receive(:system_command).and_return(
|
||||
instance_double(SystemCommand::Result, stderr: "#{file}: invalid signature"),
|
||||
instance_double(SystemCommand::Result, success?: true),
|
||||
)
|
||||
allow(File).to receive(:rename).with(anything, file).and_raise(Errno::EACCES)
|
||||
|
||||
expect { keg.codesign_patched_binary(file) }.to raise_error(Errno::EACCES)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#relocate_dynamic_linkage" do
|
||||
|
||||
Reference in new issue
Block a user