Skip to content

bm crashes with SIGKILL (Code Signature Invalid) — corrupted signature on google/_upb/_message.abi3.so after install-time relink #2

Description

@malenze

Title

bm crashes with SIGKILL (Code Signature Invalid) — corrupted signature on google/_upb/_message.abi3.so after install-time relink

Summary

Every invocation of bm (e.g. bm --version) is killed by the kernel with SIGKILL before printing any output, exit code 137. This reproduces on a fresh Homebrew install and survives reboot, xattr -rc, and brew reinstall basic-memory.

Environment

  • basic-memory 0.23.2 (Homebrew tap basicmachines-co/homebrew-basic-memory)
  • macOS 26.6.2 (25G83), arm64
  • Vendored interpreter: CPython 3.14.7 (libexec/python/cpython-3.14.7-macos-aarch64-none)

Root cause

log show during a crash pins it down precisely — every kill is the same file, same offset:

kernel: CODE SIGNING: cs_invalid_page(0x108bb4000): p=8169[python3.14] final status 0x23020200, denying page sending SIGKILL
kernel: CODE SIGNING: process 8169[python3.14]: rejecting invalid page at address 0x108bb4000 from offset 0x54000 in file
"/opt/homebrew/Cellar/basic-memory/0.23.2/libexec/tools/basic-memory/lib/python3.14/site-packages/google/_upb/_message.abi3.so"
(cs_mtime:1787859439.581342570 == mtime:1787859439.581342570) (signed:1 validated:1 tainted:1 nx:0 wpmapped:0 dirty:0 depth:0)

codesign --verify --deep --strict on that file confirms it directly:

.../google/_upb/_message.abi3.so: invalid signature (code or signature have been modified)
In architecture: arm64

_message.abi3.so is a universal (x86_64 + arm64) Mach-O. It's a transitive dependency (protobuf's upb C extension, pulled in via google-* packages) whose install name Homebrew's post-install linkage step rewrites in place (same mechanism as the "Failed changing dylib ID" / "Failed to fix install linkage" warning your README already documents for jiter). For this file the rewrite apparently succeeds in modifying the arm64 slice's load commands but the file is never re-signed afterward — so its embedded ad-hoc CodeDirectory no longer matches the on-disk bytes. Any process that mmaps an executable page from that stale region gets killed outright by AMFI/code-signing enforcement, which happens on essentially the first bm invocation (basic_memory's config import chain pulls in pydanticpydantic_settings → eventually a code path that loads this extension).

Fix (confirmed working locally)

Re-signing just that one file resolves it immediately, no reboot needed:

codesign --sign - --force /opt/homebrew/Cellar/basic-memory/0.23.2/libexec/tools/basic-memory/lib/python3.14/site-packages/google/_upb/_message.abi3.so

After that, bm --version runs clean (Basic Memory version: 0.23.2, exit 0).

Suggested upstream fix

The formula's post-install step (wherever it currently tolerates/ignores the "Failed to fix install linkage" case) should re-sign (codesign --sign - --force) every relinked/rewritten Mach-O binary under libexec/tools/basic-memory/lib/**/*.so, not just the ones where the install-name rewrite fully succeeds — otherwise any file whose slice got modified but not re-signed will silently corrupt the ad-hoc signature and crash on first use on machines with library validation code-signing enforcement.

Steps to reproduce

  1. brew install basic-memory (or brew reinstall basic-memory) on macOS 26.x / arm64
  2. bm --version
  3. Observe: no output, exit code 137, log show --last 2m --predicate 'eventMessage contains "CODE SIGNING"' shows a cs_invalid_page kill referencing google/_upb/_message.abi3.so

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions