From 76e1b4cb1e2bcd85bf7c5bfef221d924357249c6 Mon Sep 17 00:00:00 2001 From: Aarnav Date: Thu, 25 Jul 2024 18:10:21 +0200 Subject: [PATCH] Fix cmplog implementation (#2439) * fix cmplog implementation only set testcase filepath if filepath is none * libafl-fuzz: fix minor CI * add missing fields to AFLppCmpLogOperands * libafl-fuzz: pin CI AFL version to a commit fix extended_cmplog_instrumentation * libafl-fuzz: fix CI * this should not panic * aaa * libafl-fuzz: fix cmplog CI --------- Co-authored-by: Toka --- fuzzers/others/libafl-fuzz/Makefile.toml | 14 ++++---- libafl/src/corpus/inmemory_ondisk.rs | 4 ++- libafl_targets/src/cmplog.h | 21 +++++------ libafl_targets/src/cmps/mod.rs | 44 ++++++++++++++++++------ 4 files changed, 54 insertions(+), 29 deletions(-) diff --git a/fuzzers/others/libafl-fuzz/Makefile.toml b/fuzzers/others/libafl-fuzz/Makefile.toml index 90a0f25180..5bd29e2cd6 100644 --- a/fuzzers/others/libafl-fuzz/Makefile.toml +++ b/fuzzers/others/libafl-fuzz/Makefile.toml @@ -6,7 +6,7 @@ PROFILE_DIR = {value = "release", condition = {env_not_set = ["PROFILE_DIR"] }} FUZZER_NAME = 'libafl-fuzz' FUZZER = '${CARGO_TARGET_DIR}/${PROFILE_DIR}/${FUZZER_NAME}' LLVM_CONFIG = {value = "llvm-config-18", condition = {env_not_set = ["LLVM_CONFIG"] }} -AFL_VERSION = "4.21c" +AFL_VERSION = "db23931e7c1727ddac8691a6241c97b2203ec6fc" AFL_DIR_NAME= {value = "./AFLplusplus-${AFL_VERSION}"} AFL_CC_PATH= {value = "${AFL_DIR_NAME}/afl-clang-fast"} @@ -18,8 +18,8 @@ if [ ! -d "$AFL_DIR_NAME" ]; then if [ -f "v${AFL_VERSION}.zip" ]; then rm v${AFL_VERSION}.zip fi - wget https://github.com/AFLplusplus/AFLplusplus/archive/refs/tags/v${AFL_VERSION}.zip - unzip v${AFL_VERSION}.zip + wget https://github.com/AFLplusplus/AFLplusplus/archive/${AFL_VERSION}.zip + unzip ${AFL_VERSION}.zip cd ${AFL_DIR_NAME} LLVM_CONFIG=${LLVM_CONFIG} make cd .. @@ -60,9 +60,9 @@ test -d "./test/output/fuzzer_main/crashes" || { } # cmplog TODO: AFL_BENCH_UNTIL_CRASH=1 instead of timeout 15s AFL_LLVM_CMPLOG=1 AFL_PATH=${AFL_DIR_NAME} ${AFL_CC_PATH} ./test/test-cmplog.c -o ./test/out-cmplog -AFL_CORES=1 timeout 15 ${FUZZER} -Z -l 3 -m 0 -V30 -i ./test/seeds_cmplog -o ./test/cmplog-output -c 0 ./test/out-cmplog >>errors 2>&1 -test -n "$( ls ./test/cmplog-output/fuzzer_main/crashes/id:000000* ./test/cmplog-output/hangs/id:000000* 2>/dev/null )" || { - echo "no crashes found when running cmplog" +AFL_CORES=1 timeout 10 ${FUZZER} -Z -l 3 -m 0 -V30 -i ./test/seeds_cmplog -o ./test/cmplog-output -c 0 ./test/out-cmplog || true +test -n "$( ls ./test/cmplog-output/fuzzer_main/crashes/id:0* 2>/dev/null )" || { + echo "No crashes found" exit 1 } ''' @@ -77,7 +77,7 @@ windows_alias = "unsupported" script_runner="@shell" script=''' rm -rf AFLplusplus-${AFL_VERSION} -rm v${AFL_VERSION}.zip +rm ${AFL_VERSION}.zip rm -rf ./test/out-instr rm -rf ./test/output ''' diff --git a/libafl/src/corpus/inmemory_ondisk.rs b/libafl/src/corpus/inmemory_ondisk.rs index 2be9b46abd..788c357c92 100644 --- a/libafl/src/corpus/inmemory_ondisk.rs +++ b/libafl/src/corpus/inmemory_ondisk.rs @@ -413,7 +413,9 @@ where file_name }; - *testcase.file_path_mut() = Some(self.dir_path.join(&file_name)); + if testcase.file_path().is_none() { + *testcase.file_path_mut() = Some(self.dir_path.join(&file_name)); + } *testcase.filename_mut() = Some(file_name); if self.meta_format.is_some() { diff --git a/libafl_targets/src/cmplog.h b/libafl_targets/src/cmplog.h index 05be988e6d..ef9f74eaad 100644 --- a/libafl_targets/src/cmplog.h +++ b/libafl_targets/src/cmplog.h @@ -11,12 +11,7 @@ #define CMPLOG_MAP_H 32 #endif -// difference between aflpp and libafl -#ifdef CMPLOG_EXTENDED - #define CMPLOG_RTN_LEN 31 -#else - #define CMPLOG_RTN_LEN 32 -#endif +#define CMPLOG_RTN_LEN 32 #define CMPLOG_MAP_RTN_H \ ((CMPLOG_MAP_H * sizeof(CmpLogInstruction)) / sizeof(CmpLogRoutine)) @@ -57,10 +52,15 @@ typedef struct CmpLogInstruction { typedef struct CmpLogInstructionExtended { uint64_t v0; - uint64_t v1; uint64_t v0_128; + uint64_t v0_256_0; // u256 is unsupported by any compiler for now, so future use + uint64_t v0_256_1; + uint64_t v1; uint64_t v1_128; -} CmpLogInstructionExtended; + uint64_t v1_256_0; + uint64_t v1_256_1; + uint8_t unused[8]; +} __attribute__((packed)) CmpLogInstructionExtended; typedef struct CmpLogRoutine { uint8_t v0[CMPLOG_RTN_LEN]; @@ -69,10 +69,11 @@ typedef struct CmpLogRoutine { typedef struct CmpLogRoutineExtended { uint8_t v0[CMPLOG_RTN_LEN]; - uint8_t v0_len; uint8_t v1[CMPLOG_RTN_LEN]; + uint8_t v0_len; uint8_t v1_len; -} CmpLogRoutineExtended; + uint8_t unused[6]; +} __attribute__((packed)) CmpLogRoutineExtended; typedef struct CmpLogMap { CmpLogHeader headers[CMPLOG_MAP_W]; diff --git a/libafl_targets/src/cmps/mod.rs b/libafl_targets/src/cmps/mod.rs index 51ccebce30..7d6c0b8c9f 100644 --- a/libafl_targets/src/cmps/mod.rs +++ b/libafl_targets/src/cmps/mod.rs @@ -88,9 +88,14 @@ pub struct CmpLogHeader { /// comparison size is determined by the `hits` field of the associated `AFLppCmpLogHeader`. pub struct AFLppCmpLogOperands { v0: u64, - v1: u64, v0_128: u64, + v0_256_0: u64, + v0_256_1: u64, + v1: u64, v1_128: u64, + v1_256_0: u64, + v1_256_1: u64, + unused: [u8; 8], } impl AFLppCmpLogOperands { @@ -99,9 +104,14 @@ impl AFLppCmpLogOperands { pub fn new(v0: u64, v1: u64) -> Self { Self { v0, - v1, v0_128: 0, + v0_256_0: 0, + v0_256_1: 0, + v1, v1_128: 0, + v1_256_0: 0, + v1_256_1: 0, + unused: [0; 8], } } @@ -115,9 +125,14 @@ impl AFLppCmpLogOperands { Self { v0, - v1, v0_128, + v0_256_0: 0, + v0_256_1: 0, + v1, v1_128, + v1_256_0: 0, + v1_256_1: 0, + unused: [0; 8], } } @@ -175,10 +190,11 @@ impl AFLppCmpLogOperands { #[repr(C, packed)] /// Comparison function operands, like for strcmp/memcmp, represented as two byte arrays. pub struct AFLppCmpLogFnOperands { - v0: [u8; 31], + v0: [u8; 32], + v1: [u8; 32], v0_len: u8, - v1: [u8; 31], v1_len: u8, + unused: [u8; 6], } impl AFLppCmpLogFnOperands { @@ -188,8 +204,8 @@ impl AFLppCmpLogFnOperands { let v0_len = v0.len() as u8; let v1_len = v1.len() as u8; - let mut v0_arr = [0; 31]; - let mut v1_arr = [0; 31]; + let mut v0_arr = [0; 32]; + let mut v1_arr = [0; 32]; v0_arr.copy_from_slice(v0); v1_arr.copy_from_slice(v1); @@ -199,12 +215,13 @@ impl AFLppCmpLogFnOperands { v0_len, v1: v1_arr, v1_len, + unused: [0; 6], } } #[must_use] /// first rtn operand - pub fn v0(&self) -> &[u8; 31] { + pub fn v0(&self) -> &[u8; 32] { &self.v0 } @@ -216,7 +233,7 @@ impl AFLppCmpLogFnOperands { #[must_use] /// first rtn operand len - pub fn v1(&self) -> &[u8; 31] { + pub fn v1(&self) -> &[u8; 32] { &self.v1 } @@ -415,9 +432,14 @@ pub static mut libafl_cmplog_map_extended: AFLppCmpLogMap = AFLppCmpLogMap { vals: AFLppCmpLogVals { operands: [[AFLppCmpLogOperands { v0: 0, - v1: 0, v0_128: 0, + v0_256_0: 0, + v0_256_1: 0, + v1: 0, v1_128: 0, + v1_256_0: 0, + v1_256_1: 0, + unused: [0; 8], }; CMPLOG_MAP_H]; CMPLOG_MAP_W], }, }; @@ -535,7 +557,7 @@ impl CmpMap for AFLppCmpLogMap { self.vals.operands[idx][execution].v0, self.vals.operands[idx][execution].v1, ))), - // TODO handle 128 bits cmps + // TODO handle 128 bits & 256 bits cmps // other => panic!("Invalid CmpLog shape {}", other), _ => None, }