Hey everybody. I'm going through fuzzing some libraries. Does anyone have any crates, besides stdlib(not looking for that big of a project right now) they'd like to get some attention? I'm thinking of doing ws-rs next.
@Stuart Small I can think of a few good candidates (e.g.
bytes) but have no idea if it's already being fuzzed
Cool. I'll look into it. That'll be a lot easier than ws-rs. The logic for signalling the server to shutdown will be a little awkward
I already found some decent panics this evening with the first project I started on (mongo_driver) but fixing them will require some API changes. This is my first go with fuzzing and I'm having a lot of fun
@Stuart Small I know snow is looking to get some more fuzzing: https://github.com/mcginty/snow/issues/28
I'm actually working on making fuzzing viable for targets with large API surfaces such as the stdlib or the OpenSSL bindings. It's in the minimum viable prototype stage: https://github.com/Eh2406/auto-fuzz-test
@Stuart Small you can update the targets in https://github.com/rust-fuzz/targets to latest versions of libraries and re-run them. I'm pretty sure you're going to get some crashes out of that, since almost nobody does fuzzing on CI.
Also, if you need any tips on fuzzing (like the right way to run AFL in parallel or how to combine compiling release mode and sanitizers) feel free to message me. I have a bunch of experience with that.
I'm basing my "nobody runs fuzzing on CI and that's a problem" comment on https://github.com/PistonDevelopers/image-png/issues/103
@Stuart Small also you can run fuzz code that has
unsafe in it under https://github.com/Shnatsel/libdiffuzz - I'm pretty sure nobody's done that before. Since Memory Sanitizer is a pain to use, in the meanwhile libdiffuzz can be used to detect reads from uninitialized memory that affect output. You will have to modify the fuzzing targets for it, though. (Full disclosure: I wrote it).
Cool. I'll take a look at it
@Shnatsel FWIW, I've used libdiffuzz to fuzz some SIMD code :)
Oh, that's cool! Found anything?
No, "fortunately" not. But if I do and it's a public project (this wasn't) then I'll make sure to open a trophy case!
Does anyone have good guidance on converting from the crash artifact dumped in /target by rust fuzz back into the arguments to the fuzz_target? It was easy to handle when I was just passing in Vec<u8> but I'm starting to get more complex method signatures so its hard to sort out
If it's AFL, I just replace
afl::read_stdio_bytes and run the binary with test target as input.
If it's something much more complicated, you can use the newly stabilized
dbg! macro to extract inputs passed to individual functions: https://doc.rust-lang.org/std/macro.dbg.html
I'm using libfuzzer right now. Looks like I found a good way to do it:
let slice = &[0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x40,
0xff, 0x00, 0xff, 0x00, 0x40, 0xff, 0x00, 0xff,
0xff, 0xff, 0x00, 0x6c, 0xff, 0x00, 0x00, 0x00, 0x6c];
let mut fb = RingBuffer::new(slice, slice.len()).unwrap();
let rand: (Option<u8>, Vec<Action>) = Arbitrary::arbitrary(&mut fb).unwrap();
I'm not 100% sure RingBuffer is a good idea. I use a fixed-size buffer instead: https://gist.github.com/Shnatsel/4a907d44d6429de93d63d6e7c4d1361e
I originally used fixed sized but it paniced. I'll give it a closed look as to why
Probably because it tried to allocate very large strings or vectors and ran out of data
It would be interesting to have a comparison between ring buffer and fixed size buffer in terms of fuzzing efficiency
Ah I think my issue might be that the definition of Action changed at some point after I generated that byte stream. That would do it.