diff --git a/fuzzers/libfuzzer_libmozjpeg/README.md b/fuzzers/libfuzzer_libmozjpeg/README.md index 9a823669c6..b302a1b2bb 100644 --- a/fuzzers/libfuzzer_libmozjpeg/README.md +++ b/fuzzers/libfuzzer_libmozjpeg/README.md @@ -1,16 +1,32 @@ # Libfuzzer for libmozjpeg This folder contains an example fuzzer for libmozjpeg, using LLMP for fast multi-process fuzzing and crash detection. +Alongside the traditional edge coverage, this example shows how to use a value-profile like feedback to bypass CMPs and an allocations size maximization feedback to spot patological inputs in terms of memory usage. It has been tested on Linux. -https://github.com/mozilla/mozjpeg/archive/v4.0.3.tar.gz - ## Build -To build this example, run `cargo build --example libfuzzer_libmozjpeg --release`. -This will call (the build.rs)[./builld.rs], which in turn downloads a libmozjpeg archive from the web. -Then, it will link (the fuzzer)[./src/fuzzer.rs] against (the c++ harness)[./harness.cc] and the instrumented `libmozjpeg`. -Afterwards, the fuzzer will be ready to run, from `../../target/examples/libfuzzer_libmozjpeg`. +To build this example, run `cargo build --release`. +This will build the library with the fuzzer (src/lib.rs) with the libfuzzer compatibility layer. the SanitizerCoverage runtime functions for edges and value-profile feedbacks and the `hook_allocs.c` C file that hooks the allocator to report the size to the fuzzer. +In addition, it will build also two C and C++ compiler wrappers (bin/c(c/xx).rs) that you must use to compile the target. + +Then download the mozjpeg source tarball from https://github.com/mozilla/mozjpeg/archive/v4.0.3.tar.gz and unpack the archive. + +Now compile it with: + +``` +cd mozjpeg-4.0.3 +cmake --disable-shared . -DCMAKE_C_COMPILER=/path/to/libfuzzer_mozjpeg/target/release/cc -DCMAKE_CXX_COMPILER=/path/to/libfuzzer_mozjpeg/target/release/cxx -G "Unix Makefiles" +make -j `nproc` +``` + +Now, we have to build the libfuzzer harness and link all togheter to create our fuzzer binary. + +``` +/path/to/libfuzzer_libpng/target/debug/cxx /path/to/libfuzzer_libpng/harness.cc mozjpeg-4.0.3/*.a -I mozjpeg-4.0.3/ -o fuzzer +``` + +Afterwards, the fuzzer will be ready to run simply executing `./fuzzer`. ## Run @@ -21,10 +37,4 @@ As this example uses in-process fuzzing, we added a Restarting Event Manager (`s This means each client will start itself again to listen for crashes and timeouts. By restarting the actual fuzzer, it can recover from these exit conditions. -For convenience, you may just run `./test.sh` in this folder or: - -broker.sh - starts the broker -start.sh - starts as many clients as there are cores -stop.sh - stop everything - - +In any real-world scenario, you should use `taskset` to pin each client to an empty CPU core, the lib does not pick an empty core automatically (yet). diff --git a/libafl_targets/build.rs b/libafl_targets/build.rs index 8062540719..250196da36 100644 --- a/libafl_targets/build.rs +++ b/libafl_targets/build.rs @@ -6,8 +6,8 @@ use std::path::Path; fn main() { let out_dir = env::var_os("OUT_DIR").unwrap(); let out_dir = out_dir.to_string_lossy().to_string(); - let src_dir = Path::new("src"); //let out_dir_path = Path::new(&out_dir); + let _src_dir = Path::new("src"); //std::env::set_var("CC", "clang"); //std::env::set_var("CXX", "clang++"); @@ -17,7 +17,7 @@ fn main() { println!("cargo:rerun-if-changed=src/libfuzzer_compatibility.c"); cc::Build::new() - .file(src_dir.join("libfuzzer_compatibility.c")) + .file(_src_dir.join("libfuzzer_compatibility.c")) .compile("libfuzzer_compatibility"); } @@ -26,7 +26,7 @@ fn main() { println!("cargo:rerun-if-changed=src/value_profile.c"); cc::Build::new() - .file(src_dir.join("value_profile.c")) + .file(_src_dir.join("value_profile.c")) .compile("value_profile"); }