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 <tokazerkje@outlook.com>
This commit is contained in:
Aarnav 2024-07-25 18:10:21 +02:00 committed by GitHub
parent c857b8dd77
commit 76e1b4cb1e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 54 additions and 29 deletions

View File

@ -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
'''

View File

@ -413,7 +413,9 @@ where
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() {

View File

@ -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_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];

View File

@ -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,
}