From 50892ddc7592009eae6bc4af8b433977c3a3fed7 Mon Sep 17 00:00:00 2001 From: Sameer Puri Date: Thu, 15 Feb 2024 13:45:15 -0800 Subject: [PATCH] Finalize macOS support for libafl_libfuzzer (#1843) * libafl_targets: on macOS, do not provide a default implementation for weak functions * libafl_libfuzzer: update README to talk about macOS specifics * libafl_targets: allow __sanitizer_cov_pcs_init to be called more than once --------- Co-authored-by: Dominik Maier --- libafl_libfuzzer/README.md | 16 ++++++++++++++++ libafl_targets/src/common.h | 11 ++++------- libafl_targets/src/sancov_cmp.rs | 4 ++-- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/libafl_libfuzzer/README.md b/libafl_libfuzzer/README.md index 6fcd0daba8..32b0a454b8 100644 --- a/libafl_libfuzzer/README.md +++ b/libafl_libfuzzer/README.md @@ -51,6 +51,22 @@ As this branch generally offers the highest performance version of `libafl_libfu Remember to `cargo update` often if using the experimental changes, and please [submit an issue] if you encounter problems while using `libfuzzer-best`! +#### macOS + +On macOS, you will need to add weak linking for some functions in a `build.rs` file: + +```rust +fn main() { + for func in [ + "_libafl_main", + "_LLVMFuzzerCustomMutator", + "_LLVMFuzzerCustomCrossOver", + ] { + println!("cargo:rustc-link-arg=-Wl,-U,{func}"); + } +} +``` + #### Caveats Like harnesses built with `libfuzzer-sys`, Rust targets which build other libraries (e.g. C/C++ FFI) may not diff --git a/libafl_targets/src/common.h b/libafl_targets/src/common.h index 69d1a0c184..ae4c6ae401 100644 --- a/libafl_targets/src/common.h +++ b/libafl_targets/src/common.h @@ -140,14 +140,11 @@ typedef uint128_t u128; #else #if defined(__APPLE__) - // On Apple, weak_import and weak attrs behave differently to linux. - - #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \ - __attribute__((weak, visibility("default"))) RETURN_TYPE NAME FUNC_SIG { \ - return (RETURN_TYPE)0; \ - } - #define EXT_FUNC_IMPL(NAME, RETURN_TYPE, FUNC_SIG, WARN) \ + EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) + + // Declare these symbols as weak to allow them to be optionally defined. + #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \ __attribute__((weak, visibility("default"))) RETURN_TYPE NAME FUNC_SIG // Weakly defined globals diff --git a/libafl_targets/src/sancov_cmp.rs b/libafl_targets/src/sancov_cmp.rs index 0d71e17176..0c53240a30 100644 --- a/libafl_targets/src/sancov_cmp.rs +++ b/libafl_targets/src/sancov_cmp.rs @@ -34,11 +34,11 @@ extern "C" { unsafe extern "C" fn __sanitizer_cov_pcs_init(pcs_beg: *const usize, pcs_end: *const usize) { // "The Unsafe Code Guidelines also notably defines that usize and isize are respectively compatible with uintptr_t and intptr_t defined in C." assert!( - PCS_BEG.is_null(), + pcs_beg == PCS_BEG || PCS_BEG.is_null(), "__sanitizer_cov_pcs_init can be called only once." ); assert!( - PCS_END.is_null(), + pcs_end == PCS_END || PCS_END.is_null(), "__sanitizer_cov_pcs_init can be called only once." );