From 3576250771871b10688828e88597b4ae227acde9 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Wed, 27 Sep 2023 18:01:26 +0200 Subject: [PATCH 1/7] rename allocator symbols to avoid conflict with mimalloc --- libafl_libfuzzer/build.rs | 100 ++++++++++++++++-- .../libafl_libfuzzer_runtime/Cargo.toml | 2 +- .../libafl_libfuzzer_runtime/src/lib.rs | 3 + 3 files changed, 93 insertions(+), 12 deletions(-) diff --git a/libafl_libfuzzer/build.rs b/libafl_libfuzzer/build.rs index f4c701c4fa5..bdd0c6dbc59 100644 --- a/libafl_libfuzzer/build.rs +++ b/libafl_libfuzzer/build.rs @@ -69,20 +69,98 @@ fn main() { let mut lib_path = custom_lib_dir.join(std::env::var_os("TARGET").unwrap()); lib_path.push("release"); - #[cfg(all(feature = "embed-runtime", target_family = "unix"))] - { - // NOTE: lib, .a are added always on unix-like systems as described in: - // https://gist.github.com/novafacing/1389cbb2f0a362d7eb103e67b4468e2b + if cfg!(target_family = "unix") { + use std::path::Path; + + lib_path.push("libafl_libfuzzer_runtime.a"); + let target_libdir = Command::new("rustc") + .args(["--print", "target-libdir"]) + .output() + .expect("Couldn't find rustc's target-libdir"); + let target_libdir = String::from_utf8(target_libdir.stdout).unwrap(); + let target_libdir = Path::new(target_libdir.trim()); + + let rust_lld = target_libdir.join("../bin/rust-lld"); + let rust_ar = target_libdir.join("../bin/llvm-ar"); // NOTE: depends on llvm-tools + let rust_objcopy = target_libdir.join("../bin/llvm-objcopy"); // NOTE: depends on llvm-tools + + let objfile_orig = custom_lib_dir.join("libFuzzer.o"); + let objfile_dest = custom_lib_dir.join("libFuzzer-mimalloc.o"); + + let mut command = Command::new(rust_lld); + command + .args(["-flavor", "gnu"]) + .arg("-r") + .arg("--whole-archive") + .arg(lib_path) + .args(["-o", objfile_orig.to_str().expect("Invalid path characters present in your current directory prevent us from linking to the runtime")]); + + assert!( + !command.status().map(|s| !s.success()).unwrap_or(true), + "Couldn't link runtime crate! Do you have the llvm-tools component installed?" + ); + + let mut command = Command::new(rust_objcopy); + command + .args(["--redefine-sym", "__rust_alloc=__rust_alloc_mimalloc"]) + .args(["--redefine-sym", "__rust_dealloc=__rust_dealloc_mimalloc"]) + .args(["--redefine-sym", "__rust_realloc=__rust_realloc_mimalloc"]) + .args([ + "--redefine-sym", + "__rust_alloc_zeroed=__rust_alloc_zeroed_mimalloc", + ]) + .args([ + "--redefine-sym", + "__rust_alloc_error_handler=__rust_alloc_error_handler_mimalloc", + ]) + .args([ + "--redefine-sym", + "__rust_no_alloc_shim_is_unstable=__rust_no_alloc_shim_is_unstable_mimalloc", + ]) + .args([ + "--redefine-sym", + "__rust_alloc_error_handler_should_panic=__rust_alloc_error_handler_should_panic_mimalloc", + ]) + .args([&objfile_orig, &objfile_dest]); + + assert!( + !command.status().map(|s| !s.success()).unwrap_or(true), + "Couldn't rename allocators in the runtime crate! Do you have the llvm-tools component installed?" + ); + + let mut command = Command::new(rust_ar); + command + .arg("cr") + .arg(custom_lib_dir.join("libFuzzer.a")) + .arg(objfile_dest); + + assert!( + !command.status().map(|s| !s.success()).unwrap_or(true), + "Couldn't create runtime archive!" + ); + + #[cfg(feature = "embed-runtime")] + { + // NOTE: lib, .a are added always on unix-like systems as described in: + // https://gist.github.com/novafacing/1389cbb2f0a362d7eb103e67b4468e2b + println!( + "cargo:rustc-env=LIBAFL_LIBFUZZER_RUNTIME_PATH={}", + custom_lib_dir.join("libFuzzer.a").display() + ); + } + println!( - "cargo:rustc-env=LIBAFL_LIBFUZZER_RUNTIME_PATH={}", - lib_path.join("libafl_libfuzzer_runtime.a").display() + "cargo:rustc-link-search=native={}", + custom_lib_dir.to_str().unwrap() ); + println!("cargo:rustc-link-lib=static=Fuzzer"); + } else { + println!( + "cargo:rustc-link-search=native={}", + lib_path.to_str().unwrap() + ); + println!("cargo:rustc-link-lib=static=afl_fuzzer_runtime"); } - println!( - "cargo:rustc-link-search=native={}", - lib_path.to_str().unwrap() - ); - println!("cargo:rustc-link-lib=static=afl_libfuzzer_runtime"); println!("cargo:rustc-link-lib=stdc++"); } diff --git a/libafl_libfuzzer/libafl_libfuzzer_runtime/Cargo.toml b/libafl_libfuzzer/libafl_libfuzzer_runtime/Cargo.toml index e7824bf5a73..18b9eab450a 100644 --- a/libafl_libfuzzer/libafl_libfuzzer_runtime/Cargo.toml +++ b/libafl_libfuzzer/libafl_libfuzzer_runtime/Cargo.toml @@ -37,7 +37,7 @@ libafl_targets = { path = "../../libafl_targets", features = ["sancov_8bit", "sa ahash = { version = "0.8.3", default-features = false } libc = "0.2.139" log = "0.4.17" -mimalloc = { version = "0.1.34", default-features = false, optional = true } +mimalloc = { version = "0.1.34", default-features = false } num-traits = "0.2.15" rand = "0.8.5" serde = { version = "1.0", features = ["derive"] } # serialization lib diff --git a/libafl_libfuzzer/libafl_libfuzzer_runtime/src/lib.rs b/libafl_libfuzzer/libafl_libfuzzer_runtime/src/lib.rs index 12734b60b22..3de1b59cc39 100644 --- a/libafl_libfuzzer/libafl_libfuzzer_runtime/src/lib.rs +++ b/libafl_libfuzzer/libafl_libfuzzer_runtime/src/lib.rs @@ -80,8 +80,11 @@ use libafl::{ }; use libafl_bolts::AsSlice; use libc::_exit; +use mimalloc::MiMalloc; use crate::options::{LibfuzzerMode, LibfuzzerOptions}; +#[global_allocator] +static GLOBAL: MiMalloc = MiMalloc; mod corpus; mod feedbacks; From 64055463435aa9f38886ca992383f676b35eccd6 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Wed, 27 Sep 2023 18:05:29 +0200 Subject: [PATCH 2/7] re-add llvm-tools to CI --- .github/workflows/build_and_test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index e79bf28a7d1..558eab4c536 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -124,6 +124,7 @@ jobs: with: profile: minimal toolchain: stable + components: llvm-tools - name: Remove existing clang and LLVM run: sudo apt purge llvm* clang* - name: Install and cache deps From 79069d52be60f6f39087c59ca46dad221c385782 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Wed, 27 Sep 2023 19:48:41 +0200 Subject: [PATCH 3/7] rename everything --- libafl_libfuzzer/build.rs | 88 ++++++++++++++++++++++++++++++--------- 1 file changed, 68 insertions(+), 20 deletions(-) diff --git a/libafl_libfuzzer/build.rs b/libafl_libfuzzer/build.rs index bdd0c6dbc59..952c1180cd7 100644 --- a/libafl_libfuzzer/build.rs +++ b/libafl_libfuzzer/build.rs @@ -1,4 +1,9 @@ -use std::{path::PathBuf, process::Command}; +use std::{ + fs::File, + io::{BufRead, BufReader, BufWriter, Write}, + path::PathBuf, + process::{Command, Stdio}, +}; fn main() { if cfg!(any(feature = "cargo-clippy", docsrs)) { @@ -83,6 +88,9 @@ fn main() { let rust_lld = target_libdir.join("../bin/rust-lld"); let rust_ar = target_libdir.join("../bin/llvm-ar"); // NOTE: depends on llvm-tools let rust_objcopy = target_libdir.join("../bin/llvm-objcopy"); // NOTE: depends on llvm-tools + let nm = "nm"; // NOTE: we use system nm here because llvm-nm doesn't respect the encoding? + + let redefined_symbols = custom_lib_dir.join("redefs.txt"); let objfile_orig = custom_lib_dir.join("libFuzzer.o"); let objfile_dest = custom_lib_dir.join("libFuzzer-mimalloc.o"); @@ -100,27 +108,67 @@ fn main() { "Couldn't link runtime crate! Do you have the llvm-tools component installed?" ); + let mut child = Command::new(nm) + .arg(&objfile_orig) + .stdout(Stdio::piped()) + .spawn() + .unwrap(); + + let mut redefinitions_file = BufWriter::new(File::create(&redefined_symbols).unwrap()); + + // redefine all the rust-mangled symbols we can + // TODO this will break when v0 mangling is stabilised + for line in BufReader::new(child.stdout.take().unwrap()).lines() { + let line = line.unwrap(); + let (_, symbol) = line.rsplit_once(' ').unwrap(); + if symbol.starts_with("_ZN") { + writeln!( + redefinitions_file, + "{} {}", + symbol, + symbol.replacen("_ZN", "_ZN26__libafl_libfuzzer_runtime", 1) + ) + .unwrap(); + } + } + redefinitions_file.flush().unwrap(); + drop(redefinitions_file); + + assert!( + !child.wait().map(|s| !s.success()).unwrap_or(true), + "Couldn't link runtime crate! Do you have the llvm-tools component installed?" + ); + let mut command = Command::new(rust_objcopy); + + for symbol in [ + "__rust_drop_panic", + "__rust_foreign_exception", + "rust_begin_unwind", + "rust_panic", + "rust_eh_personality", + "__rg_oom", + "__rdl_oom", + "__rdl_alloc", + "__rust_alloc", + "__rdl_dealloc", + "__rust_dealloc", + "__rdl_realloc", + "__rust_realloc", + "__rdl_alloc_zeroed", + "__rust_alloc_zeroed", + "__rust_alloc_error_handler", + "__rust_no_alloc_shim_is_unstable", + "__rust_alloc_error_handler_should_panic", + ] { + command + .arg("--redefine-sym") + .arg(format!("{symbol}={symbol}_libafl_libfuzzer_runtime")); + } + command - .args(["--redefine-sym", "__rust_alloc=__rust_alloc_mimalloc"]) - .args(["--redefine-sym", "__rust_dealloc=__rust_dealloc_mimalloc"]) - .args(["--redefine-sym", "__rust_realloc=__rust_realloc_mimalloc"]) - .args([ - "--redefine-sym", - "__rust_alloc_zeroed=__rust_alloc_zeroed_mimalloc", - ]) - .args([ - "--redefine-sym", - "__rust_alloc_error_handler=__rust_alloc_error_handler_mimalloc", - ]) - .args([ - "--redefine-sym", - "__rust_no_alloc_shim_is_unstable=__rust_no_alloc_shim_is_unstable_mimalloc", - ]) - .args([ - "--redefine-sym", - "__rust_alloc_error_handler_should_panic=__rust_alloc_error_handler_should_panic_mimalloc", - ]) + .arg("--redefine-syms") + .arg(redefined_symbols) .args([&objfile_orig, &objfile_dest]); assert!( From 426890661d6581d17abfa4d3d6679793e00091d5 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Wed, 27 Sep 2023 22:05:44 +0200 Subject: [PATCH 4/7] fixup clippy lint --- libafl_libfuzzer/libafl_libfuzzer_runtime/build.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/libafl_libfuzzer/libafl_libfuzzer_runtime/build.rs b/libafl_libfuzzer/libafl_libfuzzer_runtime/build.rs index 85b12f47bc8..c2566b847f9 100644 --- a/libafl_libfuzzer/libafl_libfuzzer_runtime/build.rs +++ b/libafl_libfuzzer/libafl_libfuzzer_runtime/build.rs @@ -1,5 +1,6 @@ use std::{env, path::Path}; +#[allow(clippy::too_many_lines)] fn main() { let out_dir = env::var_os("OUT_DIR").unwrap(); From ddedadca2c08135379dec88e47fee911d27fc81c Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Thu, 28 Sep 2023 02:59:00 +0200 Subject: [PATCH 5/7] make fuzzer entries more noticeable :) --- libafl_libfuzzer/build.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libafl_libfuzzer/build.rs b/libafl_libfuzzer/build.rs index 952c1180cd7..bbb3f49b1bc 100644 --- a/libafl_libfuzzer/build.rs +++ b/libafl_libfuzzer/build.rs @@ -116,6 +116,11 @@ fn main() { let mut redefinitions_file = BufWriter::new(File::create(&redefined_symbols).unwrap()); + const NAMESPACE: &str = "🐇"; + const NAMESPACE_LEN: usize = NAMESPACE.as_bytes().len(); + + let replacement = format!("_ZN{NAMESPACE_LEN}{NAMESPACE}"); + // redefine all the rust-mangled symbols we can // TODO this will break when v0 mangling is stabilised for line in BufReader::new(child.stdout.take().unwrap()).lines() { @@ -126,7 +131,7 @@ fn main() { redefinitions_file, "{} {}", symbol, - symbol.replacen("_ZN", "_ZN26__libafl_libfuzzer_runtime", 1) + symbol.replacen("_ZN", &replacement, 1) ) .unwrap(); } From f482614134df3a26bff274bbcdcacba5ffe9d3e3 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Fri, 29 Sep 2023 01:27:35 +0200 Subject: [PATCH 6/7] rabbit mode --- libafl_libfuzzer/Cargo.toml | 3 +++ libafl_libfuzzer/build.rs | 9 ++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/libafl_libfuzzer/Cargo.toml b/libafl_libfuzzer/Cargo.toml index 1182d4a3341..c358480692a 100644 --- a/libafl_libfuzzer/Cargo.toml +++ b/libafl_libfuzzer/Cargo.toml @@ -35,6 +35,9 @@ introspection = [] ## `-fsanitize=fuzzer-no-link -l:libafl_libfuzzer_runtime.a` embed-runtime = [] +## 🐇 +rabbit = [] + [dependencies] libfuzzer-sys = { version = "0.4.7", default-features = false } document-features = { version = "0.2" } diff --git a/libafl_libfuzzer/build.rs b/libafl_libfuzzer/build.rs index bbb3f49b1bc..43903354ab0 100644 --- a/libafl_libfuzzer/build.rs +++ b/libafl_libfuzzer/build.rs @@ -5,6 +5,12 @@ use std::{ process::{Command, Stdio}, }; +#[cfg(feature = "rabbit")] +const NAMESPACE: &str = "🐇"; +#[cfg(not(feature = "rabbit"))] +const NAMESPACE: &str = "__libafl"; +const NAMESPACE_LEN: usize = NAMESPACE.as_bytes().len(); + fn main() { if cfg!(any(feature = "cargo-clippy", docsrs)) { return; // skip when clippy or docs is running @@ -116,9 +122,6 @@ fn main() { let mut redefinitions_file = BufWriter::new(File::create(&redefined_symbols).unwrap()); - const NAMESPACE: &str = "🐇"; - const NAMESPACE_LEN: usize = NAMESPACE.as_bytes().len(); - let replacement = format!("_ZN{NAMESPACE_LEN}{NAMESPACE}"); // redefine all the rust-mangled symbols we can From 87fdcaff2a0ac60246fb16165cf1f39690ed7a03 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Fri, 29 Sep 2023 01:27:59 +0200 Subject: [PATCH 7/7] clippy --- libafl_libfuzzer/build.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/libafl_libfuzzer/build.rs b/libafl_libfuzzer/build.rs index 43903354ab0..a5348203456 100644 --- a/libafl_libfuzzer/build.rs +++ b/libafl_libfuzzer/build.rs @@ -11,6 +11,7 @@ const NAMESPACE: &str = "🐇"; const NAMESPACE: &str = "__libafl"; const NAMESPACE_LEN: usize = NAMESPACE.as_bytes().len(); +#[allow(clippy::too_many_lines)] fn main() { if cfg!(any(feature = "cargo-clippy", docsrs)) { return; // skip when clippy or docs is running