Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add custom mutator macro #62

Closed
wants to merge 1 commit into from
Closed

Add custom mutator macro #62

wants to merge 1 commit into from

Conversation

epilys
Copy link

@epilys epilys commented Jun 5, 2020

This adds a new macro that defines a custom mutator macro for libfuzzer.

Custom mutator

The mutator receives a mutable C array of bytes that is afterwards fed into the fuzzer. The user can use libfuzzer's standard mutator by calling the llvm_fuzzer_mutate wrapper function.

Handling of the C byte array

In Rust, the byte array can be exposed as a mutable slice of length max_len. In the C API, the user must return the actual length used by the array without any guarantee that len <= max_len. I have added two options in the mutator declaration macro, either provide a mutable Vec<u8> and then trim the vector if its length is more than max_len before copying it back into the C API's slice, or use a custom struct Buffer that works like a Vec but ignores any attempts at adding more bytes if the final length surpasses max_len. Buffer is not a very clean solution, but at least it prevents copying in each mutation step.

Next steps

If the Arbritary trait provides a method to turn objects back into bytes (like mentioned in rust-fuzz/arbitrary/issues/44) the macro can take a data: &mut T argument so that the user can work directly on an object rather than raw bytes.

@Manishearth
Copy link
Member

r? @fitzgen

@fitzgen
Copy link
Member

fitzgen commented Jun 8, 2020

In Rust, the byte array can be exposed as a mutable slice of length max_len. In the C API, the user must return the actual length used by the array without any guarantee that len <= max_len. I have added two options in the mutator declaration macro, either provide a mutable Vec<u8> and then trim the vector if its length is more than max_len before copying it back into the C API's slice, or use a custom struct Buffer that works like a Vec but ignores any attempts at adding more bytes if the final length surpasses max_len. Buffer is not a very clean solution, but at least it prevents copying in each mutation step.

I would prefer to more closely match the C API.

Buffer is roughly a whole copy of std::vec::Vec, and I don't think maintaining that is the best use of our (this crate's maintainers) resources.

I would prefer to give custom mutators the &mut [u8] slice created from the data and size, the max length, and the seed, and then expect it to return a usize new length, and assert that the returned length is less than or equal the max length. Then, if users want to layer Buffer-style APIs on top of that, they have access to everything they need to do so.

@fitzgen
Copy link
Member

fitzgen commented May 13, 2021

Closing in favor of #79.

@fitzgen fitzgen closed this May 13, 2021
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.

3 participants