Skip to content

Commit aed885c

Browse files
committed
fix: re-sign macOS binaries locally to prevent AMFI SIGKILL
macOS AMFI (Apple Mobile File Integrity) caches code signing validation per-inode. Ad-hoc signatures created on CI runners can be cached as invalid on user machines, causing SIGKILL (exit 137) with no crash report. Re-signing locally after install/update refreshes the cache. Applied to: install.sh, installBinary(), ReplaceSelf()
1 parent a7436af commit aed885c

3 files changed

Lines changed: 27 additions & 0 deletions

File tree

install.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,14 @@ main() {
9595
tar -xzf "${TMPDIR}/${ARCHIVE}" -C "$TMPDIR"
9696
chmod +x "${TMPDIR}/${BINARY}"
9797

98+
# macOS: re-sign binary locally to avoid AMFI code signing cache issues
99+
# CI signs on GitHub runners, but the ad-hoc signature may be cached as
100+
# invalid by macOS AMFI on the user's machine, causing SIGKILL on launch.
101+
if [ "$OS" = "darwin" ] && command -v codesign >/dev/null 2>&1; then
102+
codesign --force --sign - "${TMPDIR}/${BINARY}" >/dev/null 2>&1
103+
ok "Code signed for macOS"
104+
fi
105+
98106
# Try /usr/local/bin first, sudo if needed, fall back to ~/bin
99107
installed=false
100108
if [ -w "$INSTALL_DIR" ]; then

internal/commands/commands.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,11 @@ func installBinary() (string, bool) {
553553
return "", false
554554
}
555555

556+
// macOS: re-sign to prevent AMFI SIGKILL on ad-hoc signed binaries
557+
if runtime.GOOS == "darwin" {
558+
exec.Command("codesign", "--force", "--sign", "-", installPath).Run()
559+
}
560+
556561
ui.ShowSuccess("codes installed to %s", installPath)
557562

558563
if runtime.GOOS == "windows" {

internal/update/apply.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"io"
99
"net/http"
1010
"os"
11+
"os/exec"
1112
"path/filepath"
1213
"runtime"
1314
"time"
@@ -195,6 +196,7 @@ func ReplaceSelf(newBinaryPath string) error {
195196
os.Remove(newBinaryPath)
196197
}
197198
}
199+
codesignDarwin(self)
198200
return nil
199201
}
200202

@@ -281,3 +283,15 @@ func copyFile(src, dst string) error {
281283
_, err = io.Copy(out, in)
282284
return err
283285
}
286+
287+
// codesignDarwin re-signs a binary with an ad-hoc signature on macOS.
288+
// This prevents SIGKILL from macOS AMFI (Apple Mobile File Integrity) which
289+
// can reject binaries whose code signing cache is stale or was created on a
290+
// different machine (e.g. CI runners).
291+
func codesignDarwin(path string) {
292+
if runtime.GOOS != "darwin" {
293+
return
294+
}
295+
cmd := exec.Command("codesign", "--force", "--sign", "-", path)
296+
_ = cmd.Run() // best-effort; ignore errors
297+
}

0 commit comments

Comments
 (0)