libafl_libfuzzer: rename all symbols and allow mimalloc use (#1565)
* rename allocator symbols to avoid conflict with mimalloc * re-add llvm-tools to CI * rename everything * fixup clippy lint * make fuzzer entries more noticeable :) * rabbit mode * clippy
This commit is contained in:
parent
aa69436b64
commit
1e96652ed2
1
.github/workflows/build_and_test.yml
vendored
1
.github/workflows/build_and_test.yml
vendored
@ -124,6 +124,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
profile: minimal
|
profile: minimal
|
||||||
toolchain: stable
|
toolchain: stable
|
||||||
|
components: llvm-tools
|
||||||
- name: Remove existing clang and LLVM
|
- name: Remove existing clang and LLVM
|
||||||
run: sudo apt purge llvm* clang*
|
run: sudo apt purge llvm* clang*
|
||||||
- name: Install and cache deps
|
- name: Install and cache deps
|
||||||
|
@ -35,6 +35,9 @@ introspection = []
|
|||||||
## `-fsanitize=fuzzer-no-link -l:libafl_libfuzzer_runtime.a`
|
## `-fsanitize=fuzzer-no-link -l:libafl_libfuzzer_runtime.a`
|
||||||
embed-runtime = []
|
embed-runtime = []
|
||||||
|
|
||||||
|
## 🐇
|
||||||
|
rabbit = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libfuzzer-sys = { version = "0.4.7", default-features = false }
|
libfuzzer-sys = { version = "0.4.7", default-features = false }
|
||||||
document-features = { version = "0.2" }
|
document-features = { version = "0.2" }
|
||||||
|
@ -1,5 +1,17 @@
|
|||||||
use std::{path::PathBuf, process::Command};
|
use std::{
|
||||||
|
fs::File,
|
||||||
|
io::{BufRead, BufReader, BufWriter, Write},
|
||||||
|
path::PathBuf,
|
||||||
|
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();
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_lines)]
|
||||||
fn main() {
|
fn main() {
|
||||||
if cfg!(any(feature = "cargo-clippy", docsrs)) {
|
if cfg!(any(feature = "cargo-clippy", docsrs)) {
|
||||||
return; // skip when clippy or docs is running
|
return; // skip when clippy or docs is running
|
||||||
@ -69,20 +81,143 @@ fn main() {
|
|||||||
let mut lib_path = custom_lib_dir.join(std::env::var_os("TARGET").unwrap());
|
let mut lib_path = custom_lib_dir.join(std::env::var_os("TARGET").unwrap());
|
||||||
lib_path.push("release");
|
lib_path.push("release");
|
||||||
|
|
||||||
#[cfg(all(feature = "embed-runtime", target_family = "unix"))]
|
if cfg!(target_family = "unix") {
|
||||||
{
|
use std::path::Path;
|
||||||
// NOTE: lib, .a are added always on unix-like systems as described in:
|
|
||||||
// https://gist.github.com/novafacing/1389cbb2f0a362d7eb103e67b4468e2b
|
lib_path.push("libafl_libfuzzer_runtime.a");
|
||||||
println!(
|
let target_libdir = Command::new("rustc")
|
||||||
"cargo:rustc-env=LIBAFL_LIBFUZZER_RUNTIME_PATH={}",
|
.args(["--print", "target-libdir"])
|
||||||
lib_path.join("libafl_libfuzzer_runtime.a").display()
|
.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 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");
|
||||||
|
|
||||||
|
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 child = Command::new(nm)
|
||||||
|
.arg(&objfile_orig)
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut redefinitions_file = BufWriter::new(File::create(&redefined_symbols).unwrap());
|
||||||
|
|
||||||
|
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() {
|
||||||
|
let line = line.unwrap();
|
||||||
|
let (_, symbol) = line.rsplit_once(' ').unwrap();
|
||||||
|
if symbol.starts_with("_ZN") {
|
||||||
|
writeln!(
|
||||||
|
redefinitions_file,
|
||||||
|
"{} {}",
|
||||||
|
symbol,
|
||||||
|
symbol.replacen("_ZN", &replacement, 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
|
||||||
|
.arg("--redefine-syms")
|
||||||
|
.arg(redefined_symbols)
|
||||||
|
.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-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++");
|
println!("cargo:rustc-link-lib=stdc++");
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ libafl_targets = { path = "../../libafl_targets", features = ["sancov_8bit", "sa
|
|||||||
ahash = { version = "0.8.3", default-features = false }
|
ahash = { version = "0.8.3", default-features = false }
|
||||||
libc = "0.2.139"
|
libc = "0.2.139"
|
||||||
log = "0.4.17"
|
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"
|
num-traits = "0.2.15"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
serde = { version = "1.0", features = ["derive"] } # serialization lib
|
serde = { version = "1.0", features = ["derive"] } # serialization lib
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use std::{env, path::Path};
|
use std::{env, path::Path};
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_lines)]
|
||||||
fn main() {
|
fn main() {
|
||||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||||
|
|
||||||
|
@ -80,8 +80,11 @@ use libafl::{
|
|||||||
};
|
};
|
||||||
use libafl_bolts::AsSlice;
|
use libafl_bolts::AsSlice;
|
||||||
use libc::_exit;
|
use libc::_exit;
|
||||||
|
use mimalloc::MiMalloc;
|
||||||
|
|
||||||
use crate::options::{LibfuzzerMode, LibfuzzerOptions};
|
use crate::options::{LibfuzzerMode, LibfuzzerOptions};
|
||||||
|
#[global_allocator]
|
||||||
|
static GLOBAL: MiMalloc = MiMalloc;
|
||||||
|
|
||||||
mod corpus;
|
mod corpus;
|
||||||
mod feedbacks;
|
mod feedbacks;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user