libfuzzer icon indicating copy to clipboard operation
libfuzzer copied to clipboard

Avoid the "replace main" trick

Open Manishearth opened this issue 4 years ago • 5 comments

The way libfuzzer works is that libfuzzer itself contains a main(), and you link in a binary that contains a hook but not main().

This is kind of awkward, ideally we can get rid of this requirement and instead have a system where you define main() and call libfuzzer::fuzz(|x: &[u8]| {...}) when ready.

Of course, this won't work without changes to libFuzzer itself. Ideally we can add a compile time flag that disables main() and routes everything through FuzzerDriver.

Manishearth avatar Nov 25 '19 23:11 Manishearth

This also lets us do things like add custom formatters to libFuzzer (https://github.com/rust-fuzz/libfuzzer-sys/issues/47), because last I checked we can't hook into any of the optional functions

That said, it seems like we're using LLVMFuzzerInitialize so perhaps we can, now!

Update: this is no longer necessary to use optional functions.

Manishearth avatar Nov 25 '19 23:11 Manishearth

Greetings from a year later 👋

How are you thinking this would work? We commit a .patch file that renames (or removes) main in FuzzerMain.cpp? And apply the patch everytime we update LLVM? Or were you thinking something else?

frewsxcv avatar Nov 21 '20 14:11 frewsxcv

Something like that, yeah

Manishearth avatar Nov 21 '20 19:11 Manishearth

We could -Dmain=libfuzzer_main or something along those lines. It can then also be made optional through build-time features.

I'll see about making a PR for this today.

nagisa avatar Nov 22 '20 14:11 nagisa

I'm interested in this because when I run a fuzz target against an existing corpus, I'd like to gather statistics from inside the fuzz target and report them when the fuzzer exits.

I could do that instead by factoring out the fuzz target function so I can call it from a separate program that just feeds it the contents of every file in a directory. I could also use the libc crate to set up an atexit handler, but carefully, since I understand none of the Rust I/O machinery works at that point.

But I think it'd be nicer to be able to wrap logic like this around a simple library call to the fuzzer driver.

jameysharp avatar Sep 03 '22 01:09 jameysharp