ITADN

SIGSEGV in `yrx_compiler_build` from Go bindings — regression in 1.15.0

#663Openmarius-benthin 创建于 2026-05-28
M
marius-benthincommented
## SIGSEGV in `yrx_compiler_build` from Go bindings — regression in 1.15.0 ### Summary Calling `Compiler.Build()` from the Go bindings consistently crashes with `SIGSEGV` (sigcode 2 / `SEGV_ACCERR`) inside the cgo call to `yrx_compiler_build`. The crash is deterministic, happens at the same PC across runs, and reproduces with a small ruleset (50k lines / ~few hundred rules). I bisected and the regression appeared in **v1.15.0**: | version | result | |---|---| | 1.13.0 | works | | 1.14.0 | works | | **1.15.0** | **crashes** | | 1.16.0 | (not retested, but expected to crash) | | 1.17.0 | crashes | Wasmtime version is unchanged between 1.14.0 and 1.15.0 (both 40.0.4), so it's not a wasmtime bump. My best guess is the "Add full support for WASM" change in 1.15.0 affected the compile path. ### Crash signature ``` SIGSEGV: segmentation violation PC=0xe6fd14 m=11 sigcode=2 addr=0x7f96a3cccde0 signal arrived during cgo execution goroutine 1 gp=0x31bc5bf581e0 m=11 mp=0x31bc5c172008 [syscall]: runtime.cgocall(0x7600d0, 0x31bc5bf7d6d8) /usr/local/go/src/runtime/cgocall.go:167 +0x4b github.com/VirusTotal/yara-x/go._Cfunc_yrx_compiler_build(0x7f96a3f0e080) _cgo_gotypes.go:508 +0x45 github.com/VirusTotal/yara-x/go.(*Compiler).Build.func1(...) /go/pkg/mod/github.com/!virus!total/yara-x/go@v1.17.0/compiler.go:632 github.com/VirusTotal/yara-x/go.(*Compiler).Build(0x31bc5c05c240) /go/pkg/mod/github.com/!virus!total/yara-x/go@v1.17.0/compiler.go:632 +0x48 main.main() /build/main.go:98 +0xb2a ... rsp 0x7f96a3cccdd0 rip 0xe6fd14 ``` Crash hits after `AddSource` and `Warnings()` complete successfully. The fault address is exactly **16 bytes above rsp** — i.e. the first stack-local access after a large `sub rsp, N` on function entry — and `sigcode=2` (`SEGV_ACCERR`) on a page just past the stack base is the classic stack-guard-page hit. This points to a function in the compile path with a stack frame larger than the cgo-call stack the Go runtime provides for the M's g0 (which is fairly small on Linux). The crash signature is identical (same PC, same offset, sigcode=2) whether the input is a 550k-line ruleset or a 50k-line one — so it's a fixed-size frame on the build path, not depth-dependent recursion. ### Reproducer - Build environment: static musl binary on Alpine, Go cgo, yara-x C API linked statically. - Triggering call: `Compiler.Build()` after a successful `AddSource` of a non-trivial ruleset. - Build patches applied (none of which should be related, but for completeness): - Remove `cdylib` from `capi/Cargo.toml` (keep only `staticlib`) - `config.signals_based_traps(false)` added in `lib/src/wasm/mod.rs` (avoids wasmtime signal handler conflict with Go at scan time — not load-bearing for this crash) - `RUSTFLAGS="-C target-feature=-crt-static"` so the .a doesn't bundle musl libc Build command: ``` cargo build -p yara-x-capi --release \ --target x86_64-unknown-linux-musl \ --features=rules-profiling ``` Go link: ``` go build -ldflags "-extldflags '-static -llzma -Wl,-z,muldefs' -w -s" \ -tags static_link -o goodwarescanner-linux . ``` Happy to share a minimal Dockerfile and a Go reproducer if helpful. ### Workarounds considered - Bumping the linker's ELF stack size (`-Wl,-z,stack-size=...`) — only affects the main thread, not Go-created Ms. - Running `yrx_compiler_build` on a manually-created pthread with a larger stack via a C shim — should work but invasive. - Wrapping internal recursive paths in `stacker::maybe_grow` in the Rust source. For now I'm pinned to 1.14.0. ### Versions - yara-x: 1.15.0+ (broken), 1.14.0 (works) - yara-x/go bindings: same versions as above - Go: as bundled in `golang:alpine` (cgo enabled) - Rust: `rust:slim` (latest at time of build) - Target: `x86_64-unknown-linux-musl`
10 条评论