rust-fuzz / libfuzzer Goto Github PK
View Code? Open in Web Editor NEWRust bindings and utilities for LLVM’s libFuzzer
License: Apache License 2.0
Rust bindings and utilities for LLVM’s libFuzzer
License: Apache License 2.0
I wrap a function that I know is buggy into a std::panic::catch_unwind()
so that when it panics my own code does not. I can then gracefully handle the error.
Unfortunately, libfuzzer still detects this as an error and stops.
Here's an example fuzzing target:
#![no_main]
use libfuzzer_sys::fuzz_target;
fn may_panic(input: &[u8]) -> u8 {
let value = *input.get(0).unwrap_or(&0);
if value > 240 {
panic!("Value is greater than 240! value={}", value);
}
value
}
fn wrapper(input: &[u8]) -> Option<u8> {
match std::panic::catch_unwind(|| may_panic(input)) {
Ok(value) => Some(value),
Err(err) => {
println!("Caught panic, returning None");
None
}
}
}
fuzz_target!(|data: &[u8]| {
wrapper(data);
});
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 2547700486
INFO: Loaded 1 modules (743 inline 8-bit counters): 743 [0x10946a9c0, 0x10946aca7),
INFO: Loaded 1 PC tables (743 PCs): 743 [0x10946aca8,0x10946db18),
fuzz/target/x86_64-apple-darwin/release/issue: Running 1 inputs 1 time(s) each.
Running: fuzz/artifacts/issue/minimized-from-ac85e832d98dd32e68baaafa21973abcb7a73101
thread '<unnamed>' panicked at 'Value is greater than 240! value=243', fuzz_targets/issue.rs:7:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
==26058== ERROR: libFuzzer: deadly signal
#0 0x109605b15 in __sanitizer_print_stack_trace+0x35 (librustc-nightly_rt.asan.dylib:x86_64+0x4fb15)
rust-fuzz/cargo-fuzz#1 0x10934b14a in fuzzer::PrintStackTrace()+0x2a (issue:x86_64+0x10001d14a)
rust-fuzz/cargo-fuzz#2 0x10933d093 in fuzzer::Fuzzer::CrashCallback()+0x43 (issue:x86_64+0x10000f093)
rust-fuzz/cargo-fuzz#3 0x7fff734065fc in _sigtramp+0x1c (libsystem_platform.dylib:x86_64+0x35fc)
rust-fuzz/cargo-fuzz#4 0x10946db1f (<unknown module>)
rust-fuzz/cargo-fuzz#5 0x7fff732dc807 in abort+0x77 (libsystem_c.dylib:x86_64+0x7f807)
rust-fuzz/cargo-fuzz#6 0x1093c9528 in std::sys::unix::abort_internal::h70ee130d4bec8a65+0x8 (issue:x86_64+0x10009b528)
rust-fuzz/cargo-fuzz#7 0x10942df08 in std::process::abort::h8a4caf764e23a06d+0x8 (issue:x86_64+0x1000fff08)
rust-fuzz/cargo-fuzz#8 0x10933bf74 in libfuzzer_sys::initialize::_$u7b$$u7b$closure$u7d$$u7d$::h09a768b82a6aeb19+0x54 (issue:x86_64+0x10000df74)
rust-fuzz/cargo-fuzz#9 0x1093bdb65 in std::panicking::rust_panic_with_hook::h2f2e429268b7f845+0x255 (issue:x86_64+0x10008fb65)
rust-fuzz/cargo-fuzz#10 0x1093bd5dd in std::panicking::begin_panic_handler::_$u7b$$u7b$closure$u7d$$u7d$::he71680fea17513cb+0x8d (issue:x86_64+0x10008f5dd)
rust-fuzz/cargo-fuzz#11 0x1093ba376 in std::sys_common::backtrace::__rust_end_short_backtrace::h32d0456e90e0ce79+0x16 (issue:x86_64+0x10008c376)
rust-fuzz/cargo-fuzz#12 0x1093bd549 in rust_begin_unwind+0x49 (issue:x86_64+0x10008f549)
rust-fuzz/cargo-fuzz#13 0x10942e39a in std::panicking::begin_panic_fmt::hf8e6c99ec321f361+0x3a (issue:x86_64+0x10010039a)
rust-fuzz/cargo-fuzz#14 0x10933277b in std::panicking::try::do_call::hcdaafa6b928860c7+0x3ab (issue:x86_64+0x10000477b)
rust-fuzz/cargo-fuzz#15 0x109337eb3 in __rust_try+0x13 (issue:x86_64+0x100009eb3)
rust-fuzz/cargo-fuzz#16 0x109336da8 in issue::wrapper::h9ac1378f8c7f7847+0x128 (issue:x86_64+0x100008da8)
rust-fuzz/cargo-fuzz#17 0x109337a5f in rust_fuzzer_test_input+0x49f (issue:x86_64+0x100009a5f)
rust-fuzz/cargo-fuzz#18 0x10933c083 in __rust_try+0x13 (issue:x86_64+0x10000e083)
rust-fuzz/cargo-fuzz#19 0x10933b7d1 in LLVMFuzzerTestOneInput+0x131 (issue:x86_64+0x10000d7d1)
rust-fuzz/cargo-fuzz#20 0x10933edd1 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long)+0x131 (issue:x86_64+0x100010dd1)
rust-fuzz/cargo-fuzz#21 0x10935c315 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long)+0xe5 (issue:x86_64+0x10002e315)
rust-fuzz/cargo-fuzz#22 0x1093625fd in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long))+0x1edd (issue:x86_64+0x1000345fd)
rust-fuzz/cargo-fuzz#23 0x109371b42 in main+0x22 (issue:x86_64+0x100043b42)
rust-fuzz/cargo-fuzz#24 0x7fff7320dcc8 in start+0x0 (libdyld.dylib:x86_64+0x1acc8)
NOTE: libFuzzer has rudimentary signal handlers.
Combine libFuzzer with AddressSanitizer or similar for better crash reports.
SUMMARY: libFuzzer: deadly signal
────────────────────────────────────────────────────────────────────────────────
Error: Fuzz target exited with exit code: 77
Where the file fuzz/artifacts/issue/minimized-from-ac85e832d98dd32e68baaafa21973abcb7a73101
contains a single byte: 0xF3
(243).
Can we instruct libfuzzer to not bother with these kinds of errors?
Thanks!
This is being developed on the Update: the next
branchnext
branch has been merged into `master.
We should release 0.2.0 or perhaps 1.0.0
and make cargo-fuzz
start using it!
Prerequisites:
libfuzzer
since it's more high level than than just sys stuff?While conducting an internal unsafe review @cramertj found an issue in test_input_wrap
:
This function unconditionally calls from_raw_parts
with the provided data
and size
values. It should be marked unsafe
and should include a comment explaining the conditions under which it is safe to call (it could simply link to https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety).
Lines 56 to 72 in c9c43f3
Any blockers?
Hi, I'm new to fuzzing so sorry if I don't understand. It seems like fuzz_target will fuzz one thing, but say for example I want to fuzz a function across a range of types (in my case all integer types) and then set it going for a few days. At the moment it seems like I have to set one running and then after that set up another target running.
I could have a switch inside the fuzz target but that would annoy the input reduction that the fuzzer tries to do.
I would imagine it would just round robin from one fuzz test to the next.
Maybe I misunderstood the book and this is possible?
Rustc will very soon merge it's shinny new LLVM6.0 backend rust-lang/rust#47828.
It will break fuzzing with current libfuzzer because the generated coverage intrumentation will expect new symbols to be implemented by the linked fuzzer implementation.
The current libfuzzer in libfuzzer-sys is 4.0 and is missing those new symbols.
Upgrading libfuzzer source code to 6.0 while disabling sanitizers works well and is compatible with compiler using LLVM4.0 (so the transition will be easy).
However, begin able to compile with sanitizer enabled will need more work: for instance, to make sanitizer=address
work, we will probably need to first package asan
Thank you so much for this amazing library!
Sorry for polluting your bug tracker with a question.
This change doing an explicit T::arbitrary
call inside of fuzz_target!(arg: &[u8]
instead of just using fuzz_target!(arg: T
seems to allow the fuzzer to try ~500x more valid inputs: oxigraph/oxigraph#509
Is there a reason why fuzz_target!(arg: T
could be way slower than fuzz_target!(arg: &[u8] { let arg = T::arbitrary(&mut Unstructured::new(data));
?
Just tried to use this on MacOS, but ran into:
error: Sanitizers only work with the `x86_64-unknown-linux-gnu` target.
I know it's not directly related to this library, but maybe we should note this only works on Linux. Could this platform be lifted in the future or do LLVM sanitizers only work on Linux?
Hello, I wonder if there's any way to avoid default exit when encountering std::process::exit.
For example, I have fuzz target as below.
fuzz_target!(|data: &[u8]| {
if data.len() < 3 {
std::process::exit(0); //normal exit
}
if data[3] == 0x12 {
panic!("got it"); //abnormal crash
}
});
I want to catch only the abnormal crash but ignore th normal exit(Maybe rewriting fuzz target is a good idea, but the real function to fuzz is very complicated. afl.rs will ignore the normal exit by default, but libfuzzer seems something different). I wonder if there's anyway to avoid exit fuzzer when encountering std::process::exit without rewriting fuzz target.
Thanks a lot.
libfuzzer-sys
will just build and link libfuzzer.a
.
libfuzzer
will depend on libfuzzer-sys
and additionally export our nice fuzz_target!
macro.
I started poking at this over in https://github.com/fitzgen/libfuzzer/tree/split-libfuzzer-and-libfuzzer-sys but quickly ran into linker issues. Don't have the time for that today, so I'm filing this issue for posterity.
Might be nice to have have something similar to quickcheck’s Arbitrary trait, so instead of always taking &[u8]
, we could make it take anything that implements some Arbitrary
trait and provide a number of impls for such trait. (e.g. to fuzz with a String, to fuzz with an array of numbers of some type, to fuzz with something else)
Here the original &[u8] would be used as a source of “randomness”.
I can't compile my fuzzers these days anymore, and I'm banging my head on the problem.
To repro:
git clone https://github.com/google/oss-fuzz.git
python infra/helper.py shell libra
compile
This will compile with clang 10 on ubuntu xenial:
Step 8/10 : RUN clang -v
---> Running in ef911c30fa25
clang version 10.0.0 (https://github.com/llvm/llvm-project.git e84b7a5fe230e42b8e6fe451369874a773bf1867)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/local/bin
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5.4.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6.0.0
Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5.4.0
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Candidate multilib: x32;@mx32
Selected multilib: .;@m64
Removing intermediate container ef911c30fa25
---> 76978329e057
Step 9/10 : RUN cat /etc/os-release
---> Running in 1e87f0c344d7
NAME="Ubuntu"
VERSION="16.04.6 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.6 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
VERSION_CODENAME=xenial
UBUNTU_CODENAME=xenial
I'm getting this error:
Step #4: error: linking with `cc` failed: exit code: 1
// ...
Step #4: = note: /rust/rustup/toolchains/1.42.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-0b278345638bce90.rlib(compiler_builtins-0b278345638bce90.compiler_builtins.c31qu5fm-cgu.0.rcgu.o): In function `__muloti4':
Step #4: /cargo/registry/src/github.com-1ecc6299db9ec823/compiler_builtins-0.1.25/src/macros.rs:253: multiple definition of `__muloti4'
Step #4: /tmp/rustcjXWpoV/liblibrocksdb_sys-eab822076e906c87.rlib(int128_builtins.cpp.o):int128_builtins.cpp:(.text.__muloti4+0x0): first defined here
Step #4: collect2: error: ld returned 1 exit status
Step #4:
Step #4:
Step #4: error: aborting due to previous error
Step #4:
Step #4: error: could not compile `libra_fuzzer_fuzz`.
Step #4:
Step #4: To learn more, run the command again with --verbose.
Step #4: ********************************************************************************
Step #4: Failed to build.
Step #4: To reproduce, run:
Step #4: python infra/helper.py build_image libra
Step #4: python infra/helper.py build_fuzzers --sanitizer address --engine libfuzzer --architecture x86_64 libra
Step #4: ********************************************************************************
It looks like there is a similar error in this thread but I'm not sure what to do of it: https://reviews.llvm.org/D49828
Hi folks,
I've been writing a Rust-based replacement for libFuzzer called Fazi, and I've encountered a couple of issues that have some crossover with libFuzzer usage and the potential for Fazi (or any Rust-based library) to replace libfuzzer for fuzzing rust code.
I apologize for this issue not strictly relating to this crate, but this is the best place I could think of for such discussion.
You can compile a Rust crate with sancov instrumentation via:
$ cargo rustc -- \
-C passes=sancov-module \
-C llvm-args=-sanitizer-coverage-level=4 \
-C llvm-args=-sanitizer-coverage-inline-8bit-counters \
-C llvm-args=-sanitizer-coverage-trace-compares \
-C llvm-args=-sanitizer-coverage-pc-table
When compiling a Rust binary that depends on another Rust library for fuzzing, we now have a scenario where everything in the Rust world is instrumented, including the fuzzing library itself. Even if I could mark the fuzzing crate as #[no_sanitize(coverage)]
, its dependencies (including stdlib) would likely still be instrumented.
This introduces at least two problems I encountered:
__sanitizer_cov_trace_{const_}_cmp*
functions being executed while a lock is held within the fuzzing codelibFuzzer supports hooking a collection of builtin functions such as memcmp
, strcmp
, etc. by implicitly adding the-fno-builtin-memcmp
argument when -fsanitize=fuzzer
or -fsanitize=fuzzer-no-link
are provided to the clang frontend.
As far as I can tell, disabling these builtins is only possible via clang and not supported with an LLVM argument . Support for this would likely fix issues such as #90 as the interceptors could be used.
So now for the questions I wanted to discuss:
The fuzz_target!
macro doesn't accept closures that use a nontrivial pattern for the single argument, like |mut data| { ... }
:
Line 204 in e07c487
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.
When running fuzz test in CI with cargo-fuzz it takes lots of time. Can lots of output log on console be reason for that?
Is it possible to reduce logs and only get information about things when fuzzer finds some test failure?
High due to lack of another way reach you I am having to ask in here:
Is there a way to fuzz rust async/await code? (which uses tokio).
As I want to fuzz a crate that relies very much on async/await and without it most likely a lot of functions cannot be fuzzed. So I am wondering if there is a way to do this. I imagine tokio::spawn
would cause panics to not get catched as the context changes for the code.
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.
This would be helpful for mutations on structures
This might be a good starting task to keep the momentum going for this repo.
Expand this:
#![no_main]
#[macro_use]
extern crate fuzzer;
fuzzer_target!(
fn some_name(in: &[u8]) -> i32 {
// Fuzz body here
0
}
)
Into:
#![no_main]
#[macro_use]
extern crate fuzzer;
#[export_name="LLVMFuzzerTestOneInput"]
pub extern fn some_name(data: *const u8, size: isize) -> i32 {
fn inner(in: &[u8]) -> i32 {
// Fuzz body here
0
}
let in = unsafe { slice::from_raw_parts(data, size) };
inner(in)
}
Thoughts?
http://llvm.org/docs/LibFuzzer.html#afl-compatibility
Not sure how easy this is, but it would be nice. Then afl.rs could use this.
Hi there,
I'm working on a fuzzer for which I would like to initialize a mutable variable once at the start of the program. I will then use this repeatedly in my fuzzing loop.
Since I believe the fuzzing loop is single threaded, it ought to be simple and safe to setup such a variable at the start of my program. However, due to how fuzz_target!
expands, I don't think I can do this without using statics? I was thinking to use LLVMFuzzerInitialize
, but then I saw that it's actually used already by libfuzzer
🙂 This was also touched upon in #46.
I started using a static mut
with a OnceCell
, but I was immediately told that I'm leaking memory. I was hoping that it would be okay since I expect the static to be dropped as part of the program cleanup when the fuzzing loops stops? However, I see a few hundred messages saying both
Direct leak of 40968 byte(s) in 1 object(s) allocated from:
Direct leak of 30728 byte(s) in 1 object(s) allocated from:
Direct leak of 30728 byte(s) in 1 object(s) allocated from:
and
Indirect leak of 65556 byte(s) in 1 object(s) allocated from:
Indirect leak of 49192 byte(s) in 2 object(s) allocated from:
Indirect leak of 36530 byte(s) in 2 object(s) allocated from:
After all these messages, the fuzzer found a problem and I exited out of the fuzzing loop with a panic!
.
Is there a better way to do expensive initialization of a mutable variable?
A possible upgrade would be the ability for creating multiple variables that are to be fuzzed from the same data in the fuzz_target
macro.
Something like this?
fuzz_target!(|rgb: Rgb, other: Other| {})
That, or have another macro named fuzz_targets
First, the Cargo.toml
needs to have a dep on arbitrary
, which cargo-fuzz
doesn't generate (or alternatively, libfuzzer_sys
needs to re-export the Arbitrary
trait).
Second, the fuzz_target!
macro expands to code that has a type error:
// fuzz_target_1.rs
#![no_main]
use libfuzzer_sys::fuzz_target;
fuzz_target!(|data: usize| {
// NB: ^^^^^ type that implements `Arbitrary`
let _ = data;
});
Running cargo fuzz run fuzz_target_1
results in this error:
error[E0308]: mismatched types
--> fuzz_targets/fuzz_target_1.rs:4:1
|
4 | / fuzz_target!(|data: usize| {
5 | | // NB: ^^^^^ type that implements `Arbitrary`
6 | |
7 | | let _ = data;
8 | | });
| |___^ expected enum `arbitrary::BufferError`, found &str
|
= note: expected type `std::result::Result<_, arbitrary::BufferError>`
found type `std::result::Result<_, &str>`
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.
error: could not compile `foobar-fuzz`.
I've been looking through the libFuzzer API, but it's undocumented and quite complex. What I needed was a way to call the fuzzer programmatically on my example with a set timeout.
I know it seems far-fetched, but is there any hope for something like this added to this crate? My only hope right now it to tediously read the source code of libFuzzer until I understand how it works just to be able to simply do what it currently does but be able to invoke it at runtime.
Currently we just output the string as a list of bytes and as a string, but given that we use Arbitrary types it would be nice if we could Debug the output whenever possible.
This would need https://github.com/rust-fuzz/libfuzzer-sys/issues/46 and another patch to libfuzzer to support custom formatters.
@bnjbvr was reporting that starting fuzzing from scratch with a fuzz target that takes an Arbtirary
impl was spending a lot of time on three bytes long inputs, where the Arbitrary
implementation required more input bytes than given. The fuzzer wasn't giving more input bytes fast enough to get to the meaty bits of the fuzz target.
In theory, we could use Arbitrary::size_hint
to create a bunch of random seeds for the corpus of the appropriate size and/or control the maximum length of inputs that libfuzzer will generate.
I'm not sure exactly what this would look like, but it probably requires another env var dance between cargo fuzz
and libfuzzer-sys
like how the debug printing works.
As far as how this is exposed to users, maybe we should add cargo fuzz seed <target>
as a new subcommand?
Or maybe we can just document that users can do something like head -c 100 /dev/random > fuzz/corpus/my-target/my-random-seed
to add a random 100 bytes seed to their fuzz target's corpus to get things off the ground...
IIUC, this allows you to maximize another metric other than source code coverage (e.g. malloc sizes to try and trigger OOMs). Would be particularly useful for JITs that want to get coverage of the JITed code.
It seems like the interface is to define a custom section though, which isn't great: https://cs.github.com/aosp-mirror/platform_system_core/blob/8c8df2284bf81e4e2fe0a1d641983ff9b77b43d3/trusty/fuzz/counters.cpp?q=__libfuzzer_extra_counters#L37
We use this crate to fuzz libra (https://github.com/libra/libra) - and it's been working really well, thank you for this integration!
We tried upgrading to 0.3.3 a while back and had to revert, because the build was breaking on certain machines which don't have LLVM source on the include path. I am not sure how to fix this, but I wanted to file an issue in the hopes someone can hepl fix it.
As far as I can tell, this is due to an upstream issue. 0.3.3 includes an updated version of libfuzzer (0493bb8) which most specifically includes llvm/llvm-project@4548236
This includes a file that's not in the libfuzzer source tree, and I don't see this file being present in this source repo.
I'm not super familiar with how the build.rs
scripts work under the hood, but it seems like we need to ensure that this file is present in the repo and appropriately passed to the include paths for the compiler.
If it's helpful, here are the logs from our system:
OPT_LEVEL = Some("3")
HOST = Some("x86_64-unknown-linux-gnu")
CXX_x86_64-unknown-linux-gnu = None
CXX_x86_64_unknown_linux_gnu = None
HOST_CXX = None
CXX = None
CXXFLAGS_x86_64-unknown-linux-gnu = None
CXXFLAGS_x86_64_unknown_linux_gnu = None
HOST_CXXFLAGS = None
CXXFLAGS = None
CRATE_CC_NO_DEFAULTS = None
DEBUG = Some("true")
CARGO_CFG_TARGET_FEATURE = Some("fxsr,mmx,sse,sse2")
running: "c++" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" "-Wall" "-Wextra" "-std=c++11" "-fno-omit-frame-pointer" "-w" "-o" "/sanitized_root/target/x86_64-unknown-linux-gnu/release/build/libfuzzer-sys-f9d0e2c655ba9127/out/libfuzzer/FuzzerCrossOver.o" "-c" "libfuzzer/FuzzerCrossOver.cpp"
running: "c++" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" "-Wall" "-Wextra" "-std=c++11" "-fno-omit-frame-pointer" "-w" "-o" "/sanitized_root/target/x86_64-unknown-linux-gnu/release/build/libfuzzer-sys-f9d0e2c655ba9127/out/libfuzzer/FuzzerDataFlowTrace.o" "-c" "libfuzzer/FuzzerDataFlowTrace.cpp"
running: "c++" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" "-Wall" "-Wextra" "-std=c++11" "-fno-omit-frame-pointer" "-w" "-o" "/sanitized_root/target/x86_64-unknown-linux-gnu/release/build/libfuzzer-sys-f9d0e2c655ba9127/out/libfuzzer/FuzzerDriver.o" "-c" "libfuzzer/FuzzerDriver.cpp"
running: "c++" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" "-Wall" "-Wextra" "-std=c++11" "-fno-omit-frame-pointer" "-w" "-o" "/sanitized_root/target/x86_64-unknown-linux-gnu/release/build/libfuzzer-sys-f9d0e2c655ba9127/out/libfuzzer/FuzzerExtFunctionsDlsym.o" "-c" "libfuzzer/FuzzerExtFunctionsDlsym.cpp"
running: "c++" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" "-Wall" "-Wextra" "-std=c++11" "-fno-omit-frame-pointer" "-w" "-o" "/sanitized_root/target/x86_64-unknown-linux-gnu/release/build/libfuzzer-sys-f9d0e2c655ba9127/out/libfuzzer/FuzzerExtFunctionsWeak.o" "-c" "libfuzzer/FuzzerExtFunctionsWeak.cpp"
exit code: 0
running: "c++" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" "-Wall" "-Wextra" "-std=c++11" "-fno-omit-frame-pointer" "-w" "-o" "/sanitized_root/target/x86_64-unknown-linux-gnu/release/build/libfuzzer-sys-f9d0e2c655ba9127/out/libfuzzer/FuzzerExtFunctionsWindows.o" "-c" "libfuzzer/FuzzerExtFunctionsWindows.cpp"
running: "c++" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" "-Wall" "-Wextra" "-std=c++11" "-fno-omit-frame-pointer" "-w" "-o" "/sanitized_root/target/x86_64-unknown-linux-gnu/release/build/libfuzzer-sys-f9d0e2c655ba9127/out/libfuzzer/FuzzerExtraCounters.o" "-c" "libfuzzer/FuzzerExtraCounters.cpp"
running: "c++" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" "-Wall" "-Wextra" "-std=c++11" "-fno-omit-frame-pointer" "-w" "-o" "/sanitized_root/target/x86_64-unknown-linux-gnu/release/build/libfuzzer-sys-f9d0e2c655ba9127/out/libfuzzer/FuzzerFork.o" "-c" "libfuzzer/FuzzerFork.cpp"
exit code: 0
exit code: 0
running: "c++" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" "-Wall" "-Wextra" "-std=c++11" "-fno-omit-frame-pointer" "-w" "-o" "/sanitized_root/target/x86_64-unknown-linux-gnu/release/build/libfuzzer-sys-f9d0e2c655ba9127/out/libfuzzer/FuzzerIO.o" "-c" "libfuzzer/FuzzerIO.cpp"
running: "c++" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" "-Wall" "-Wextra" "-std=c++11" "-fno-omit-frame-pointer" "-w" "-o" "/sanitized_root/target/x86_64-unknown-linux-gnu/release/build/libfuzzer-sys-f9d0e2c655ba9127/out/libfuzzer/FuzzerIOPosix.o" "-c" "libfuzzer/FuzzerIOPosix.cpp"
running: "c++" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" "-Wall" "-Wextra" "-std=c++11" "-fno-omit-frame-pointer" "-w" "-o" "/sanitized_root/target/x86_64-unknown-linux-gnu/release/build/libfuzzer-sys-f9d0e2c655ba9127/out/libfuzzer/FuzzerIOWindows.o" "-c" "libfuzzer/FuzzerIOWindows.cpp"
exit code: 0
running: "c++" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" "-Wall" "-Wextra" "-std=c++11" "-fno-omit-frame-pointer" "-w" "-o" "/sanitized_root/target/x86_64-unknown-linux-gnu/release/build/libfuzzer-sys-f9d0e2c655ba9127/out/libfuzzer/FuzzerInterceptors.o" "-c" "libfuzzer/FuzzerInterceptors.cpp"
running: "c++" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" "-Wall" "-Wextra" "-std=c++11" "-fno-omit-frame-pointer" "-w" "-o" "/sanitized_root/target/x86_64-unknown-linux-gnu/release/build/libfuzzer-sys-f9d0e2c655ba9127/out/libfuzzer/FuzzerLoop.o" "-c" "libfuzzer/FuzzerLoop.cpp"
running: "c++" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" "-Wall" "-Wextra" "-std=c++11" "-fno-omit-frame-pointer" "-w" "-o" "/sanitized_root/target/x86_64-unknown-linux-gnu/release/build/libfuzzer-sys-f9d0e2c655ba9127/out/libfuzzer/FuzzerMain.o" "-c" "libfuzzer/FuzzerMain.cpp"
exit code: 0
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:30:45: fatal error: sanitizer/common_interface_defs.h: No such file or directory
cargo:warning= #include <sanitizer/common_interface_defs.h>
cargo:warning= ^
cargo:warning=compilation terminated.
exit code: 1
running: "c++" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" "-Wall" "-Wextra" "-std=c++11" "-fno-omit-frame-pointer" "-w" "-o" "/sanitized_root/target/x86_64-unknown-linux-gnu/release/build/libfuzzer-sys-f9d0e2c655ba9127/out/libfuzzer/FuzzerMerge.o" "-c" "libfuzzer/FuzzerMerge.cpp"
exit code: 0
exit code: 0
exit code: 0
exit code: 0
exit code: 0
exit code: 0
exit code: 0
exit code: 0
exit code: 0
--- stderr
error occurred: Command "c++" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" "-Wall" "-Wextra" "-std=c++11" "-fno-omit-frame-pointer" "-w" "-o" "/sanitized_root/target/x86_64-unknown-linux-gnu/release/build/libfuzzer-sys-f9d0e2c655ba9127/out/libfuzzer/FuzzerInterceptors.o" "-c" "libfuzzer/FuzzerInterceptors.cpp" with args "c++" did not execute successfully (status code exit code: 1).
While taking a look at #89, I noticed that even with the proposed workaround, the ci script fails because the first example doesn't find the panicking input. I guess this is an issue caused by llvm, but I am filing it here because I am not sure.
You can use my fork to reproduce the issue. This was working with an old version of rustc, so I was able to bisect the error. 2021-12-17 is good, 2021-12-18 is bad. This is the failing example:
// example/src/main.rs
fuzz_target!(|data: &[u8]| {
if data == b"banana!" {
panic!("success!");
}
});
rustup override set nightly-2021-12-18
./ci/script.sh
# Fails to find panicking input
INFO: A corpus is not provided, starting from an empty corpus
#2 INITED ft: 15 corp: 1/1b exec/s: 0 rss: 33Mb
#418 NEW ft: 24 corp: 2/8b lim: 8 exec/s: 0 rss: 34Mb L: 7/7 MS: 1 InsertRepeatedBytes-
#100000 DONE ft: 24 corp: 2/8b lim: 994 exec/s: 0 rss: 42Mb
Done 100000 runs in 0 second(s)
rustup override set nightly-2021-12-17
./ci/script.sh
# Everything works as expected
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes
INFO: A corpus is not provided, starting from an empty corpus
#2 INITED ft: 15 corp: 1/1b exec/s: 0 rss: 30Mb
#469 NEW ft: 18 corp: 2/8b lim: 8 exec/s: 0 rss: 30Mb L: 7/7 MS: 2 InsertByte-InsertRepeatedBytes-
thread '<unnamed>' panicked at 'success!', example/src/main.rs:7:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
==5118== ERROR: libFuzzer: deadly signal
I bisected the cause to this PR: rust-lang/rust#91838 which optimizes comparison of slice and array. But note that this is just a library change, so the actual bug was probably already present before. The PR changes the PartialEq implementation from this one, which forwards the implementation to slice-slice comparison:
#[inline]
fn eq(&self, other: &[B]) -> bool {
self[..] == other[..]
}
to this one, which uses array-array comparison:
#[inline]
fn eq(&self, other: &[B]) -> bool {
let b: Result<&[B; N], _> = other.try_into();
match b {
Ok(b) => *self == *b,
Err(_) => false,
}
}
So a quick workaround would be to force slice-slice comparison, like this:
if data == &b"banana!"[..] {
panic!("success!");
}
And that does fix the issue. Another workaround is to use a longer string, which somehow prevents the optimization from happening:
if data == b"a very long banana!" {
panic!("success!");
}
And this also fixes the issue. But obviously it would be better to fix this in the compiler, otherwise there will be many bugs that could have been found by fuzzing but they were not.
I also tried changing the compilation flags, but I did not find any combination that fixed the issue. Also I tried other versions such as the latest nightly 2022-02-28 and the issue is not fixed yet.
I tried comparing the assembly code of the good version and the bad version, and I think the main difference is that in the bad version the banana!
string is stored inside a register as the constant 0x21616e616e6162
, while in the old version it must be stored somewhere else because I did not find that constant.
Also I see that most of the calls to cmp
and test
are preceded by a call to __sanitizer_cov_trace_const_cmp1
, which I assume is the coverage code, while the cmp with 0x21616e616e6162
from the new version does not have such a call, as you can see in this snippet:
movzbl 0x7fff8000(%rax),%r13d
xor %edi,%edi
mov %r13d,%esi
call 0xf6950 <__sanitizer_cov_trace_const_cmp1>
test %r13d,%r13d
jne 0xe0c80 <rust_fuzzer_test_input+3136>
addb $0x1,0x845f2(%rip) # 0x164f8a
addb $0x1,0x845ef(%rip) # 0x164f8e
movzwl 0x4(%r14),%eax
movzbl 0x6(%r14),%ecx
shl $0x10,%ecx
or %eax,%ecx
shl $0x20,%rcx
mov (%r14),%eax
or %rcx,%rax
movabs $0x21616e616e6162,%rcx
cmp %rcx,%rax
je 0xe0d52 <rust_fuzzer_test_input+3346>
addb $0x1,0x845bd(%rip) # 0x164f8f
jmp 0xe0a93 <rust_fuzzer_test_input+2643>
addb $0x1,0x845a3(%rip) # 0x164f81
Here is the full disassembly of the rust_fuzzer_test_input
function, so you can compare the differences: fuzz_main_dissasembly.zip
I hope this report was useful, and if someone knows what is going on then let me know. If I have time I will try to check if the new slice comparison code has ever compiled correctly in older versions of rust, and also I may try to reproduce the bug in C++ and open an issue directly in the llvm repo.
I try use https://lib.rs/crates/libfuzzer-sys information to fuzz rust code.
After run:
cargo rustc --
-C passes='sancov'
-C llvm-args='-sanitizer-coverage-level=3'
-Z sanitizer=address
I run my target/debug/fuzzed
And see:
-fsanitize-coverage=trace-pc-guard is no longer supported by libFuzzer.
Please either migrate to a compiler that supports -fsanitize=fuzzer
or use an older version of libFuzzer
How i can use an older version of libFuzzer ?
The name of the tool we're working with here is called 'libfuzzer', not 'fuzzer'.
It can be difficult to sort out the exact cause of an explicit panic or assert if its message isn't printed, because the exact source line isn't given in the stack trace;
#13 0x7f8810c2fca9 in std::panicking::begin_panic::h29cf9d60248c6dfc /checkout/src/libstd/panicking.rs:411:4
#14 0x7f8810c458f1 in _$LT$mvp_tree..node..Node$LT$T$GT$$GT$::add_child::h3fdba3b9cf987f7a /home/austin/mvp-tree-rs/fuzz/<panic macros>:3
(^^ panic occurred due to a failed `assert!()` at this frame ^^)
#15 0x7f8810c6273a in _$LT$mvp_tree..MvpTree$LT$T$C$$u20$Df$GT$$GT$::insert::find_insert::hef1424b577421142 /home/austin/mvp-tree-rs/src/lib.rs:65:29
The exact line of a panic is included in the message, which makes it pertinent to save it for presentation to the user. This should be done in the panic hook this lib sets, before it aborts the process.
An easy solution would be to invoke the default panic hook first before aborting:
// clear any custom hook
let _ = panic::take_hook():
// get the default hook
let default_hook = panic::take_hook();
panic::set_hook(move |payload| {
default_hook(payload);
std::process::abort();
});
Is there an equivalent of afl-clang-fast
within libfuzzer-sys
?
afl-clang-fast test.c -o test
I would like to develop my own fuzzer and utilize libfuzzer-sys
solely for instrumentation.
The idea: if a project already has property-based tests, whether using proptest
or quickcheck
(or maybe something else?), it's useful to do fuzz testing with those APIs. That way, cargo test
will still run quickly, while cargo fuzz
will reuse all the same property-testing code, generators, etc., and run for as long as you want to see if it can find anything.
$ cargo rustc --bin test -- -C passes='sancov' -C llvm-args='-sanitizer-coverage-level=3' -C llvm-args='-sanitizer-coverage-inline-8bit-counters' -Z sanitizer=address
error: failed to run LLVM passes: unknown pass name 'sancov'
$ rustc --version
rustc 1.72.0-nightly (d59363ad0 2023-06-01)
Can't build it on target x86_64-unknown-linux-musl ...
Seems to be missed to #include <cstddef>
somewhere to be compatible?
running: "c++" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" "-Wall" "-Wextra" "-std=c++11" "-fno-omit-frame-pointer" "-w" "-o" "/home/rocket/Rocket_v0.5.0-rc.2/core/lib/fuzz/target/debug/build/libfuzzer-sys-6a0b651a20d3591b/out/libfuzzer/FuzzerInterceptors.o" "-c" "libfuzzer/FuzzerInterceptors.cpp"
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:62:36: error: 'size_t' has not been declared
cargo:warning= 62 | size_t n) {
cargo:warning= | ^~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp: In function 'int internal_strcmp_strncmp(const char*, const char*, bool, int)':
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:63:3: error: 'size_t' was not declared in this scope; did you mean 'std::size_t'?
cargo:warning= 63 | size_t i = 0;
cargo:warning= | ^~~~~~
cargo:warning= | std::size_t
cargo:warning=In file included from /usr/include/c++/10.3.1/cassert:43,
cargo:warning= from libfuzzer/FuzzerInterceptors.cpp:27:
cargo:warning=/usr/include/c++/10.3.1/x86_64-alpine-linux-musl/bits/c++config.h:264:26: note: 'std::size_t' declared here
cargo:warning= 264 | typedef __SIZE_TYPE__ size_t;
cargo:warning= | ^~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:66:11: error: 'i' was not declared in this scope
cargo:warning= 66 | if (i == n)
cargo:warning= | ^
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:68:7: error: 'i' was not declared in this scope
cargo:warning= 68 | i++;
cargo:warning= | ^
cargo:warning=libfuzzer/FuzzerInterceptors.cpp: At global scope:
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:82:61: error: 'size_t' has not been declared
cargo:warning= 82 | static int internal_strncmp(const char *s1, const char *s2, size_t n) {
cargo:warning= | ^~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:90:60: error: 'size_t' has not been declared
cargo:warning= 90 | static int internal_memcmp(const void *s1, const void *s2, size_t n) {
cargo:warning= | ^~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp: In function 'int internal_memcmp(const void*, const void*, int)':
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:93:8: error: 'size_t' was not declared in this scope; did you mean 'std::size_t'?
cargo:warning= 93 | for (size_t i = 0; i < n; ++i, ++t1, ++t2)
cargo:warning= | ^~~~~~
cargo:warning= | std::size_t
cargo:warning=In file included from /usr/include/c++/10.3.1/cassert:43,
cargo:warning= from libfuzzer/FuzzerInterceptors.cpp:27:
cargo:warning=/usr/include/c++/10.3.1/x86_64-alpine-linux-musl/bits/c++config.h:264:26: note: 'std::size_t' declared here
cargo:warning= 264 | typedef __SIZE_TYPE__ size_t;
cargo:warning= | ^~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:93:22: error: 'i' was not declared in this scope
cargo:warning= 93 | for (size_t i = 0; i < n; ++i, ++t1, ++t2)
cargo:warning= | ^
cargo:warning=libfuzzer/FuzzerInterceptors.cpp: At global scope:
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:99:8: error: 'size_t' does not name a type
cargo:warning= 99 | static size_t internal_strlen(const char *s) {
cargo:warning= | ^~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:30:1: note: 'size_t' is defined in header '<cstddef>'; did you forget to '#include <cstddef>'?
cargo:warning= 29 | #include <dlfcn.h> // for dlsym()
cargo:warning= +++ |+#include <cstddef>
cargo:warning= 30 |
cargo:warning=libfuzzer/FuzzerInterceptors.cpp: In function 'char* internal_strstr(const char*, const char*)':
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:108:3: error: 'size_t' was not declared in this scope; did you mean 'std::size_t'?
cargo:warning= 108 | size_t len1 = internal_strlen(haystack);
cargo:warning= | ^~~~~~
cargo:warning= | std::size_t
cargo:warning=In file included from /usr/include/c++/10.3.1/cassert:43,
cargo:warning= from libfuzzer/FuzzerInterceptors.cpp:27:
cargo:warning=/usr/include/c++/10.3.1/x86_64-alpine-linux-musl/bits/c++config.h:264:26: note: 'std::size_t' declared here
cargo:warning= 264 | typedef __SIZE_TYPE__ size_t;
cargo:warning= | ^~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:109:9: error: expected ';' before 'len2'
cargo:warning= 109 | size_t len2 = internal_strlen(needle);
cargo:warning= | ^~~~~
cargo:warning= | ;
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:110:7: error: 'len1' was not declared in this scope
cargo:warning= 110 | if (len1 < len2)
cargo:warning= | ^~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:110:14: error: 'len2' was not declared in this scope
cargo:warning= 110 | if (len1 < len2)
cargo:warning= | ^~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:112:14: error: expected ';' before 'pos'
cargo:warning= 112 | for (size_t pos = 0; pos <= len1 - len2; pos++) {
cargo:warning= | ^~~~
cargo:warning= | ;
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:112:24: error: 'pos' was not declared in this scope
cargo:warning= 112 | for (size_t pos = 0; pos <= len1 - len2; pos++) {
cargo:warning= | ^~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:112:31: error: 'len1' was not declared in this scope
cargo:warning= 112 | for (size_t pos = 0; pos <= len1 - len2; pos++) {
cargo:warning= | ^~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:112:38: error: 'len2' was not declared in this scope
cargo:warning= 112 | for (size_t pos = 0; pos <= len1 - len2; pos++) {
cargo:warning= | ^~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp: At global scope:
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:124:51: error: 'size_t' has not been declared
cargo:warning= 124 | const void *s2, size_t n, int result);
cargo:warning= | ^~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:126:52: error: 'size_t' has not been declared
cargo:warning= 126 | const char *s2, size_t n, int result);
cargo:warning= | ^~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:128:56: error: 'size_t' has not been declared
cargo:warning= 128 | const char *s2, size_t n, int result);
cargo:warning= | ^~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:137:68: error: 'size_t' has not been declared
cargo:warning= 137 | void __sanitizer_weak_hook_memmem(void *called_pc, const void *s1, size_t len1,
cargo:warning= | ^~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:138:51: error: 'size_t' has not been declared
cargo:warning= 138 | const void *s2, size_t len2, void *result);
cargo:warning= | ^~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:140:52: error: 'size_t' has not been declared
cargo:warning= 140 | DEFINE_REAL(int, bcmp, const void *, const void *, size_t)
cargo:warning= | ^~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:22:39: note: in definition of macro 'DEFINE_REAL'
cargo:warning= 22 | typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \
cargo:warning= | ^~~~~~~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:141:54: error: 'size_t' has not been declared
cargo:warning= 141 | DEFINE_REAL(int, memcmp, const void *, const void *, size_t)
cargo:warning= | ^~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:22:39: note: in definition of macro 'DEFINE_REAL'
cargo:warning= 22 | typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \
cargo:warning= | ^~~~~~~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:142:55: error: 'size_t' has not been declared
cargo:warning= 142 | DEFINE_REAL(int, strncmp, const char *, const char *, size_t)
cargo:warning= | ^~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:22:39: note: in definition of macro 'DEFINE_REAL'
cargo:warning= 22 | typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \
cargo:warning= | ^~~~~~~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:144:59: error: 'size_t' has not been declared
cargo:warning= 144 | DEFINE_REAL(int, strncasecmp, const char *, const char *, size_t)
cargo:warning= | ^~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:22:39: note: in definition of macro 'DEFINE_REAL'
cargo:warning= 22 | typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \
cargo:warning= | ^~~~~~~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:148:43: error: 'size_t' has not been declared
cargo:warning= 148 | DEFINE_REAL(void *, memmem, const void *, size_t, const void *, size_t)
cargo:warning= | ^~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:22:39: note: in definition of macro 'DEFINE_REAL'
cargo:warning= 22 | typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \
cargo:warning= | ^~~~~~~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:148:65: error: 'size_t' has not been declared
cargo:warning= 148 | DEFINE_REAL(void *, memmem, const void *, size_t, const void *, size_t)
cargo:warning= | ^~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:22:39: note: in definition of macro 'DEFINE_REAL'
cargo:warning= 22 | typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \
cargo:warning= | ^~~~~~~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:150:62: error: 'size_t' has not been declared
cargo:warning= 150 | ATTRIBUTE_INTERFACE int bcmp(const char *s1, const char *s2, size_t n) {
cargo:warning= | ^~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:158:64: error: 'size_t' has not been declared
cargo:warning= 158 | ATTRIBUTE_INTERFACE int memcmp(const void *s1, const void *s2, size_t n) {
cargo:warning= | ^~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:166:65: error: 'size_t' has not been declared
cargo:warning= 166 | ATTRIBUTE_INTERFACE int strncmp(const char *s1, const char *s2, size_t n) {
cargo:warning= | ^~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:182:69: error: 'size_t' has not been declared
cargo:warning= 182 | ATTRIBUTE_INTERFACE int strncasecmp(const char *s1, const char *s2, size_t n) {
cargo:warning= | ^~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:212:30: error: 'size_t' has not been declared
cargo:warning= 212 | void *memmem(const void *s1, size_t len1, const void *s2, size_t len2) {
cargo:warning= | ^~~~~~
cargo:warning=libfuzzer/FuzzerInterceptors.cpp:212:59: error: 'size_t' has not been declared
cargo:warning= 212 | void *memmem(const void *s1, size_t len1, const void *s2, size_t len2) {
cargo:warning= | ^~~~~~
exit status: 1
--- stderr
error occurred: Command "c++" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" "-Wall" "-Wextra" "-std=c++11" "-fno-omit-frame-pointer" "-w" "-o" "/home/rocket/Rocket_v0.5.0-rc.2/core/lib/fuzz/target/debug/build/libfuzzer-sys-6a0b651a20d3591b/out/libfuzzer/FuzzerInterceptors.o" "-c" "libfuzzer/FuzzerInterceptors.cpp" with args "c++" did not execute successfully (status code exit status: 1).
Please see the rational and example implementation in this honggfuzz-rs commit:
rust-fuzz/honggfuzz-rs@abe2b4c
There was chatter in #rust-internals a couple days ago by @Manishearth and @nagisa for how to automate some of the libfuzzer process:
https://botbot.me/mozilla/rust-internals/2017-02-18/?msg=81162759&page=1
Hi,
I'm not sure the issue is related to this crate, so feel free to redirect me.
I get the following error and I don't understand what it means:
INFO: Seed: 2943382958
INFO: Loaded 1 modules (10632 inline 8-bit counters): 10632 [0x5566fff84008, 0x5566fff86990),
INFO: Loaded 1 PC tables (6775 PCs): 6775 [0x5566fff86990,0x5566fffa1100),
ERROR: The size of coverage PC tables does not match the
number of instrumented PCs. This might be a compiler bug,
please contact the libFuzzer developers.
Also check https://bugs.llvm.org/show_bug.cgi?id=34636
for possible workarounds (tl;dr: don't use the old GNU ld)
To reproduce, you can try:
# In case the version of rust and cargo-fuzz matters:
rustup toolchain install nightly-2019-11-02
cargo +nightly-2019-11-02 install -f --version=0.5.4 cargo-fuzz
# The actual issue:
git clone [email protected]:ia0/data-encoding.git
cd data-encoding/lib
cargo +nightly-2019-11-02 fuzz run -O -a round_trip
Thanks!
Hi, is there a way to dynamically have more than one corpus folder?
I would like to split in two corpuses, the ones that end in error and the one that end successfully. Is there a way to do this?
With error I mean it shouldn't crash. Many thanks for the help.
In an examples/
directory so one can easily try fuzzing
No license is currently specified. MIT / Apache 2.0 fine with everyone?
@Manishearth @ner0x652 @nagisa
Hi there,
The arbitrary
dependency of libfuzzer-sys
is not locked.
The 1.1
version of arbitrary
can be built with rustc
1.62.1.
But 1.2
version of arbitrary
can be built with rustc
1.63 or newer.
I run into issues with building an old version of an application with a specified rust version, which depends on libfuzzer-sys
. We can avoid this in the future to dep on arbitrary = 1.1
or arbitrary = 1.2
not arbitrary = ^1
.
Thanks in advanced.
Adding a LICENSE file with the full license text would make it easier to include this project in other codebases such as the Android Open Source Project.
Also the reference to the libfuzzer licensing in the README may be out of date. I'm not sure what version of libfuzzer is included, but LLVM was re-licensed with the 9.0 release.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.