Skip to content

bun x / bun run / Bun.spawn crash on Android 10: pidfd_open trapped by seccomp as SIGSYS #15

Description

@HanSoBored

Summary

On Android < 12 (kernel < 5.3, e.g. kernel 4.9 / SDK 29), the app-sandbox seccomp policy TRAPs pidfd_open as SIGSYS. Bun calls pidfd_open when spawning child processes, so anything that spawns crashes:

  • bun x cowsay ... → exit 134 (SIGABRT)
  • bun run <script-with-script>error: script was terminated by signal SIGSYS
  • Bun.spawn() → exit 159

Root cause

Two-part:

  1. Bun's spawn path calls pidfd_open, which Android seccomp TRAPs as SIGSYS instead of returning ENOSYS.
  2. Bun then installs its own SIGSYS crash handler (SA_RESETHAND) at startup, so the trap lands in Bun's abort path rather than letting the shim's fallback run.

bun -e '...' (no child spawn) works fine; only child-process spawning fails.

Reproduction

bun x cowsay "hi"        # exit 134
bun run hi               # error: script was terminated by signal SIGSYS

Proposed fix

Add a SIGSYS handler to bun-shim.so (same technique as opencode-termux's libseccomp-shim):

  • A SIGSYS handler returns -ENOSYS for seccomp-trapped syscalls, so Bun falls back to waitpid.
  • Interpose sigaction() so Bun's own SA_RESETHAND crash handler cannot override ours.

Verified on aarch64/Android 10 (kernel 4.9): all child spawn paths work, and tests/run-tests.sh passes 9/9.

Environment

  • Termux (aarch64), Android 10, kernel 4.9.186
  • Bun 1.3.14

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