Environment:
Box64 version: v0.4.3 f79babc (nightly build)
Host: ARM64, Cortex-A520, 8 cores
Distro: Ubuntu inside proot-distro (Termux)
Guest binary: an Electron-based x86_64 Linux app (Node v22.22.0, Electron 39.6.1)
Description:
An Electron/Node application calls child_process.execSync() to run a shell command and capture its output. Internally this triggers a write() syscall to a socket/pipe connected to the child process's stdin. Every time this code path runs, Box64 crashes with SIGSEGV inside box64/syscall.
Key observation:
Across multiple reproductions (different runs, different PIDs), the value in RSI at the time of the crash (write's 3rd argument — buffer length) is consistently equal to the OS PID of the crashing process itself, not the actual length of the buffer being written. This strongly suggests the syscall wrapper is reading the wrong register/context value for the length argument in this particular call path.
Reproduction steps:
Run any Electron app that calls child_process.execSync(cmd) (with or without an input option) early during startup, under Box64.
Crash occurs consistently at the write syscall with EFAULT, RDI staying constant at 0x129 (likely the fd), RSI == PID.
Tested variations (all reproduce identically):
With default dynarec settings
With BOX64_DYNAREC=0 (pure interpreter mode) — rules out a dynarec-specific codegen bug, points to the syscall translation layer itself
With various BOX64_DYNAREC_* env vars (BIGBLOCK, SAFEFLAGS, STRONGMEM, CALLRET) — no effect
Crash signature:
[BOX64] |SIGSEGV @ (syscall) (x64pc=0x302a08b3/"box64/syscall + 0x13", ...)
RDI:0x0000000000000129 RSI: RDX:
Node-side error before the native crash:
Error: write EFAULT
at afterWriteDispatched (node:internal/stream_base_commons:159:15)
at writeGeneric (node:internal/stream_base_commons:150:3)
at Socket._writeGeneric (node:net:966:11)
at Socket._write (node:net:978:8)
at execSync (node:child_process:1000:20)
Environment:
Box64 version: v0.4.3 f79babc (nightly build)
Host: ARM64, Cortex-A520, 8 cores
Distro: Ubuntu inside proot-distro (Termux)
Guest binary: an Electron-based x86_64 Linux app (Node v22.22.0, Electron 39.6.1)
Description:
An Electron/Node application calls child_process.execSync() to run a shell command and capture its output. Internally this triggers a write() syscall to a socket/pipe connected to the child process's stdin. Every time this code path runs, Box64 crashes with SIGSEGV inside box64/syscall.
Key observation:
Across multiple reproductions (different runs, different PIDs), the value in RSI at the time of the crash (write's 3rd argument — buffer length) is consistently equal to the OS PID of the crashing process itself, not the actual length of the buffer being written. This strongly suggests the syscall wrapper is reading the wrong register/context value for the length argument in this particular call path.
Reproduction steps:
Run any Electron app that calls child_process.execSync(cmd) (with or without an input option) early during startup, under Box64.
Crash occurs consistently at the write syscall with EFAULT, RDI staying constant at 0x129 (likely the fd), RSI == PID.
Tested variations (all reproduce identically):
With default dynarec settings
With BOX64_DYNAREC=0 (pure interpreter mode) — rules out a dynarec-specific codegen bug, points to the syscall translation layer itself
With various BOX64_DYNAREC_* env vars (BIGBLOCK, SAFEFLAGS, STRONGMEM, CALLRET) — no effect
Crash signature:
[BOX64] |SIGSEGV @ (syscall) (x64pc=0x302a08b3/"box64/syscall + 0x13", ...)
RDI:0x0000000000000129 RSI: RDX:
Node-side error before the native crash:
Error: write EFAULT
at afterWriteDispatched (node:internal/stream_base_commons:159:15)
at writeGeneric (node:internal/stream_base_commons:150:3)
at Socket._writeGeneric (node:net:966:11)
at Socket._write (node:net:978:8)
at execSync (node:child_process:1000:20)