Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Avoid the "replace main" trick #46

Open
Manishearth opened this issue Nov 25, 2019 · 5 comments
Open

Avoid the "replace main" trick #46

Manishearth opened this issue Nov 25, 2019 · 5 comments

Comments

@Manishearth
Copy link
Member

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
Copy link
Member Author

Manishearth commented Nov 25, 2019

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.

@frewsxcv
Copy link
Member

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?

@Manishearth
Copy link
Member Author

Something like that, yeah

@nagisa
Copy link
Member

nagisa commented Nov 22, 2020

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.

@jameysharp
Copy link

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.

# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

No branches or pull requests

4 participants