Skip to content

fix: gate generate_minibsod behind LIBAFL_MINIBSOD env var#3826

Open
kx7m2qd wants to merge 3 commits into
AFLplusplus:mainfrom
kx7m2qd:fix/gate-minibsod-libfuzzer
Open

fix: gate generate_minibsod behind LIBAFL_MINIBSOD env var#3826
kx7m2qd wants to merge 3 commits into
AFLplusplus:mainfrom
kx7m2qd:fix/gate-minibsod-libfuzzer

Conversation

@kx7m2qd
Copy link
Copy Markdown

@kx7m2qd kx7m2qd commented May 12, 2026

Description

generate_minibsod() was being called unconditionally in inproc_crash_handler, producing megabytes of output (Rust backtrace, register dump, /proc/self/maps) on every target crash. This output doesn't appear in standard libFuzzer and is particularly noisy in libafl_libfuzzer_runtime compatibility mode, where ASan already provides the relevant stack trace. The Rust backtrace is especially problematic since Backtrace::force_capture() ignores RUST_BACKTRACE=0, giving users no way to suppress it.

This PR gates the generate_minibsod() calls in unix.rs and inprocess.rs behind the LIBAFL_MINIBSOD environment variable, making the full diagnostic output opt-in:

  • Default (no env var): clean output matching standard libFuzzer behaviour
  • LIBAFL_MINIBSOD=1: full minibsod output (registers, backtrace, memory maps) for debugging fuzzer internals

The crash handler in libafl_qemu/src/executor.rs was intentionally left ungated — that path fires when the fuzzer itself crashes (not the target), where the diagnostic info is genuinely useful.

Fixes #3792

Checklist

  • I have run ./scripts/precommit.sh and addressed all comments

kx7m2qd and others added 3 commits May 12, 2026 15:51
Calling generate_minibsod() unconditionally in inproc_crash_handler
produces megabytes of output (backtrace, registers, memory maps) that
doesn't appear in standard libFuzzer. This is especially noisy in
libafl_libfuzzer_runtime compatibility mode where ASan already provides
the relevant stack trace.

Gate the minibsod output behind the LIBAFL_MINIBSOD environment variable
so it is opt-in. Users who want the full diagnostic output can set
LIBAFL_MINIBSOD=1.

Fixes AFLplusplus#3792
@domenukk
Copy link
Copy Markdown
Member

So I think the env shouldn't be part of LibAFL, that's against the "Lib" part, right? IMHO it should be a simple variable that we set when creating the executor (builder/..) and then the libfuzzer shim just sets this to false, other fuzzers can chose what they want (or read an env).
Does that make sense?

@kx7m2qd
Copy link
Copy Markdown
Author

kx7m2qd commented May 14, 2026

Thanks for the feedback @domenukk! That makes sense keeping it as a library-level config rather than an env var is cleaner. So the idea would be to add something like with_minibsod(bool) on the executor builder, defaulting to true, and have libafl_libfuzzer_runtime explicitly set it to false? Happy to rework the PR along those lines if that's the right direction

@domenukk
Copy link
Copy Markdown
Member

At this point it's probably time to add a builder if you want to do that? It's a bit more work but would be better since we already have new and with_timeout on the InProcessExecutor. Otherwise just add a function as you suggested that also takes a timeout (it's basically the default, proactically nobody uses new() for the executor).

@kx7m2qd
Copy link
Copy Markdown
Author

kx7m2qd commented May 14, 2026

Thanks @domenukk! So the plan would be to add minibsod: bool to InProcessExecutorHandlerData (defaulting to true), wire it through a new with_timeout_and_minibsod constructor on InProcessExecutor, and have libafl_libfuzzer_runtime pass false. The crash handlers in unix.rs and inprocess.rs would read from GLOBAL_STATE.minibsod instead of the env var. Does that sound right, or would you prefer a different shape?

@domenukk
Copy link
Copy Markdown
Member

Thanks @domenukk! So the plan would be to add minibsod: bool to InProcessExecutorHandlerData (defaulting to true), wire it through a new with_timeout_and_minibsod constructor on InProcessExecutor, and have libafl_libfuzzer_runtime pass false. The crash handlers in unix.rs and inprocess.rs would read from GLOBAL_STATE.minibsod instead of the env var. Does that sound right, or would you prefer a different shape?

Well or just new takes a timeout, always, and a crashdump: bool param that we set to true most of the time, and false in libfuzzer_runtime. That makes for less code.
And maybe keep the with_timeout() around that calls down to new(timeout, true) and has a deprecated flag.
Something along those lines?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

libafl_libfuzzer crash output is extremely verbose compared to libFuzzer

2 participants