rust-fuzz/libfuzzer

fuzz_target macro hygiene

stormshield-guillaumed opened this issue · 1 comments

The run function defined in the fuzz_target macro takes precedence over a run function defined in the same file as the macro invocation. If you modify the bananas example to look like below, it won't compile, and if you keep the arguments the same, it will compile but recurse infinitely.

#![no_main]

use libfuzzer_sys::fuzz_target;

fuzz_target!(|data: (&[u8], bool)| { run(data.0, data.1) });

fn run(data: &[u8], b: bool) {
    if data == "banana!".as_bytes() && b {
        panic!("success!");
    }
    example::bananas(data);
}

When running cargo fuzz run bananas, we get the following error. Using rustc 1.67.0-nightly (7eef946fc 2022-11-06).

error[E0061]: this function takes 1 argument but 2 arguments were supplied
 --> example/fuzz/fuzz_targets/bananas.rs:5:38
  |
5 | fuzz_target!(|data: (&[u8], bool)| { run(data.0, data.1) });
  |                                      ^^^
  |
note: function defined here
 --> example/fuzz/fuzz_targets/bananas.rs:5:1
  |
5 | fuzz_target!(|data: (&[u8], bool)| { run(data.0, data.1) });
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  = note: this error originates in the macro `$crate::fuzz_target` which comes from the expansion of the macro `fuzz_target` (in Nightly builds, run with -Z macro-backtrace for more info)
help: wrap these arguments in parentheses to construct a tuple
  |
5 | fuzz_target!(|data: (&[u8], bool)| { run((data.0, data.1)) });
  |                                          +              +

A workaround is to call crate::run in the macro invocation or to name the function differently.

This commit has introduced the run inner function and seems to have thought about name collision.

A workaround is to call crate::run in the macro invocation or to name the function differently.

Would be happy to receive a pull request that implemented this!