From e139515c254a4bd22d1cd33710bb1885f121fdcf Mon Sep 17 00:00:00 2001 From: akshaytheflash Date: Wed, 25 Feb 2026 02:35:47 -0800 Subject: [PATCH] fix(cmplog): handle non-power-of-2 comparison sizes from AFL++ GCC plugin AFL++'s GCC cmplog plugin (afl-gcc-cmplog-pass.so.cc) can report comparison sizes that are not powers of 2, e.g. 24-bit (shape=2), 40-bit (shape=4), 48-bit (shape=5), 56-bit (shape=6), via the hookN variant. The clang plugin rounds these up to the next power of 2, but the GCC plugin reports the actual size, causing LibAFL to panic with 'Invalid CmpLog shape {shape}'. Fix both CmpLogMap::values_of and AflppCmpLogMap::values_of to treat: - shape 2 (24-bit) as U32 (same as clang plugin) - shapes 4/5/6 (40/48/56-bit) as U64 (same as clang plugin) For any remaining unknown shapes, emit a warning instead of panicking. Fixes #3729 --- crates/libafl_targets/src/cmps/mod.rs | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/crates/libafl_targets/src/cmps/mod.rs b/crates/libafl_targets/src/cmps/mod.rs index b52eec3a68..52e46b46ce 100644 --- a/crates/libafl_targets/src/cmps/mod.rs +++ b/crates/libafl_targets/src/cmps/mod.rs @@ -412,19 +412,26 @@ impl CmpMap for CmpLogMap { self.vals.operands[idx][execution].1 as u16, self.vals.operands[idx][execution].2 == 1, ))), - 3 => Some(CmpValues::U32(( + // Shape 2 = 24-bit (3 bytes): AFL++ GCC cmplog plugin reports 24-bit comparisons + // via hookN. Treat as 32-bit (U32), same as the clang plugin does. + 2 | 3 => Some(CmpValues::U32(( self.vals.operands[idx][execution].0 as u32, self.vals.operands[idx][execution].1 as u32, self.vals.operands[idx][execution].2 == 1, ))), - 7 => Some(CmpValues::U64(( + // Shapes 4/5/6 = 40/48/56-bit: AFL++ GCC cmplog plugin can report these sizes + // via hookN. Treat as 64-bit (U64), rounding up to the next power-of-2. + 4 | 5 | 6 | 7 => Some(CmpValues::U64(( self.vals.operands[idx][execution].0, self.vals.operands[idx][execution].1, self.vals.operands[idx][execution].2 == 1, ))), // TODO handle 128 bits & 256 bits & 512 bits cmps 15 | 31 | 63 => None, - _ => panic!("Invalid CmpLog shape {shape}"), + _ => { + log::warn!("Ignoring unknown CmpLog shape {shape}"); + None + } } } } else { @@ -618,19 +625,26 @@ impl CmpMap for AflppCmpLogMap { self.vals.operands[idx][execution].v1 as u16, false, ))), - 3 => Some(CmpValues::U32(( + // Shape 2 = 24-bit (3 bytes): AFL++ GCC cmplog plugin reports 24-bit comparisons + // via hookN. Treat as 32-bit (U32), same as the clang plugin does. + 2 | 3 => Some(CmpValues::U32(( self.vals.operands[idx][execution].v0 as u32, self.vals.operands[idx][execution].v1 as u32, false, ))), - 7 => Some(CmpValues::U64(( + // Shapes 4/5/6 = 40/48/56-bit: AFL++ GCC cmplog plugin can report these sizes + // via hookN. Treat as 64-bit (U64), rounding up to the next power-of-2. + 4 | 5 | 6 | 7 => Some(CmpValues::U64(( self.vals.operands[idx][execution].v0, self.vals.operands[idx][execution].v1, false, ))), // TODO handle 128 bits & 256 bits & 512 bits cmps 15 | 31 | 63 => None, - _ => panic!("Invalid CmpLog shape {shape}"), + _ => { + log::warn!("Ignoring unknown CmpLog shape {shape}"); + None + } } } } else {