From b250190f864d3cb2deb9f7ba933f624393b03b7b Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 24 Sep 2025 10:31:25 +0200 Subject: [PATCH 01/35] add AFL++ IJON functionality --- afl/src/lib.rs | 191 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 190 insertions(+), 1 deletion(-) diff --git a/afl/src/lib.rs b/afl/src/lib.rs index e9b3d58d0..3ebb3f005 100644 --- a/afl/src/lib.rs +++ b/afl/src/lib.rs @@ -9,7 +9,7 @@ use std::env; use std::io::{self, Read}; use std::panic; -// those functions are provided by the afl-llvm-rt static library +// those functions are provided by the afl-compiler-rt static library unsafe extern "C" { fn __afl_persistent_loop(counter: usize) -> isize; fn __afl_manual_init(); @@ -18,6 +18,195 @@ unsafe extern "C" { static __afl_fuzz_ptr: *const u8; } +// AFL++ IJON functions in afl-compiler-rt +unsafe extern "C" { + pub fn ijon_max(addr: u32, val: u64); + pub fn ijon_min(addr: u32, val: u64); + pub fn ijon_set(addr: u32, val: u32); + pub fn ijon_inc(addr: u32, val: u32); + pub fn ijon_xor_state(val: u32); + pub fn ijon_reset_state(); + pub fn ijon_simple_hash(x: u64) -> u64; + pub fn ijon_hashint(old: u32, val: u32) -> u32; + pub fn ijon_hashstr(old: u32, val: *const u8) -> u32; + pub fn ijon_hashmen(old: u32, val: *const u8, len: usize) -> u32; + pub fn ijon_hashstack_backtrace() -> u32; + pub fn ijon_hashstack() -> u32; + pub fn ijon_strdist(a: *const u8, b: *const u8) -> u32; + pub fn ijon_memdist(a: *const u8, b: *const u8, len: usize) -> u32; + pub fn ijon_max_variadic(addr: u32, ...); + pub fn ijon_min_variadic(addr: u32, ...); +} + +#[macro_export] +macro_rules! ijon_inc { + ($x:expr) => {{ + use std::sync::atomic::{AtomicU32, Ordering}; + static LOC_CACHE: AtomicU32 = AtomicU32::new(0); + let mut loc = LOC_CACHE.load(Ordering::Relaxed); + if loc == 0 { + let new_val = ijon_hashstr(line!(), file!()); + LOC_CACHE.store(new_val, Ordering::Relaxed); + loc = new_val; + } + ijon_inc(loc, $x); + }}; +} + +#[macro_export] +macro_rules! ijon_max { + ($($x:expr),+ $(,)?) => {{ + use std::sync::atomic::{AtomicU32, Ordering}; + static LOC_CACHE: AtomicU32 = AtomicU32::new(0); + let mut loc = LOC_CACHE.load(Ordering::Relaxed); + if loc == 0 { + let new_val = ijon_hashstr(line!(), file!()); + LOC_CACHE.store(new_val, Ordering::Relaxed); + loc = new_val; + } + ijon_max_variadic(loc, $($x),+, 0u64); + }}; +} + +#[macro_export] +macro_rules! ijon_min { + ($($x:expr),+ $(,)?) => {{ + use std::sync::atomic::{AtomicU32, Ordering}; + static LOC_CACHE: AtomicU32 = AtomicU32::new(0); + let mut loc = LOC_CACHE.load(Ordering::Relaxed); + if loc == 0 { + let new_val = ijon_hashstr(line!(), file!()); + LOC_CACHE.store(new_val, Ordering::Relaxed); + loc = new_val; + } + ijon_min_variadic(loc, $($x),+, 0u64); + }}; +} + +#[macro_export] +macro_rules! ijon_set { + ($x:expr) => {{ + use std::sync::atomic::{AtomicU32, Ordering}; + static LOC_CACHE: AtomicU32 = AtomicU32::new(0); + let mut loc = LOC_CACHE.load(Ordering::Relaxed); + if loc == 0 { + let new_val = ijon_hashstr(line!(), file!()); + LOC_CACHE.store(new_val, Ordering::Relaxed); + loc = new_val; + } + ijon_set(loc, $x); + }}; +} + +#[macro_export] +macro_rules! ijon_state { + ($n:expr) => { + ijon_xor_state($n) + }; +} + +#[macro_export] +macro_rules! ijon_ctx { + ($x:expr) => {{ + let hash = ijon_hashstr(line!(), file!()); + ijon_xor_state(hash); + let temp = $x; + ijon_xor_state(hash); + temp + }}; +} + +#[macro_export] +macro_rules! ijon_max_at { + ($addr:expr, $x:expr) => { + ijon_max($addr, $x) + }; +} + +#[macro_export] +macro_rules! ijon_min_at { + ($addr:expr, $x:expr) => { + ijon_min($addr, $x) + }; +} + +#[macro_export] +macro_rules! _ijon_abs_dist { + ($x:expr, $y:expr) => { + if $x < $y { $y - $x } else { $x - $y } + }; +} + +#[macro_export] +macro_rules! ijon_bits { + ($x:expr) => { + ijon_set(ijon_hashint( + ijon_hashstack(), + if $x == 0 { + 0 + } else { + $x.leading_zeros() as u32 + }, + )) + }; +} + +#[macro_export] +macro_rules! ijon_strdist { + ($x:expr, $y:expr) => { + ijon_set(ijon_hashint(ijon_hashstack(), ijon_strdist($x, $y))) + }; +} + +#[macro_export] +macro_rules! ijon_dist { + ($x:expr, $y:expr) => { + ijon_set(ijon_hashint( + ijon_hashstack(), + $crate::_ijon_abs_dist!($x, $y), + )) + }; +} + +#[macro_export] +macro_rules! ijon_cmp { + ($x:expr, $y:expr) => { + ijon_inc(ijon_hashint(ijon_hashstack(), ($x ^ $y).count_ones())) + }; +} + +#[macro_export] +macro_rules! ijon_stack_max { + ($x:expr) => {{ + use std::sync::atomic::{AtomicU32, Ordering}; + static LOC: AtomicU32 = AtomicU32::new(0); + let mut loc = LOC.load(Ordering::Relaxed); + if loc == 0 { + let new_val = ijon_hashstr(line!(), file!()); + LOC.store(new_val, Ordering::Relaxed); + loc = new_val; + } + ijon_max(ijon_hashint(loc, ijon_hashstack()), $x); + }}; +} + +#[macro_export] +macro_rules! ijon_stack_min { + ($x:expr) => {{ + use std::sync::atomic::{AtomicU32, Ordering}; + static LOC: AtomicU32 = AtomicU32::new(0); + let mut loc = LOC.load(Ordering::Relaxed); + if loc == 0 { + let new_val = ijon_hashstr(line!(), file!()); + LOC.store(new_val, Ordering::Relaxed); + loc = new_val; + } + ijon_min(ijon_hashint(loc, ijon_hashstack()), $x); + }}; +} + +// end if AFL++ IJON functions + #[allow(non_upper_case_globals)] #[doc(hidden)] #[unsafe(no_mangle)] From d2ab3bd1f1aed08b34ba0a904da3807608da27dc Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 24 Sep 2025 21:05:46 +0200 Subject: [PATCH 02/35] example --- afl/examples/maze.rs | 196 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 afl/examples/maze.rs diff --git a/afl/examples/maze.rs b/afl/examples/maze.rs new file mode 100644 index 000000000..27d723d37 --- /dev/null +++ b/afl/examples/maze.rs @@ -0,0 +1,196 @@ +/* +The maze: +[1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], +[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], +[1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1], +[1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1], +[1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1], +[1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1], +[1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,1], +[1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1], +[1,0,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,1,0,1], +[1,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,1], +[1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,1,0,1,0,1], +[1,0,1,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,1,0,1,0,1,0,1], +[1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,1,0,0,1,0,1,0,1,0,1,0,1,0,1], +[1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1], +[1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1], +[1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,2,0,0,1,0,0,0,1,0,1,0,1,0,1,0,1], +[1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1], +[1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1], +[1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1,0,0,1,0,1,0,1,0,1,0,1,0,1], +[1,0,1,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,1,0,1,0,1,0,1], +[1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,1,0,1,0,1], +[1,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,1], +[1,0,1,0,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,1,0,1], +[1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1], +[1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,1,0,1], +[1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1], +[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,1], +[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1], +[1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1], +[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], +[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], +*/ + +/* Solution: +cddbddcccacaaaccaaaaaabbbbbbbbbbaaccccccccccccaaccaabbbbbbbbbbbbbbbbbbbbbbbbbaacccccccccccccccccccccccccccccdddddddddddddddddddddddddddddbbbbbbbbbbbbbbbd +*/ + +use afl::ijon_set; +use afl::ijon_hashint; + +fn main() { + afl::fuzz!(|data: &[u8]| { + // 31x31 maze, 0 = open, 1 = wall, 2 = start, 3 = exit + + let maze = [ + [ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, + ], + [ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, + ], + [ + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, + ], + [ + 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, + ], + [ + 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 1, 0, 1, + ], + [ + 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 1, 0, 1, + ], + [ + 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, + 1, 0, 1, + ], + [ + 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, + 1, 0, 1, + ], + [ + 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, + 1, 0, 1, + ], + [ + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, + ], + [ + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, + ], + [ + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, + ], + [ + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, + ], + [ + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, + ], + [ + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, + ], + [ + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, + ], + [ + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, + ], + [ + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, + ], + [ + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, + ], + [ + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, + ], + [ + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, + ], + [ + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, + ], + [ + 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, + 1, 0, 1, + ], + [ + 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, + 1, 0, 1, + ], + [ + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, + 1, 0, 1, + ], + [ + 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 1, 0, 1, + ], + [ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, + 1, 0, 1, + ], + [ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 1, 0, 1, + ], + [ + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 1, 0, 1, + ], + [ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, + ], + [ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, + ], + ]; + + let mut pos: (usize, usize) = (15, 15); // start position + + for &b in data { + let next = match b % 4 { + 0 => (pos.0.wrapping_sub(1), pos.1), // up + 1 => (pos.0 + 1, pos.1), // down + 2 => (pos.0, pos.1.wrapping_sub(1)), // left + _ => (pos.0, pos.1 + 1), // right + }; + + if next.0 < 31 && next.1 < 31 && maze[next.0][next.1] != 1 { + pos = next; + } + + if maze[pos.0][pos.1] == 3 { + panic!("Exited the maze!"); + } + + ijon_set!(ijon_hashint(pos.0 as u32, pos.1 as u32)); + + } + }); +} From 94ab7cb308e1cd9db5f3389ef35e786a92181012 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 25 Sep 2025 10:08:39 +0200 Subject: [PATCH 03/35] fix ijon macros --- afl/examples/maze.rs | 5 +-- afl/src/lib.rs | 78 +++++++++++++++++++++++++------------------- 2 files changed, 48 insertions(+), 35 deletions(-) diff --git a/afl/examples/maze.rs b/afl/examples/maze.rs index 27d723d37..89bcd0867 100644 --- a/afl/examples/maze.rs +++ b/afl/examples/maze.rs @@ -37,8 +37,10 @@ The maze: cddbddcccacaaaccaaaaaabbbbbbbbbbaaccccccccccccaaccaabbbbbbbbbbbbbbbbbbbbbbbbbaacccccccccccccccccccccccccccccdddddddddddddddddddddddddddddbbbbbbbbbbbbbbbd */ -use afl::ijon_set; use afl::ijon_hashint; +use afl::ijon_hashstr; +use afl::ijon_set; +use std::ffi::CString; fn main() { afl::fuzz!(|data: &[u8]| { @@ -190,7 +192,6 @@ fn main() { } ijon_set!(ijon_hashint(pos.0 as u32, pos.1 as u32)); - } }); } diff --git a/afl/src/lib.rs b/afl/src/lib.rs index 3ebb3f005..15cc3681d 100644 --- a/afl/src/lib.rs +++ b/afl/src/lib.rs @@ -7,6 +7,7 @@ use std::env; use std::io::{self, Read}; +use std::os::raw::c_char; use std::panic; // those functions are provided by the afl-compiler-rt static library @@ -28,7 +29,7 @@ unsafe extern "C" { pub fn ijon_reset_state(); pub fn ijon_simple_hash(x: u64) -> u64; pub fn ijon_hashint(old: u32, val: u32) -> u32; - pub fn ijon_hashstr(old: u32, val: *const u8) -> u32; + pub fn ijon_hashstr(old: u32, val: *const c_char) -> u32; pub fn ijon_hashmen(old: u32, val: *const u8, len: usize) -> u32; pub fn ijon_hashstack_backtrace() -> u32; pub fn ijon_hashstack() -> u32; @@ -45,11 +46,12 @@ macro_rules! ijon_inc { static LOC_CACHE: AtomicU32 = AtomicU32::new(0); let mut loc = LOC_CACHE.load(Ordering::Relaxed); if loc == 0 { - let new_val = ijon_hashstr(line!(), file!()); + let cfile = CString::new(file!()).unwrap(); + let new_val = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; LOC_CACHE.store(new_val, Ordering::Relaxed); loc = new_val; } - ijon_inc(loc, $x); + unsafe { ijon_inc(loc, $x) }; }}; } @@ -60,11 +62,12 @@ macro_rules! ijon_max { static LOC_CACHE: AtomicU32 = AtomicU32::new(0); let mut loc = LOC_CACHE.load(Ordering::Relaxed); if loc == 0 { - let new_val = ijon_hashstr(line!(), file!()); + let cfile = CString::new(file!()).unwrap(); + let new_val = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; LOC_CACHE.store(new_val, Ordering::Relaxed); loc = new_val; } - ijon_max_variadic(loc, $($x),+, 0u64); + unsafe { ijon_max_variadic(loc, $($x),+, 0u64) }; }}; } @@ -75,11 +78,12 @@ macro_rules! ijon_min { static LOC_CACHE: AtomicU32 = AtomicU32::new(0); let mut loc = LOC_CACHE.load(Ordering::Relaxed); if loc == 0 { - let new_val = ijon_hashstr(line!(), file!()); + let cfile = CString::new(file!()).unwrap(); + let new_val = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; LOC_CACHE.store(new_val, Ordering::Relaxed); loc = new_val; } - ijon_min_variadic(loc, $($x),+, 0u64); + unsafe { ijon_min_variadic(loc, $($x),+, 0u64) }; }}; } @@ -90,28 +94,30 @@ macro_rules! ijon_set { static LOC_CACHE: AtomicU32 = AtomicU32::new(0); let mut loc = LOC_CACHE.load(Ordering::Relaxed); if loc == 0 { - let new_val = ijon_hashstr(line!(), file!()); + let cfile = CString::new(file!()).unwrap(); + let new_val = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; LOC_CACHE.store(new_val, Ordering::Relaxed); loc = new_val; } - ijon_set(loc, $x); + unsafe { ijon_set(loc, $x) }; }}; } #[macro_export] macro_rules! ijon_state { ($n:expr) => { - ijon_xor_state($n) + unsafe { ijon_xor_state($n) } }; } #[macro_export] macro_rules! ijon_ctx { ($x:expr) => {{ - let hash = ijon_hashstr(line!(), file!()); - ijon_xor_state(hash); + let cfile = CString::new(file!()).unwrap(); + let hash = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; + unsafe { ijon_xor_state(hash) }; let temp = $x; - ijon_xor_state(hash); + unsafe { ijon_xor_state(hash) }; temp }}; } @@ -119,14 +125,14 @@ macro_rules! ijon_ctx { #[macro_export] macro_rules! ijon_max_at { ($addr:expr, $x:expr) => { - ijon_max($addr, $x) + unsafe { ijon_max($addr, $x) } }; } #[macro_export] macro_rules! ijon_min_at { ($addr:expr, $x:expr) => { - ijon_min($addr, $x) + unsafe { ijon_min($addr, $x) } }; } @@ -140,38 +146,42 @@ macro_rules! _ijon_abs_dist { #[macro_export] macro_rules! ijon_bits { ($x:expr) => { - ijon_set(ijon_hashint( - ijon_hashstack(), - if $x == 0 { - 0 - } else { - $x.leading_zeros() as u32 - }, - )) + unsafe { + ijon_set(ijon_hashint( + ijon_hashstack(), + if $x == 0 { + 0 + } else { + $x.leading_zeros() as u32 + }, + )) + } }; } #[macro_export] macro_rules! ijon_strdist { ($x:expr, $y:expr) => { - ijon_set(ijon_hashint(ijon_hashstack(), ijon_strdist($x, $y))) + unsafe { ijon_set(ijon_hashint(ijon_hashstack(), ijon_strdist($x, $y))) } }; } #[macro_export] macro_rules! ijon_dist { ($x:expr, $y:expr) => { - ijon_set(ijon_hashint( - ijon_hashstack(), - $crate::_ijon_abs_dist!($x, $y), - )) + unsafe { + ijon_set(ijon_hashint( + ijon_hashstack(), + $crate::_ijon_abs_dist!($x, $y), + )) + } }; } #[macro_export] macro_rules! ijon_cmp { ($x:expr, $y:expr) => { - ijon_inc(ijon_hashint(ijon_hashstack(), ($x ^ $y).count_ones())) + unsafe { ijon_inc(ijon_hashint(ijon_hashstack(), ($x ^ $y).count_ones())) } }; } @@ -182,11 +192,12 @@ macro_rules! ijon_stack_max { static LOC: AtomicU32 = AtomicU32::new(0); let mut loc = LOC.load(Ordering::Relaxed); if loc == 0 { - let new_val = ijon_hashstr(line!(), file!()); + let cfile = CString::new(file!()).unwrap(); + let new_val = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; LOC.store(new_val, Ordering::Relaxed); loc = new_val; } - ijon_max(ijon_hashint(loc, ijon_hashstack()), $x); + unsafe { ijon_max(ijon_hashint(loc, ijon_hashstack()), $x) }; }}; } @@ -197,11 +208,12 @@ macro_rules! ijon_stack_min { static LOC: AtomicU32 = AtomicU32::new(0); let mut loc = LOC.load(Ordering::Relaxed); if loc == 0 { - let new_val = ijon_hashstr(line!(), file!()); + let cfile = CString::new(file!()).unwrap(); + let new_val = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; LOC.store(new_val, Ordering::Relaxed); loc = new_val; } - ijon_min(ijon_hashint(loc, ijon_hashstack()), $x); + unsafe { ijon_min(ijon_hashint(loc, ijon_hashstack()), $x) }; }}; } From 2ea0d2da6b99e19b2a6ee09d194e1d78114d3a82 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 25 Sep 2025 10:29:25 +0200 Subject: [PATCH 04/35] add ijon pass --- cargo-afl/src/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/cargo-afl/src/main.rs b/cargo-afl/src/main.rs index ab9a04e15..3ddf36c6f 100644 --- a/cargo-afl/src/main.rs +++ b/cargo-afl/src/main.rs @@ -314,6 +314,7 @@ where -Z llvm-plugins={p}/SanitizerCoveragePCGUARD.so \ -Z llvm-plugins={p}/cmplog-instructions-pass.so \ -Z llvm-plugins={p}/cmplog-routines-pass.so \ + -Z llvm-plugins={p}/afl-llvm-ijon-pass.so " )); From 021ed32ff1c4721038f23e3105c8d9311d7dd641 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 25 Sep 2025 17:44:47 +0200 Subject: [PATCH 05/35] add test --- cargo-afl/tests/integration.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/cargo-afl/tests/integration.rs b/cargo-afl/tests/integration.rs index 28b09dce1..ccda19955 100644 --- a/cargo-afl/tests/integration.rs +++ b/cargo-afl/tests/integration.rs @@ -54,6 +54,22 @@ fn integration_cfg() { } } +#[test] +fn integration_maze() { + assert_cmd::Command::new(cargo_afl_path()) + .arg("afl") + .arg("build") + .arg("-r") + .arg("--example") + .arg("maze") + .arg("--manifest-path") + .arg("../afl/Cargo.toml") + .assert() + .success(); + + fuzz_example("maze", true); +} + fn fuzz_example(name: &str, should_crash: bool) { let temp_dir = tempfile::TempDir::new().expect("Could not create temporary directory"); let temp_dir_path = temp_dir.path(); @@ -64,7 +80,7 @@ fn fuzz_example(name: &str, should_crash: bool) { .arg(input_path()) .arg("-o") .arg(temp_dir_path) - .args(["-V", "5"]) // 5 seconds + .args(["-V", "10"]) // 5 seconds .arg(examples_path(name)) .env("AFL_BENCH_UNTIL_CRASH", "1") .env("AFL_NO_CRASH_README", "1") From 729399d91283fbc5ed123816e03a957b5a70f190 Mon Sep 17 00:00:00 2001 From: Samuel Moelius Date: Mon, 29 Sep 2025 05:08:36 -0400 Subject: [PATCH 06/35] Verify that plugins are available in `integration_maze` test --- cargo-afl/tests/integration.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cargo-afl/tests/integration.rs b/cargo-afl/tests/integration.rs index ccda19955..b402aed97 100644 --- a/cargo-afl/tests/integration.rs +++ b/cargo-afl/tests/integration.rs @@ -1,8 +1,13 @@ use std::{ + io::Write, path, process::{self, ExitStatus}, }; +#[allow(dead_code)] +#[path = "../src/common.rs"] +mod common; + fn target_dir_path() -> &'static path::Path { if path::Path::new("../target/debug/cargo-afl").exists() { path::Path::new("../target/debug/") @@ -56,6 +61,15 @@ fn integration_cfg() { #[test] fn integration_maze() { + if !common::plugins_available().unwrap_or_default() { + writeln!( + std::io::stderr(), + "Skipping `integration_maze` test as plugins are unavailable" + ) + .unwrap(); + return; + } + assert_cmd::Command::new(cargo_afl_path()) .arg("afl") .arg("build") From 7e60ee1ea809ebe25eb69141ffed7cba2a81bd2b Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 29 Sep 2025 15:39:37 +0200 Subject: [PATCH 07/35] znostart-stop-gc --- cargo-afl/src/main.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cargo-afl/src/main.rs b/cargo-afl/src/main.rs index 3ddf36c6f..321ffc259 100644 --- a/cargo-afl/src/main.rs +++ b/cargo-afl/src/main.rs @@ -286,7 +286,8 @@ where -C overflow_checks \ -C codegen-units=1 \ -C opt-level={opt_level} \ - -C target-cpu=native ", + -C target-cpu=native \ + -C link-arg=-Wl,-znostart-stop-gc ", ); let mut environment_variables = HashMap::<&str, String>::new(); environment_variables.insert("ASAN_OPTIONS", asan_options); From d1f00bb4a06b97c7fa4f374d9161f4b146da2054 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 29 Sep 2025 16:29:07 +0200 Subject: [PATCH 08/35] update afl++ --- cargo-afl/src/main.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cargo-afl/src/main.rs b/cargo-afl/src/main.rs index 321ffc259..3ddf36c6f 100644 --- a/cargo-afl/src/main.rs +++ b/cargo-afl/src/main.rs @@ -286,8 +286,7 @@ where -C overflow_checks \ -C codegen-units=1 \ -C opt-level={opt_level} \ - -C target-cpu=native \ - -C link-arg=-Wl,-znostart-stop-gc ", + -C target-cpu=native ", ); let mut environment_variables = HashMap::<&str, String>::new(); environment_variables.insert("ASAN_OPTIONS", asan_options); From bc683c679da2a0b02d187abb67e1c7adccba2487 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 29 Sep 2025 16:40:49 +0200 Subject: [PATCH 09/35] clippy --- afl/examples/maze.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/afl/examples/maze.rs b/afl/examples/maze.rs index 89bcd0867..59c14afc5 100644 --- a/afl/examples/maze.rs +++ b/afl/examples/maze.rs @@ -37,6 +37,8 @@ The maze: cddbddcccacaaaccaaaaaabbbbbbbbbbaaccccccccccccaaccaabbbbbbbbbbbbbbbbbbbbbbbbbaacccccccccccccccccccccccccccccdddddddddddddddddddddddddddddbbbbbbbbbbbbbbbd */ +#![allow(clippy::too_many_lines, clippy::manual_assert, clippy::cast_possible_truncation)] + use afl::ijon_hashint; use afl::ijon_hashstr; use afl::ijon_set; From 86d8d2a251d764fea7859581f57b5a2f367b97d3 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 29 Sep 2025 16:43:33 +0200 Subject: [PATCH 10/35] fmt --- afl/examples/maze.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/afl/examples/maze.rs b/afl/examples/maze.rs index 59c14afc5..d2a6a0b46 100644 --- a/afl/examples/maze.rs +++ b/afl/examples/maze.rs @@ -37,7 +37,11 @@ The maze: cddbddcccacaaaccaaaaaabbbbbbbbbbaaccccccccccccaaccaabbbbbbbbbbbbbbbbbbbbbbbbbaacccccccccccccccccccccccccccccdddddddddddddddddddddddddddddbbbbbbbbbbbbbbbd */ -#![allow(clippy::too_many_lines, clippy::manual_assert, clippy::cast_possible_truncation)] +#![allow( + clippy::too_many_lines, + clippy::manual_assert, + clippy::cast_possible_truncation +)] use afl::ijon_hashint; use afl::ijon_hashstr; From 6e50d3a59f8168cdb0928ceced3521d6d71ad850 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 30 Sep 2025 09:51:12 +0200 Subject: [PATCH 11/35] clippy, cfg fuzzing, docs --- README.md | 19 +++++++++++++++++++ afl/examples/maze.rs | 1 + cargo-afl/tests/integration.rs | 1 + 3 files changed, 21 insertions(+) diff --git a/README.md b/README.md index af618b3c8..47b8ab141 100644 --- a/README.md +++ b/README.md @@ -51,3 +51,22 @@ environment variable `AFL_NO_CFG_FUZZING` to `1` when building. [american-fuzzy-lop]: http://lcamtuf.coredump.cx/afl/ [AFLplusplus]: https://aflplus.plus/ [rust]: https://www.rust-lang.org + +## IJON + +If you want to use IJON - helping fuzzer coverage through code annotation - then +have a look at the [maze example](afl/examples/maze.rs) how to use it. + +You can find the AFL++ IJON documentation at [https://github.com/AFLplusplus/AFLplusplus/blob/stable/docs/IJON.md](https://github.com/AFLplusplus/AFLplusplus/blob/stable/docs/IJON.md) + +Note that the IJON macros have been rustyfied to lowercase - hence `IJON_MAX(x)` is `ijon_max(x)` in Rust. + +You will need to the following parts of cargo AFL: + +``` +use afl::ijon_hashint; +use afl::ijon_hashstr; +use std::ffi::CString; +``` + +plus any macros that you use, e.g. `afl::ijon_max`. diff --git a/afl/examples/maze.rs b/afl/examples/maze.rs index d2a6a0b46..183b46733 100644 --- a/afl/examples/maze.rs +++ b/afl/examples/maze.rs @@ -197,6 +197,7 @@ fn main() { panic!("Exited the maze!"); } + #[cfg(fuzzing)] ijon_set!(ijon_hashint(pos.0 as u32, pos.1 as u32)); } }); diff --git a/cargo-afl/tests/integration.rs b/cargo-afl/tests/integration.rs index b402aed97..c44cf3add 100644 --- a/cargo-afl/tests/integration.rs +++ b/cargo-afl/tests/integration.rs @@ -62,6 +62,7 @@ fn integration_cfg() { #[test] fn integration_maze() { if !common::plugins_available().unwrap_or_default() { + #[allow(clippy::explicit_write)] writeln!( std::io::stderr(), "Skipping `integration_maze` test as plugins are unavailable" From fb9386d2c8d0f3fe65edb289c26f398e7556418d Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 30 Sep 2025 10:03:40 +0200 Subject: [PATCH 12/35] clippy --- afl/examples/maze.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/afl/examples/maze.rs b/afl/examples/maze.rs index 183b46733..0a96b3345 100644 --- a/afl/examples/maze.rs +++ b/afl/examples/maze.rs @@ -43,9 +43,13 @@ cddbddcccacaaaccaaaaaabbbbbbbbbbaaccccccccccccaaccaabbbbbbbbbbbbbbbbbbbbbbbbbaac clippy::cast_possible_truncation )] +#[cfg(fuzzing)] use afl::ijon_hashint; +#[cfg(fuzzing)] use afl::ijon_hashstr; +#[cfg(fuzzing)] use afl::ijon_set; +#[cfg(fuzzing)] use std::ffi::CString; fn main() { From c1da0bbb415698abb2c0c7724829e72b22e93e62 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Oct 2025 15:17:50 +0200 Subject: [PATCH 13/35] Update README.md Co-authored-by: Samuel Moelius <35515885+smoelius@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 47b8ab141..b99f79bb0 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ You can find the AFL++ IJON documentation at [https://github.com/AFLplusplus/AFL Note that the IJON macros have been rustyfied to lowercase - hence `IJON_MAX(x)` is `ijon_max(x)` in Rust. -You will need to the following parts of cargo AFL: +You will need to the following imports from `afl`, in addition to any macros that you use (e.g., `afl::ijon_max`): ``` use afl::ijon_hashint; From b55aa77f497c6f532dedb2173feeb79187ddaae2 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Oct 2025 15:18:15 +0200 Subject: [PATCH 14/35] Update README.md Co-authored-by: Samuel Moelius <35515885+smoelius@users.noreply.github.com> --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index b99f79bb0..39c1ad802 100644 --- a/README.md +++ b/README.md @@ -68,5 +68,3 @@ use afl::ijon_hashint; use afl::ijon_hashstr; use std::ffi::CString; ``` - -plus any macros that you use, e.g. `afl::ijon_max`. From 90ebb0536fffbcb48af7b855ac448219a0e181a1 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Oct 2025 15:18:35 +0200 Subject: [PATCH 15/35] Update README.md Co-authored-by: Samuel Moelius <35515885+smoelius@users.noreply.github.com> --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 39c1ad802..f7734df5a 100644 --- a/README.md +++ b/README.md @@ -66,5 +66,4 @@ You will need to the following imports from `afl`, in addition to any macros tha ``` use afl::ijon_hashint; use afl::ijon_hashstr; -use std::ffi::CString; ``` From 887cd59489b5db77909baaec3a83ade50806ef09 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Oct 2025 15:19:35 +0200 Subject: [PATCH 16/35] Update README.md Co-authored-by: Samuel Moelius <35515885+smoelius@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f7734df5a..b4b787fd5 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ environment variable `AFL_NO_CFG_FUZZING` to `1` when building. ## IJON If you want to use IJON - helping fuzzer coverage through code annotation - then -have a look at the [maze example](afl/examples/maze.rs) how to use it. +have a look at the [maze example](afl/examples/maze.rs). You can find the AFL++ IJON documentation at [https://github.com/AFLplusplus/AFLplusplus/blob/stable/docs/IJON.md](https://github.com/AFLplusplus/AFLplusplus/blob/stable/docs/IJON.md) From 08ce698f19b26376a92979efbd6904d3714cb693 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Oct 2025 15:19:58 +0200 Subject: [PATCH 17/35] Update afl/examples/maze.rs Co-authored-by: Samuel Moelius <35515885+smoelius@users.noreply.github.com> --- afl/examples/maze.rs | 156 +++++++++---------------------------------- 1 file changed, 32 insertions(+), 124 deletions(-) diff --git a/afl/examples/maze.rs b/afl/examples/maze.rs index 0a96b3345..f03ae078b 100644 --- a/afl/examples/maze.rs +++ b/afl/examples/maze.rs @@ -56,131 +56,39 @@ fn main() { afl::fuzz!(|data: &[u8]| { // 31x31 maze, 0 = open, 1 = wall, 2 = start, 3 = exit + #[rustfmt::skip] let maze = [ - [ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, - ], - [ - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, - ], - [ - 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 0, 1, - ], - [ - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 1, - ], - [ - 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 0, 1, - ], - [ - 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, - 1, 0, 1, - ], - [ - 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, - 1, 0, 1, - ], - [ - 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, - 1, 0, 1, - ], - [ - 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, - 1, 0, 1, - ], - [ - 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, - ], - [ - 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, - ], - [ - 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, - ], - [ - 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, - ], - [ - 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, - ], - [ - 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, - ], - [ - 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, - ], - [ - 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, - ], - [ - 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, - ], - [ - 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, - ], - [ - 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, - ], - [ - 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, - ], - [ - 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, - ], - [ - 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, - 1, 0, 1, - ], - [ - 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, - 1, 0, 1, - ], - [ - 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, - 1, 0, 1, - ], - [ - 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, - 1, 0, 1, - ], - [ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, - 1, 0, 1, - ], - [ - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, - 1, 0, 1, - ], - [ - 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 0, 1, - ], - [ - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, - ], - [ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, - ], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], + [1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1], + [1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1], + [1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1], + [1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1], + [1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,1], + [1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1], + [1,0,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,1,0,1], + [1,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,1], + [1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,1,0,1,0,1], + [1,0,1,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,1,0,1,0,1,0,1], + [1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,1,0,0,1,0,1,0,1,0,1,0,1,0,1], + [1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1], + [1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1], + [1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,2,0,0,1,0,0,0,1,0,1,0,1,0,1,0,1], + [1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1], + [1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1], + [1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1,0,0,1,0,1,0,1,0,1,0,1,0,1], + [1,0,1,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,1,0,1,0,1,0,1], + [1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,1,0,1,0,1], + [1,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,1], + [1,0,1,0,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,1,0,1], + [1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1], + [1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,1,0,1], + [1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,1], + [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1], + [1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1], + [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], ]; let mut pos: (usize, usize) = (15, 15); // start position From bd0db01251bac3338d6b5cc236930932bdd6f573 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Oct 2025 15:20:22 +0200 Subject: [PATCH 18/35] Update afl/examples/maze.rs Co-authored-by: Samuel Moelius <35515885+smoelius@users.noreply.github.com> --- afl/examples/maze.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/afl/examples/maze.rs b/afl/examples/maze.rs index f03ae078b..bc1c65e5f 100644 --- a/afl/examples/maze.rs +++ b/afl/examples/maze.rs @@ -37,11 +37,7 @@ The maze: cddbddcccacaaaccaaaaaabbbbbbbbbbaaccccccccccccaaccaabbbbbbbbbbbbbbbbbbbbbbbbbaacccccccccccccccccccccccccccccdddddddddddddddddddddddddddddbbbbbbbbbbbbbbbd */ -#![allow( - clippy::too_many_lines, - clippy::manual_assert, - clippy::cast_possible_truncation -)] +#![allow(clippy::cast_possible_truncation)] #[cfg(fuzzing)] use afl::ijon_hashint; From 0e10bf62bee6adc2a06e0a81e9d0bdb084e64c2f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Oct 2025 15:20:44 +0200 Subject: [PATCH 19/35] Update afl/examples/maze.rs Co-authored-by: Samuel Moelius <35515885+smoelius@users.noreply.github.com> --- afl/examples/maze.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/afl/examples/maze.rs b/afl/examples/maze.rs index bc1c65e5f..bb1de6a9b 100644 --- a/afl/examples/maze.rs +++ b/afl/examples/maze.rs @@ -40,13 +40,7 @@ cddbddcccacaaaccaaaaaabbbbbbbbbbaaccccccccccccaaccaabbbbbbbbbbbbbbbbbbbbbbbbbaac #![allow(clippy::cast_possible_truncation)] #[cfg(fuzzing)] -use afl::ijon_hashint; -#[cfg(fuzzing)] -use afl::ijon_hashstr; -#[cfg(fuzzing)] -use afl::ijon_set; -#[cfg(fuzzing)] -use std::ffi::CString; +use afl::{ijon_hashint, ijon_set}; fn main() { afl::fuzz!(|data: &[u8]| { From c83393da246032b8aa750b9919f572c7613c093c Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Oct 2025 15:21:13 +0200 Subject: [PATCH 20/35] Update afl/examples/maze.rs Co-authored-by: Samuel Moelius <35515885+smoelius@users.noreply.github.com> --- afl/examples/maze.rs | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/afl/examples/maze.rs b/afl/examples/maze.rs index bb1de6a9b..48095f298 100644 --- a/afl/examples/maze.rs +++ b/afl/examples/maze.rs @@ -1,38 +1,3 @@ -/* -The maze: -[1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], -[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], -[1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1], -[1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1], -[1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1], -[1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1], -[1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,1], -[1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1], -[1,0,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,1,0,1], -[1,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,1], -[1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,1,0,1,0,1], -[1,0,1,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,1,0,1,0,1,0,1], -[1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,1,0,0,1,0,1,0,1,0,1,0,1,0,1], -[1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1], -[1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1], -[1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,2,0,0,1,0,0,0,1,0,1,0,1,0,1,0,1], -[1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1], -[1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1], -[1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1,0,0,1,0,1,0,1,0,1,0,1,0,1], -[1,0,1,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,1,0,1,0,1,0,1], -[1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,1,0,1,0,1], -[1,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,1], -[1,0,1,0,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,1,0,1], -[1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1], -[1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,1,0,1], -[1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1], -[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,1], -[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1], -[1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1], -[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], -[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], -*/ - /* Solution: cddbddcccacaaaccaaaaaabbbbbbbbbbaaccccccccccccaaccaabbbbbbbbbbbbbbbbbbbbbbbbbaacccccccccccccccccccccccccccccdddddddddddddddddddddddddddddbbbbbbbbbbbbbbbd */ From ad9e9472622cac75f8db950ef687a98e82ecd5b6 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Oct 2025 15:21:41 +0200 Subject: [PATCH 21/35] Update afl/src/lib.rs Co-authored-by: Samuel Moelius <35515885+smoelius@users.noreply.github.com> --- afl/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/afl/src/lib.rs b/afl/src/lib.rs index 15cc3681d..f4f92407e 100644 --- a/afl/src/lib.rs +++ b/afl/src/lib.rs @@ -46,7 +46,7 @@ macro_rules! ijon_inc { static LOC_CACHE: AtomicU32 = AtomicU32::new(0); let mut loc = LOC_CACHE.load(Ordering::Relaxed); if loc == 0 { - let cfile = CString::new(file!()).unwrap(); + let cfile = std::ffi::CString::new(file!()).unwrap(); let new_val = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; LOC_CACHE.store(new_val, Ordering::Relaxed); loc = new_val; From 6c7de49e56b349ab1651200936330659ff6ab585 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Oct 2025 15:22:01 +0200 Subject: [PATCH 22/35] Update afl/src/lib.rs Co-authored-by: Samuel Moelius <35515885+smoelius@users.noreply.github.com> --- afl/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/afl/src/lib.rs b/afl/src/lib.rs index f4f92407e..d3060ad52 100644 --- a/afl/src/lib.rs +++ b/afl/src/lib.rs @@ -47,7 +47,7 @@ macro_rules! ijon_inc { let mut loc = LOC_CACHE.load(Ordering::Relaxed); if loc == 0 { let cfile = std::ffi::CString::new(file!()).unwrap(); - let new_val = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; + let new_val = unsafe { afl::ijon_hashstr(line!(), cfile.as_ptr()) }; LOC_CACHE.store(new_val, Ordering::Relaxed); loc = new_val; } From 8777f4e4cfee448ed26b318b9f15628ca18de872 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Oct 2025 15:22:32 +0200 Subject: [PATCH 23/35] Update cargo-afl/tests/integration.rs Co-authored-by: Samuel Moelius <35515885+smoelius@users.noreply.github.com> --- cargo-afl/tests/integration.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/cargo-afl/tests/integration.rs b/cargo-afl/tests/integration.rs index c44cf3add..427452f36 100644 --- a/cargo-afl/tests/integration.rs +++ b/cargo-afl/tests/integration.rs @@ -71,16 +71,6 @@ fn integration_maze() { return; } - assert_cmd::Command::new(cargo_afl_path()) - .arg("afl") - .arg("build") - .arg("-r") - .arg("--example") - .arg("maze") - .arg("--manifest-path") - .arg("../afl/Cargo.toml") - .assert() - .success(); fuzz_example("maze", true); } From a770ae6deca806008e4b851f3d183461ddbed97c Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Oct 2025 15:22:49 +0200 Subject: [PATCH 24/35] Update README.md Co-authored-by: Samuel Moelius <35515885+smoelius@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b4b787fd5..f1a50868d 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ environment variable `AFL_NO_CFG_FUZZING` to `1` when building. ## IJON -If you want to use IJON - helping fuzzer coverage through code annotation - then +If you want to use [IJON](https://github.com/AFLplusplus/AFLplusplus/blob/stable/docs/IJON.md) - helping fuzzer coverage through code annotation - then have a look at the [maze example](afl/examples/maze.rs). You can find the AFL++ IJON documentation at [https://github.com/AFLplusplus/AFLplusplus/blob/stable/docs/IJON.md](https://github.com/AFLplusplus/AFLplusplus/blob/stable/docs/IJON.md) From a214ea6f29a9016fd114939c9bfa3e03dc33a6fe Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 8 Oct 2025 15:36:51 +0200 Subject: [PATCH 25/35] nits --- afl/examples/maze.rs | 5 ++- afl/src/lib.rs | 62 +++++++++++----------------------- cargo-afl/tests/integration.rs | 1 - 3 files changed, 23 insertions(+), 45 deletions(-) diff --git a/afl/examples/maze.rs b/afl/examples/maze.rs index 48095f298..ea6e34967 100644 --- a/afl/examples/maze.rs +++ b/afl/examples/maze.rs @@ -1,4 +1,7 @@ -/* Solution: +/* +This example tests the AFL++ IJON feature. + +Solution to the maze: cddbddcccacaaaccaaaaaabbbbbbbbbbaaccccccccccccaaccaabbbbbbbbbbbbbbbbbbbbbbbbbaacccccccccccccccccccccccccccccdddddddddddddddddddddddddddddbbbbbbbbbbbbbbbd */ diff --git a/afl/src/lib.rs b/afl/src/lib.rs index d3060ad52..753378d52 100644 --- a/afl/src/lib.rs +++ b/afl/src/lib.rs @@ -42,14 +42,10 @@ unsafe extern "C" { #[macro_export] macro_rules! ijon_inc { ($x:expr) => {{ - use std::sync::atomic::{AtomicU32, Ordering}; - static LOC_CACHE: AtomicU32 = AtomicU32::new(0); - let mut loc = LOC_CACHE.load(Ordering::Relaxed); + static mut loc: u32 = 0; if loc == 0 { let cfile = std::ffi::CString::new(file!()).unwrap(); - let new_val = unsafe { afl::ijon_hashstr(line!(), cfile.as_ptr()) }; - LOC_CACHE.store(new_val, Ordering::Relaxed); - loc = new_val; + loc = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; } unsafe { ijon_inc(loc, $x) }; }}; @@ -58,30 +54,22 @@ macro_rules! ijon_inc { #[macro_export] macro_rules! ijon_max { ($($x:expr),+ $(,)?) => {{ - use std::sync::atomic::{AtomicU32, Ordering}; - static LOC_CACHE: AtomicU32 = AtomicU32::new(0); - let mut loc = LOC_CACHE.load(Ordering::Relaxed); + static mut loc: u32 = 0; if loc == 0 { - let cfile = CString::new(file!()).unwrap(); - let new_val = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; - LOC_CACHE.store(new_val, Ordering::Relaxed); - loc = new_val; + let cfile = std::ffi::CString::new(file!()).unwrap(); + loc = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; } - unsafe { ijon_max_variadic(loc, $($x),+, 0u64) }; + unsafe { ijon_max_variadic(_IJON_LOC_CACHE, $($x),+, 0u64) }; }}; } #[macro_export] macro_rules! ijon_min { ($($x:expr),+ $(,)?) => {{ - use std::sync::atomic::{AtomicU32, Ordering}; - static LOC_CACHE: AtomicU32 = AtomicU32::new(0); - let mut loc = LOC_CACHE.load(Ordering::Relaxed); + static mut loc: u32 = 0; if loc == 0 { - let cfile = CString::new(file!()).unwrap(); - let new_val = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; - LOC_CACHE.store(new_val, Ordering::Relaxed); - loc = new_val; + let cfile = std::ffi::CString::new(file!()).unwrap(); + loc = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; } unsafe { ijon_min_variadic(loc, $($x),+, 0u64) }; }}; @@ -90,14 +78,10 @@ macro_rules! ijon_min { #[macro_export] macro_rules! ijon_set { ($x:expr) => {{ - use std::sync::atomic::{AtomicU32, Ordering}; - static LOC_CACHE: AtomicU32 = AtomicU32::new(0); - let mut loc = LOC_CACHE.load(Ordering::Relaxed); + static mut loc: u32 = 0; if loc == 0 { - let cfile = CString::new(file!()).unwrap(); - let new_val = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; - LOC_CACHE.store(new_val, Ordering::Relaxed); - loc = new_val; + let cfile = std::ffi::CString::new(file!()).unwrap(); + loc = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; } unsafe { ijon_set(loc, $x) }; }}; @@ -113,7 +97,7 @@ macro_rules! ijon_state { #[macro_export] macro_rules! ijon_ctx { ($x:expr) => {{ - let cfile = CString::new(file!()).unwrap(); + let cfile = std::ffi::CString::new(file!()).unwrap(); let hash = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; unsafe { ijon_xor_state(hash) }; let temp = $x; @@ -188,14 +172,10 @@ macro_rules! ijon_cmp { #[macro_export] macro_rules! ijon_stack_max { ($x:expr) => {{ - use std::sync::atomic::{AtomicU32, Ordering}; - static LOC: AtomicU32 = AtomicU32::new(0); - let mut loc = LOC.load(Ordering::Relaxed); + static mut loc: u32 = 0; if loc == 0 { - let cfile = CString::new(file!()).unwrap(); - let new_val = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; - LOC.store(new_val, Ordering::Relaxed); - loc = new_val; + let cfile = std::ffi::CString::new(file!()).unwrap(); + loc = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; } unsafe { ijon_max(ijon_hashint(loc, ijon_hashstack()), $x) }; }}; @@ -204,14 +184,10 @@ macro_rules! ijon_stack_max { #[macro_export] macro_rules! ijon_stack_min { ($x:expr) => {{ - use std::sync::atomic::{AtomicU32, Ordering}; - static LOC: AtomicU32 = AtomicU32::new(0); - let mut loc = LOC.load(Ordering::Relaxed); + static mut loc: u32 = 0; if loc == 0 { - let cfile = CString::new(file!()).unwrap(); - let new_val = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; - LOC.store(new_val, Ordering::Relaxed); - loc = new_val; + let cfile = std::ffi::CString::new(file!()).unwrap(); + loc = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; } unsafe { ijon_min(ijon_hashint(loc, ijon_hashstack()), $x) }; }}; diff --git a/cargo-afl/tests/integration.rs b/cargo-afl/tests/integration.rs index 427452f36..5957af037 100644 --- a/cargo-afl/tests/integration.rs +++ b/cargo-afl/tests/integration.rs @@ -71,7 +71,6 @@ fn integration_maze() { return; } - fuzz_example("maze", true); } From 0950ec91c7174a24e6b8890db425c37118964593 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 8 Oct 2025 15:37:18 +0200 Subject: [PATCH 26/35] nits --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index f1a50868d..5eb55728f 100644 --- a/README.md +++ b/README.md @@ -57,8 +57,6 @@ environment variable `AFL_NO_CFG_FUZZING` to `1` when building. If you want to use [IJON](https://github.com/AFLplusplus/AFLplusplus/blob/stable/docs/IJON.md) - helping fuzzer coverage through code annotation - then have a look at the [maze example](afl/examples/maze.rs). -You can find the AFL++ IJON documentation at [https://github.com/AFLplusplus/AFLplusplus/blob/stable/docs/IJON.md](https://github.com/AFLplusplus/AFLplusplus/blob/stable/docs/IJON.md) - Note that the IJON macros have been rustyfied to lowercase - hence `IJON_MAX(x)` is `ijon_max(x)` in Rust. You will need to the following imports from `afl`, in addition to any macros that you use (e.g., `afl::ijon_max`): From 65db9f28a6dc87913f85bda1bdb31b12390cd6f2 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 8 Oct 2025 15:42:48 +0200 Subject: [PATCH 27/35] clippy --- afl/examples/maze.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/afl/examples/maze.rs b/afl/examples/maze.rs index ea6e34967..64f22ae33 100644 --- a/afl/examples/maze.rs +++ b/afl/examples/maze.rs @@ -5,7 +5,7 @@ Solution to the maze: cddbddcccacaaaccaaaaaabbbbbbbbbbaaccccccccccccaaccaabbbbbbbbbbbbbbbbbbbbbbbbbaacccccccccccccccccccccccccccccdddddddddddddddddddddddddddddbbbbbbbbbbbbbbbd */ -#![allow(clippy::cast_possible_truncation)] +#![allow(clippy::manual_assert, clippy::cast_possible_truncation)] #[cfg(fuzzing)] use afl::{ijon_hashint, ijon_set}; From 5587586976b23f5a6b0eeb376250604a362b555a Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 8 Oct 2025 16:07:31 +0200 Subject: [PATCH 28/35] fix --- afl/examples/maze.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/afl/examples/maze.rs b/afl/examples/maze.rs index 64f22ae33..363211316 100644 --- a/afl/examples/maze.rs +++ b/afl/examples/maze.rs @@ -8,7 +8,7 @@ cddbddcccacaaaccaaaaaabbbbbbbbbbaaccccccccccccaaccaabbbbbbbbbbbbbbbbbbbbbbbbbaac #![allow(clippy::manual_assert, clippy::cast_possible_truncation)] #[cfg(fuzzing)] -use afl::{ijon_hashint, ijon_set}; +use afl::{ijon_hashint, ijon_hashstr, ijon_set}; fn main() { afl::fuzz!(|data: &[u8]| { From 23ab3dd757854b774f3ad795c7a786109446087b Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 8 Oct 2025 16:14:23 +0200 Subject: [PATCH 29/35] fix --- afl/src/lib.rs | 68 +++++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/afl/src/lib.rs b/afl/src/lib.rs index 753378d52..c0493035b 100644 --- a/afl/src/lib.rs +++ b/afl/src/lib.rs @@ -42,48 +42,56 @@ unsafe extern "C" { #[macro_export] macro_rules! ijon_inc { ($x:expr) => {{ - static mut loc: u32 = 0; - if loc == 0 { - let cfile = std::ffi::CString::new(file!()).unwrap(); - loc = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; - } - unsafe { ijon_inc(loc, $x) }; + unsafe { + static mut loc: u32 = 0; + if loc == 0 { + let cfile = std::ffi::CString::new(file!()).unwrap(); + loc = ijon_hashstr(line!(), cfile.as_ptr()); + } + ijon_inc(loc, $x) + }; }}; } #[macro_export] macro_rules! ijon_max { ($($x:expr),+ $(,)?) => {{ + unsafe { static mut loc: u32 = 0; if loc == 0 { let cfile = std::ffi::CString::new(file!()).unwrap(); - loc = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; + loc = ijon_hashstr(line!(), cfile.as_ptr()); } - unsafe { ijon_max_variadic(_IJON_LOC_CACHE, $($x),+, 0u64) }; + ijon_max_variadic(_IJON_LOC_CACHE, $($x),+, 0u64) + }; }}; } #[macro_export] macro_rules! ijon_min { ($($x:expr),+ $(,)?) => {{ + unsafe { static mut loc: u32 = 0; if loc == 0 { let cfile = std::ffi::CString::new(file!()).unwrap(); - loc = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; + loc = ijon_hashstr(line!(), cfile.as_ptr()); } - unsafe { ijon_min_variadic(loc, $($x),+, 0u64) }; + ijon_min_variadic(loc, $($x),+, 0u64) + }; }}; } #[macro_export] macro_rules! ijon_set { ($x:expr) => {{ - static mut loc: u32 = 0; - if loc == 0 { - let cfile = std::ffi::CString::new(file!()).unwrap(); - loc = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; - } - unsafe { ijon_set(loc, $x) }; + unsafe { + static mut loc: u32 = 0; + if loc == 0 { + let cfile = std::ffi::CString::new(file!()).unwrap(); + loc = ijon_hashstr(line!(), cfile.as_ptr()); + } + ijon_set(loc, $x) + }; }}; } @@ -172,24 +180,28 @@ macro_rules! ijon_cmp { #[macro_export] macro_rules! ijon_stack_max { ($x:expr) => {{ - static mut loc: u32 = 0; - if loc == 0 { - let cfile = std::ffi::CString::new(file!()).unwrap(); - loc = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; - } - unsafe { ijon_max(ijon_hashint(loc, ijon_hashstack()), $x) }; + unsafe { + static mut loc: u32 = 0; + if loc == 0 { + let cfile = std::ffi::CString::new(file!()).unwrap(); + loc = ijon_hashstr(line!(), cfile.as_ptr()); + } + ijon_max(ijon_hashint(loc, ijon_hashstack()), $x) + }; }}; } #[macro_export] macro_rules! ijon_stack_min { ($x:expr) => {{ - static mut loc: u32 = 0; - if loc == 0 { - let cfile = std::ffi::CString::new(file!()).unwrap(); - loc = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; - } - unsafe { ijon_min(ijon_hashint(loc, ijon_hashstack()), $x) }; + unsafe { + static mut loc: u32 = 0; + if loc == 0 { + let cfile = std::ffi::CString::new(file!()).unwrap(); + loc = ijon_hashstr(line!(), cfile.as_ptr()); + } + ijon_min(ijon_hashint(loc, ijon_hashstack()), $x) + }; }}; } From 64b7a8e68b5ff58633466c07df304b0800bfae75 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 8 Oct 2025 20:34:54 +0200 Subject: [PATCH 30/35] use afl:: --- afl/src/lib.rs | 48 +++++++++++++++++----------------- cargo-afl/tests/integration.rs | 2 +- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/afl/src/lib.rs b/afl/src/lib.rs index c0493035b..a19386b61 100644 --- a/afl/src/lib.rs +++ b/afl/src/lib.rs @@ -46,9 +46,9 @@ macro_rules! ijon_inc { static mut loc: u32 = 0; if loc == 0 { let cfile = std::ffi::CString::new(file!()).unwrap(); - loc = ijon_hashstr(line!(), cfile.as_ptr()); + loc = afl::ijon_hashstr(line!(), cfile.as_ptr()); } - ijon_inc(loc, $x) + afl::ijon_inc(loc, $x) }; }}; } @@ -60,9 +60,9 @@ macro_rules! ijon_max { static mut loc: u32 = 0; if loc == 0 { let cfile = std::ffi::CString::new(file!()).unwrap(); - loc = ijon_hashstr(line!(), cfile.as_ptr()); + loc = afl::ijon_hashstr(line!(), cfile.as_ptr()); } - ijon_max_variadic(_IJON_LOC_CACHE, $($x),+, 0u64) + afl::ijon_max_variadic(_IJON_LOC_CACHE, $($x),+, 0u64) }; }}; } @@ -74,9 +74,9 @@ macro_rules! ijon_min { static mut loc: u32 = 0; if loc == 0 { let cfile = std::ffi::CString::new(file!()).unwrap(); - loc = ijon_hashstr(line!(), cfile.as_ptr()); + loc = afl::ijon_hashstr(line!(), cfile.as_ptr()); } - ijon_min_variadic(loc, $($x),+, 0u64) + afl::ijon_min_variadic(loc, $($x),+, 0u64) }; }}; } @@ -88,9 +88,9 @@ macro_rules! ijon_set { static mut loc: u32 = 0; if loc == 0 { let cfile = std::ffi::CString::new(file!()).unwrap(); - loc = ijon_hashstr(line!(), cfile.as_ptr()); + loc = afl::ijon_hashstr(line!(), cfile.as_ptr()); } - ijon_set(loc, $x) + afl::ijon_set(loc, $x) }; }}; } @@ -98,7 +98,7 @@ macro_rules! ijon_set { #[macro_export] macro_rules! ijon_state { ($n:expr) => { - unsafe { ijon_xor_state($n) } + unsafe { afl::ijon_xor_state($n) } }; } @@ -106,10 +106,10 @@ macro_rules! ijon_state { macro_rules! ijon_ctx { ($x:expr) => {{ let cfile = std::ffi::CString::new(file!()).unwrap(); - let hash = unsafe { ijon_hashstr(line!(), cfile.as_ptr()) }; - unsafe { ijon_xor_state(hash) }; + let hash = unsafe { afl::ijon_hashstr(line!(), cfile.as_ptr()) }; + unsafe { afl::ijon_xor_state(hash) }; let temp = $x; - unsafe { ijon_xor_state(hash) }; + unsafe { afl::ijon_xor_state(hash) }; temp }}; } @@ -117,14 +117,14 @@ macro_rules! ijon_ctx { #[macro_export] macro_rules! ijon_max_at { ($addr:expr, $x:expr) => { - unsafe { ijon_max($addr, $x) } + unsafe { afl::ijon_max($addr, $x) } }; } #[macro_export] macro_rules! ijon_min_at { ($addr:expr, $x:expr) => { - unsafe { ijon_min($addr, $x) } + unsafe { afl::ijon_min($addr, $x) } }; } @@ -139,8 +139,8 @@ macro_rules! _ijon_abs_dist { macro_rules! ijon_bits { ($x:expr) => { unsafe { - ijon_set(ijon_hashint( - ijon_hashstack(), + afl::ijon_set(afl::ijon_hashint( + afl::ijon_hashstack(), if $x == 0 { 0 } else { @@ -154,7 +154,7 @@ macro_rules! ijon_bits { #[macro_export] macro_rules! ijon_strdist { ($x:expr, $y:expr) => { - unsafe { ijon_set(ijon_hashint(ijon_hashstack(), ijon_strdist($x, $y))) } + unsafe { afl::ijon_set(afl::ijon_hashint(afl::ijon_hashstack(), afl::ijon_strdist($x, $y))) } }; } @@ -162,8 +162,8 @@ macro_rules! ijon_strdist { macro_rules! ijon_dist { ($x:expr, $y:expr) => { unsafe { - ijon_set(ijon_hashint( - ijon_hashstack(), + afl::ijon_set(afl::ijon_hashint( + afl::ijon_hashstack(), $crate::_ijon_abs_dist!($x, $y), )) } @@ -173,7 +173,7 @@ macro_rules! ijon_dist { #[macro_export] macro_rules! ijon_cmp { ($x:expr, $y:expr) => { - unsafe { ijon_inc(ijon_hashint(ijon_hashstack(), ($x ^ $y).count_ones())) } + unsafe { afl::ijon_inc(afl::ijon_hashint(afl::ijon_hashstack(), ($x ^ $y).count_ones())) } }; } @@ -184,9 +184,9 @@ macro_rules! ijon_stack_max { static mut loc: u32 = 0; if loc == 0 { let cfile = std::ffi::CString::new(file!()).unwrap(); - loc = ijon_hashstr(line!(), cfile.as_ptr()); + loc = afl::ijon_hashstr(line!(), cfile.as_ptr()); } - ijon_max(ijon_hashint(loc, ijon_hashstack()), $x) + afl::ijon_max(afl::ijon_hashint(loc, afl::ijon_hashstack()), $x) }; }}; } @@ -198,9 +198,9 @@ macro_rules! ijon_stack_min { static mut loc: u32 = 0; if loc == 0 { let cfile = std::ffi::CString::new(file!()).unwrap(); - loc = ijon_hashstr(line!(), cfile.as_ptr()); + loc = afl::ijon_hashstr(line!(), cfile.as_ptr()); } - ijon_min(ijon_hashint(loc, ijon_hashstack()), $x) + afl::ijon_min(afl::ijon_hashint(loc, afl::ijon_hashstack()), $x) }; }}; } diff --git a/cargo-afl/tests/integration.rs b/cargo-afl/tests/integration.rs index 5957af037..1d09238b0 100644 --- a/cargo-afl/tests/integration.rs +++ b/cargo-afl/tests/integration.rs @@ -46,7 +46,7 @@ fn integration_cfg() { .arg("--manifest-path") .arg("../afl/Cargo.toml") .envs(if cfg_fuzzing { - vec![] + vec![("AFL_BENCH_UNTIL_CRASH", "1")] } else { vec![("AFL_NO_CFG_FUZZING", "1")] }) From 6ef12b50d005f271c25451720557739e70b8b82c Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 9 Oct 2025 09:36:52 +0200 Subject: [PATCH 31/35] try maze 3 times for integration --- afl/src/lib.rs | 14 ++++++++++++-- cargo-afl/tests/integration.rs | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/afl/src/lib.rs b/afl/src/lib.rs index a19386b61..787afd95f 100644 --- a/afl/src/lib.rs +++ b/afl/src/lib.rs @@ -154,7 +154,12 @@ macro_rules! ijon_bits { #[macro_export] macro_rules! ijon_strdist { ($x:expr, $y:expr) => { - unsafe { afl::ijon_set(afl::ijon_hashint(afl::ijon_hashstack(), afl::ijon_strdist($x, $y))) } + unsafe { + afl::ijon_set(afl::ijon_hashint( + afl::ijon_hashstack(), + afl::ijon_strdist($x, $y), + )) + } }; } @@ -173,7 +178,12 @@ macro_rules! ijon_dist { #[macro_export] macro_rules! ijon_cmp { ($x:expr, $y:expr) => { - unsafe { afl::ijon_inc(afl::ijon_hashint(afl::ijon_hashstack(), ($x ^ $y).count_ones())) } + unsafe { + afl::ijon_inc(afl::ijon_hashint( + afl::ijon_hashstack(), + ($x ^ $y).count_ones(), + )) + } }; } diff --git a/cargo-afl/tests/integration.rs b/cargo-afl/tests/integration.rs index 1d09238b0..5796e7988 100644 --- a/cargo-afl/tests/integration.rs +++ b/cargo-afl/tests/integration.rs @@ -71,7 +71,37 @@ fn integration_maze() { return; } - fuzz_example("maze", true); + let mut fail = 0; + let temp_dir = tempfile::TempDir::new().expect("Could not create temporary directory"); + let temp_dir_path = temp_dir.path(); + + for i in 0..3 { + let _: ExitStatus = process::Command::new(cargo_afl_path()) + .arg("afl") + .arg("fuzz") + .arg("-i") + .arg(input_path()) + .arg("-o") + .arg(temp_dir_path) + .args(["-V", "15"]) // 15 seconds + .arg(examples_path("maze")) + .env("AFL_BENCH_UNTIL_CRASH", "1") + .env("AFL_NO_CRASH_README", "1") + .env("AFL_NO_UI", "1") + .stdout(process::Stdio::inherit()) + .stderr(process::Stdio::inherit()) + .status() + .expect("Could not run cargo afl fuzz"); + assert!(temp_dir_path.join("default").join("fuzzer_stats").is_file()); + let crashes = std::fs::read_dir(temp_dir_path.join("default").join("crashes")) + .unwrap() + .count(); + if (crashes >= 1) { + return; + } + } + + assert!(false); } fn fuzz_example(name: &str, should_crash: bool) { @@ -84,7 +114,7 @@ fn fuzz_example(name: &str, should_crash: bool) { .arg(input_path()) .arg("-o") .arg(temp_dir_path) - .args(["-V", "10"]) // 5 seconds + .args(["-V", "5"]) // 5 seconds .arg(examples_path(name)) .env("AFL_BENCH_UNTIL_CRASH", "1") .env("AFL_NO_CRASH_README", "1") From ccb9745ccaeaa372d23d517cc26b80aafa7b0dfe Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 9 Oct 2025 09:44:16 +0200 Subject: [PATCH 32/35] clippy --- cargo-afl/tests/integration.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cargo-afl/tests/integration.rs b/cargo-afl/tests/integration.rs index 5796e7988..b9ee35a72 100644 --- a/cargo-afl/tests/integration.rs +++ b/cargo-afl/tests/integration.rs @@ -101,7 +101,7 @@ fn integration_maze() { } } - assert!(false); + unreachable!(); } fn fuzz_example(name: &str, should_crash: bool) { From ccc4b5ca016a1d9db63afd2087f03a35d2ce1525 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 9 Oct 2025 09:45:26 +0200 Subject: [PATCH 33/35] clippy --- cargo-afl/tests/integration.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cargo-afl/tests/integration.rs b/cargo-afl/tests/integration.rs index b9ee35a72..8c9499ea0 100644 --- a/cargo-afl/tests/integration.rs +++ b/cargo-afl/tests/integration.rs @@ -71,11 +71,10 @@ fn integration_maze() { return; } - let mut fail = 0; let temp_dir = tempfile::TempDir::new().expect("Could not create temporary directory"); let temp_dir_path = temp_dir.path(); - for i in 0..3 { + for _i in 0..3 { let _: ExitStatus = process::Command::new(cargo_afl_path()) .arg("afl") .arg("fuzz") @@ -96,7 +95,7 @@ fn integration_maze() { let crashes = std::fs::read_dir(temp_dir_path.join("default").join("crashes")) .unwrap() .count(); - if (crashes >= 1) { + if crashes >= 1 { return; } } From 4b29e673eb8ceeaf1c5035b7c49469734cecca00 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 9 Oct 2025 12:46:23 +0200 Subject: [PATCH 34/35] Update cargo-afl/tests/integration.rs Co-authored-by: Samuel Moelius <35515885+smoelius@users.noreply.github.com> --- cargo-afl/tests/integration.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cargo-afl/tests/integration.rs b/cargo-afl/tests/integration.rs index 8c9499ea0..e606ea9e1 100644 --- a/cargo-afl/tests/integration.rs +++ b/cargo-afl/tests/integration.rs @@ -46,7 +46,7 @@ fn integration_cfg() { .arg("--manifest-path") .arg("../afl/Cargo.toml") .envs(if cfg_fuzzing { - vec![("AFL_BENCH_UNTIL_CRASH", "1")] + vec![] } else { vec![("AFL_NO_CFG_FUZZING", "1")] }) From ad1842c73675ac6bb5860e6bdc511baa8fb56011 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 9 Oct 2025 12:48:15 +0200 Subject: [PATCH 35/35] indent --- afl/src/lib.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/afl/src/lib.rs b/afl/src/lib.rs index 787afd95f..804a1b3ff 100644 --- a/afl/src/lib.rs +++ b/afl/src/lib.rs @@ -57,12 +57,12 @@ macro_rules! ijon_inc { macro_rules! ijon_max { ($($x:expr),+ $(,)?) => {{ unsafe { - static mut loc: u32 = 0; - if loc == 0 { - let cfile = std::ffi::CString::new(file!()).unwrap(); - loc = afl::ijon_hashstr(line!(), cfile.as_ptr()); - } - afl::ijon_max_variadic(_IJON_LOC_CACHE, $($x),+, 0u64) + static mut loc: u32 = 0; + if loc == 0 { + let cfile = std::ffi::CString::new(file!()).unwrap(); + loc = afl::ijon_hashstr(line!(), cfile.as_ptr()); + } + afl::ijon_max_variadic(_IJON_LOC_CACHE, $($x),+, 0u64) }; }}; } @@ -71,12 +71,12 @@ macro_rules! ijon_max { macro_rules! ijon_min { ($($x:expr),+ $(,)?) => {{ unsafe { - static mut loc: u32 = 0; - if loc == 0 { - let cfile = std::ffi::CString::new(file!()).unwrap(); - loc = afl::ijon_hashstr(line!(), cfile.as_ptr()); - } - afl::ijon_min_variadic(loc, $($x),+, 0u64) + static mut loc: u32 = 0; + if loc == 0 { + let cfile = std::ffi::CString::new(file!()).unwrap(); + loc = afl::ijon_hashstr(line!(), cfile.as_ptr()); + } + afl::ijon_min_variadic(loc, $($x),+, 0u64) }; }}; }