From 6431d066ae0dd32d4e418201d921cf3c1e6c3a52 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Fri, 28 Nov 2025 14:02:19 +0100 Subject: [PATCH 1/4] begin v0 fix attempt --- crates/libafl_libfuzzer/build.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/crates/libafl_libfuzzer/build.rs b/crates/libafl_libfuzzer/build.rs index 8726b92973c..c81ade86228 100644 --- a/crates/libafl_libfuzzer/build.rs +++ b/crates/libafl_libfuzzer/build.rs @@ -185,7 +185,6 @@ fn main() -> Result<(), Box> { let replacement = format!("{zn_prefix}{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(nm_child.stdout.take().unwrap()).lines() { let line = line.unwrap(); @@ -196,9 +195,13 @@ fn main() -> Result<(), Box> { let (_, symbol) = line.rsplit_once(' ').unwrap(); if symbol.starts_with(rn_prefix) { - let (_prefix, renamed) = symbol.split_once("__rustc").unwrap(); - let (size, renamed) = renamed.split_once('_').unwrap(); - writeln!(redefinitions_file, "{symbol} {replacement}{size}{renamed}E").unwrap(); + if let Some((_prefix, renamed)) = symbol.split_once("__rustc") { + let (size, renamed) = renamed.split_once('_').unwrap(); + writeln!(redefinitions_file, "{symbol} {replacement}{size}{renamed}E").unwrap(); + } else { + // v0 mangling: this uses the vendor-specific suffix model + writeln!(redefinitions_file, "{symbol} {symbol}${NAMESPACE}").unwrap(); + } } else if symbol.starts_with(zn_prefix) { writeln!( redefinitions_file, From 25c2a9877250a9bc9b9d32a853fc07dc69ed2dcc Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Fri, 28 Nov 2025 14:13:11 +0100 Subject: [PATCH 2/4] v0 mangling fixed --- crates/libafl_libfuzzer/build.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/crates/libafl_libfuzzer/build.rs b/crates/libafl_libfuzzer/build.rs index c81ade86228..ec659b140ff 100644 --- a/crates/libafl_libfuzzer/build.rs +++ b/crates/libafl_libfuzzer/build.rs @@ -174,6 +174,12 @@ fn main() -> Result<(), Box> { } else { "_RN" }; + let r_prefix = if cfg!(target_os = "macos") { + // macOS symbols have an extra `_` + "__R" + } else { + "_R" + }; let zn_prefix = if cfg!(target_os = "macos") { // macOS symbols have an extra `_` @@ -209,6 +215,9 @@ fn main() -> Result<(), Box> { symbol.replacen(zn_prefix, &replacement, 1) ) .unwrap(); + } else if symbol.starts_with(r_prefix) { + // v0 mangling (not in namespace): this uses the vendor-specific suffix model + writeln!(redefinitions_file, "{symbol} {symbol}${NAMESPACE}").unwrap(); } } redefinitions_file.flush().unwrap(); From 884ccd69815f12413d469c0d8713bb79ebb04482 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Fri, 28 Nov 2025 14:55:45 +0100 Subject: [PATCH 3/4] refactor: split out renaming --- crates/libafl_libfuzzer/build.rs | 52 ++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/crates/libafl_libfuzzer/build.rs b/crates/libafl_libfuzzer/build.rs index ec659b140ff..3dc34463c92 100644 --- a/crates/libafl_libfuzzer/build.rs +++ b/crates/libafl_libfuzzer/build.rs @@ -142,6 +142,35 @@ fn main() -> Result<(), Box> { "Couldn't build runtime crate! Did you remember to use nightly? (`rustup default nightly` to install)" ); + rename_symbols(&custom_lib_target); + + #[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={}", + redefined_archive_path.display() + ); + } + + println!( + "cargo:rustc-link-search=native={}", + custom_lib_target.to_str().unwrap() + ); + println!("cargo:rustc-link-lib=static=Fuzzer"); + + if cfg!(target_os = "macos") { + println!("cargo:rustc-link-lib=c++"); + } else { + println!("cargo:rustc-link-lib=stdc++"); + } + Ok(()) +} + +/// This function creates a copy of the libfuzzer runtime with all the symbols renamed to avoid +/// a conflict with whatever we link to. It should be compatible with legacy and v0 mangling. +fn rename_symbols(custom_lib_target: &Path) { let mut archive_path = custom_lib_target.join(std::env::var_os("TARGET").unwrap()); archive_path.push("release"); @@ -270,27 +299,4 @@ fn main() -> Result<(), Box> { objcopy_command.status().is_ok_and(|s| s.success()), "Couldn't rename allocators in the runtime crate! Do you have the llvm-tools component installed? (`rustup component add llvm-tools-preview` to install)" ); - - #[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={}", - redefined_archive_path.display() - ); - } - - println!( - "cargo:rustc-link-search=native={}", - custom_lib_target.to_str().unwrap() - ); - println!("cargo:rustc-link-lib=static=Fuzzer"); - - if cfg!(target_os = "macos") { - println!("cargo:rustc-link-lib=c++"); - } else { - println!("cargo:rustc-link-lib=stdc++"); - } - Ok(()) } From 3de999fb13b6424dc2ee341c0dc5cc3e8985882e Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Fri, 28 Nov 2025 16:37:10 +0100 Subject: [PATCH 4/4] clippy nit --- crates/libafl_libfuzzer/build.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/libafl_libfuzzer/build.rs b/crates/libafl_libfuzzer/build.rs index 3dc34463c92..efb5bdce59c 100644 --- a/crates/libafl_libfuzzer/build.rs +++ b/crates/libafl_libfuzzer/build.rs @@ -142,10 +142,9 @@ fn main() -> Result<(), Box> { "Couldn't build runtime crate! Did you remember to use nightly? (`rustup default nightly` to install)" ); - rename_symbols(&custom_lib_target); + let redefined_archive_path = rename_symbols(&custom_lib_target); - #[cfg(feature = "embed-runtime")] - { + if cfg!(feature = "embed-runtime") { // NOTE: lib, .a are added always on unix-like systems as described in: // https://gist.github.com/novafacing/1389cbb2f0a362d7eb103e67b4468e2b println!( @@ -170,7 +169,7 @@ fn main() -> Result<(), Box> { /// This function creates a copy of the libfuzzer runtime with all the symbols renamed to avoid /// a conflict with whatever we link to. It should be compatible with legacy and v0 mangling. -fn rename_symbols(custom_lib_target: &Path) { +fn rename_symbols(custom_lib_target: &Path) -> PathBuf { let mut archive_path = custom_lib_target.join(std::env::var_os("TARGET").unwrap()); archive_path.push("release"); @@ -299,4 +298,5 @@ fn rename_symbols(custom_lib_target: &Path) { objcopy_command.status().is_ok_and(|s| s.success()), "Couldn't rename allocators in the runtime crate! Do you have the llvm-tools component installed? (`rustup component add llvm-tools-preview` to install)" ); + redefined_archive_path }