diff --git a/Library/Homebrew/extend/os/mac/keg.rb b/Library/Homebrew/extend/os/mac/keg.rb index 7b9b29cc8e..9aba39320a 100644 --- a/Library/Homebrew/extend/os/mac/keg.rb +++ b/Library/Homebrew/extend/os/mac/keg.rb @@ -31,36 +31,59 @@ class Keg return unless Hardware::CPU.arm? odebug "Codesigning #{file}" - # Use quiet_system to squash notifications about resigning binaries - # which already have valid signatures. - return if quiet_system("codesign", "--sign", "-", "--force", - "--preserve-metadata=entitlements,requirements,flags,runtime", - file) + prepare_codesign_writable_files(file) do + # Use quiet_system to squash notifications about resigning binaries + # which already have valid signatures. + 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. - # - # TODO: remove this once the bug in Apple's codesign utility is fixed - Dir::Tmpname.create("workaround") do |tmppath| - FileUtils.cp file, tmppath - FileUtils.mv tmppath, file, force: true + # 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. + # + # TODO: remove this once the bug in Apple's codesign utility is fixed + Dir::Tmpname.create("workaround") do |tmppath| + FileUtils.cp file, tmppath + FileUtils.mv tmppath, file, force: true + end + + # Try signing again + 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? + + # If it fails again, error out + onoe <<~EOS + Failed applying an ad-hoc signature to #{file}: + #{result.stderr} + EOS end + end - # Try signing again - odebug "Codesigning (2nd try) #{file}" + def prepare_codesign_writable_files(file) result = system_command("codesign", args: [ - "--sign", "-", "--force", - "--preserve-metadata=entitlements,requirements,flags,runtime", - file + "--display", "--file-list", "-", file ], print_stderr: false) - return if result.success? + return unless result.success? - # If it fails again, error out - onoe <<~EOS - Failed applying an ad-hoc signature to #{file}: - #{result.stderr} - EOS + files = result.stdout.lines.map { |f| Pathname(f.chomp) } + saved_perms = {} + files.each do |f| + unless f.writable_real? + saved_perms[f] = f.stat.mode + FileUtils.chmod "u+rw", f.to_path + end + end + yield + ensure + saved_perms&.each do |f, p| + f.chmod p if p + end end def prepare_debug_symbols