`fuzz_mutator` seems to not work with stripping dead code by default
Using the package from crates prior to https://github.com/rust-fuzz/cargo-fuzz/pull/394:
$ cargo fuzz --version
cargo-fuzz 0.12.0
$ git clone [email protected]:rust-fuzz/libfuzzer.git && cd libfuzzer/example_mutator
$ cargo fuzz run boom
...
thread '<unnamed>' panicked at
...
If I install from git cargo install --git https://github.com/rust-fuzz/cargo-fuzz, it not longer panics nearly instantly (finds an input that is prefixed with "boom"). I suspect this is because fuzz_mutator is stripped due to https://github.com/rust-fuzz/cargo-fuzz/pull/394. That said, I did notice stripping dead code fixed errors llvm-cov produced when I was trying to generating coverage reports.
More info: If I compile the example in a standalone project without cargo-fuzz, I can reproduce the behavior more clearly.
$ cargo new example_mutator && cargo add flate2 libfuzzer-sys && mv ~/libfuzzer/example_mutator/fuzz_targets/boom.rs ~/example_mutator/main.rs
$ cargo +nightly rustc -- \
-C passes='sancov-module' \
-C llvm-args='-sanitizer-coverage-level=4' \
-C llvm-args='-sanitizer-coverage-inline-8bit-counters' \
-C link-dead-code
Next, add a panic!(); to fuzz_mutator! and run ./target/debug/example_mutator. I get a crash at the inserted panic.
If I remove -C link-dead-code, the panic isn't reached.
I can't reproduce this. What target are you compiling for? What linker are you using?
rustc: 1.84.0-aarch64-apple-darwin
I'm not sure how to check what rustc is invoking for linking
I was trying to repro on Linux. Easy repro on a Mac laptop.
I think the problem is that the custom mutator system relies on exporting symbols from executables, which is the (stalled) flag -Zexport-executable-symbols: https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/export-executable-symbols.html
https://github.com/rust-lang/rust/issues/84161
-Clink-dead-code is one way to paper over this.
This problem only happens on Apple targets because libfuzzer uses a different mechanism to load these functions on Apple targets. On linux/bsd, libfuzzer uses weak symbols and says this is the reason it doesn't use them on Apple: https://github.com/rust-fuzz/libfuzzer/blob/4b077c206e8c256eca681678acd1e21f03e19fb6/libfuzzer/FuzzerExtFunctionsWeak.cpp#L8-L12
// Implementation for Linux. This relies on the linker's support for weak
// symbols. We don't use this approach on Apple platforms because it requires
// clients of LibFuzzer to pass ``-U _<symbol_name>`` to the linker to allow
// weak symbols to be undefined. That is a complication we don't want to expose
// to clients right now.
I'm not sure I agree that some -U flags are less complicated. Perhaps there's a compatibility issue as they add/remove weak symbols?
If you enable the weak symbol strategy on Apple, here's how you'd build a simple mutator fuzzer:
cargo +nightly rustc -- \
-Cpasses=sancov-module \
-Cllvm-args=-sanitizer-coverage-level=4 \
-Cllvm-args=-sanitizer-coverage-inline-8bit-counters \
-Clink-arg="-Wl,-U,_LLVMFuzzerCustomCrossOver" \
-Clink-arg="-Wl,-U,___lsan_disable" \
-Clink-arg="-Wl,-U,___lsan_do_recoverable_leak_check" \
-Clink-arg="-Wl,-U,___lsan_enable" \
-Clink-arg="-Wl,-U,___msan_scoped_disable_interceptor_checks" \
-Clink-arg="-Wl,-U,___msan_scoped_enable_interceptor_checks" \
-Clink-arg="-Wl,-U,___msan_unpoison" \
-Clink-arg="-Wl,-U,___msan_unpoison_param" \
-Clink-arg="-Wl,-U,___sanitizer_acquire_crash_state" \
-Clink-arg="-Wl,-U,___sanitizer_get_module_and_offset_for_pc" \
-Clink-arg="-Wl,-U,___sanitizer_install_malloc_and_free_hooks" \
-Clink-arg="-Wl,-U,___sanitizer_log_write" \
-Clink-arg="-Wl,-U,___sanitizer_print_memory_profile" \
-Clink-arg="-Wl,-U,___sanitizer_print_stack_trace" \
-Clink-arg="-Wl,-U,___sanitizer_set_death_callback" \
-Clink-arg="-Wl,-U,___sanitizer_set_report_fd" \
-Clink-arg="-Wl,-U,___sanitizer_symbolize_pc" \
-Clink-arg="-Wl,-U,___sanitizer_purge_allocator"
Inglorious, but I can confirm it works.