From c03f2897d081b2bf41e179a48d758f1f400b5929 Mon Sep 17 00:00:00 2001 From: Samuel Moelius Date: Fri, 10 May 2024 16:55:32 -0400 Subject: Add `AFL_SHA1_FILENAMES` option --- docs/env_variables.md | 3 +++ 1 file changed, 3 insertions(+) (limited to 'docs') diff --git a/docs/env_variables.md b/docs/env_variables.md index 01904aea..b3519107 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -550,6 +550,9 @@ checks or alter some of the more exotic semantics of the tool: use a custom afl-qemu-trace or if you need to modify the afl-qemu-trace arguments. + - `AFL_SHA1_FILENAMES` causes AFL++ to generate files named by the SHA1 hash + of their contents, rather than use the standard `id:000000,...` names. + - `AFL_SHUFFLE_QUEUE` randomly reorders the input queue on startup. Requested by some users for unorthodox parallelized fuzzing setups, but not advisable otherwise. -- cgit 1.4.1 From 24b9d74e70107a4517396d7fa940140e206398bf Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 13 May 2024 08:44:43 +0200 Subject: compcov int fix --- docs/Changelog.md | 1 + instrumentation/split-compares-pass.so.cc | 6 ++++++ 2 files changed, 7 insertions(+) (limited to 'docs') diff --git a/docs/Changelog.md b/docs/Changelog.md index aa142274..9a95e343 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -13,6 +13,7 @@ * afl-cc: - re-enable i386 support that was accidently disabled - fixes for LTO and outdated afl-gcc mode + - fix COMPCOV split compare for old LLVMs - ensure shared memory variables are visible in weird build setups * afl-cmin - work with input files that have a space diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc index 728ebc22..9b7bf256 100644 --- a/instrumentation/split-compares-pass.so.cc +++ b/instrumentation/split-compares-pass.so.cc @@ -1778,7 +1778,13 @@ bool SplitComparesTransform::runOnModule(Module &M) { auto op0 = CI->getOperand(0); auto op1 = CI->getOperand(1); + // has to valid operands if (!op0 || !op1) { continue; } + // has exactly one constant and one variable + int constants = 0; + if (dyn_cast(op0)) { ++constants; } + if (dyn_cast(op1)) { ++constants; } + if (constants != 1) { continue; } auto iTy1 = dyn_cast(op0->getType()); if (iTy1 && isa(op1->getType())) { -- cgit 1.4.1 From b282ce999d2ab9428210deb0e838f45a6a534084 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 13 May 2024 13:42:58 +0200 Subject: post_process after trim --- docs/Changelog.md | 1 + docs/custom_mutators.md | 5 ++++ src/afl-fuzz-run.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ test/test-llvm.sh | 5 ++-- 4 files changed, 71 insertions(+), 2 deletions(-) (limited to 'docs') diff --git a/docs/Changelog.md b/docs/Changelog.md index 9a95e343..818010a7 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -7,6 +7,7 @@ * afl-fuzz - added AFL_DISABLE_REDUNDANT for huge queues - fix AFL_PERSISTENT_RECORD + - run custom_post_process after standard trimming - prevent filenames in the queue that have spaces - minor fix for FAST schedules - more frequent stats update when syncing (todo: check performance impact) diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index 73e3c802..b7a7032f 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -266,6 +266,11 @@ trimmed input. Here's a quick API description: Omitting any of three trimming methods will cause the trimming to be disabled and trigger a fallback to the built-in default trimming routine. +**IMPORTANT** If you have a custom post process mutator that needs to be run +after trimming, you must call it yourself at the end of your successful +trimming! + + ### Environment Variables Optionally, the following environment variables are supported: diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index ed7cb4ce..2a55da00 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -1028,6 +1028,68 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { if (needs_write) { + // run afl_custom_post_process + + if (unlikely(afl->custom_mutators_count) && + likely(!afl->afl_env.afl_post_process_keep_original)) { + + ssize_t new_size = q->len; + u8 *new_mem = in_buf; + u8 *new_buf = NULL; + + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (el->afl_custom_post_process) { + + new_size = el->afl_custom_post_process(el->data, new_mem, new_size, + &new_buf); + + if (unlikely(!new_buf || new_size <= 0)) { + + new_size = 0; + new_buf = new_mem; + + } else { + + new_mem = new_buf; + + } + + } + + }); + + if (unlikely(!new_size)) { + + new_size = q->len; + new_mem = in_buf; + + } + + if (unlikely(new_size < afl->min_length)) { + + new_size = afl->min_length; + + } else if (unlikely(new_size > afl->max_length)) { + + new_size = afl->max_length; + + } + + q->len = new_size; + + if (new_mem != in_buf && new_mem != NULL) { + + new_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), new_size); + if (unlikely(!new_buf)) { PFATAL("alloc"); } + memcpy(new_buf, new_mem, new_size); + + in_buf = new_buf; + + } + + } + s32 fd; if (unlikely(afl->no_unlink)) { diff --git a/test/test-llvm.sh b/test/test-llvm.sh index aef7a5e2..13e1bad1 100755 --- a/test/test-llvm.sh +++ b/test/test-llvm.sh @@ -197,7 +197,8 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && { for I in char short int long "long long"; do for BITS in 8 16 32 64; do bin="$testcase-split-$I-$BITS.compcov" - AFL_LLVM_INSTRUMENT=AFL AFL_DEBUG=1 AFL_LLVM_LAF_SPLIT_COMPARES_BITW=$BITS AFL_LLVM_LAF_SPLIT_COMPARES=1 ../afl-clang-fast -fsigned-char -DINT_TYPE="$I" -o "$bin" "$testcase" > test.out 2>&1; + #AFL_LLVM_INSTRUMENT=AFL + AFL_DEBUG=1 AFL_LLVM_LAF_SPLIT_COMPARES_BITW=$BITS AFL_LLVM_LAF_SPLIT_COMPARES=1 ../afl-clang-fast -fsigned-char -DINT_TYPE="$I" -o "$bin" "$testcase" > test.out 2>&1; if ! test -e "$bin"; then cat test.out $ECHO "$RED[!] llvm_mode laf-intel/compcov integer splitting failed! ($testcase with type $I split to $BITS)!"; @@ -269,7 +270,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && { { mkdir -p in echo 00000000000000000000000000000000 > in/in - AFL_BENCH_UNTIL_CRASH=1 ../afl-fuzz -l 3 -m none -V30 -i in -o out -c ./test-cmplog -- ./test-c >>errors 2>&1 + AFL_BENCH_UNTIL_CRASH=1 ../afl-fuzz -Z -l 3 -m none -V30 -i in -o out -c ./test-cmplog -- ./test-c >>errors 2>&1 } >>errors 2>&1 test -n "$( ls out/default/crashes/id:000000* out/default/hangs/id:000000* 2>/dev/null )" && { $ECHO "$GREEN[+] afl-fuzz is working correctly with llvm_mode cmplog" -- cgit 1.4.1 From b6c4f3775a229a5c760052cad1580358f5c44f56 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 14 May 2024 12:34:51 +0200 Subject: disable xml/curl/g_ string transform compare --- docs/Changelog.md | 2 ++ instrumentation/compare-transform-pass.so.cc | 36 +++++++++++++++++++++------- 2 files changed, 29 insertions(+), 9 deletions(-) (limited to 'docs') diff --git a/docs/Changelog.md b/docs/Changelog.md index 818010a7..79594e38 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -15,6 +15,8 @@ - re-enable i386 support that was accidently disabled - fixes for LTO and outdated afl-gcc mode - fix COMPCOV split compare for old LLVMs + - disable xml/curl/g_ string transform functions because we do not check + for null pointers ... TODO - ensure shared memory variables are visible in weird build setups * afl-cmin - work with input files that have a space diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc index f8ba9de5..ebab9cbb 100644 --- a/instrumentation/compare-transform-pass.so.cc +++ b/instrumentation/compare-transform-pass.so.cc @@ -230,38 +230,38 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, if (callInst->getCallingConv() != llvm::CallingConv::C) continue; StringRef FuncName = Callee->getName(); isStrcmp &= - (!FuncName.compare("strcmp") || !FuncName.compare("xmlStrcmp") || + (!FuncName.compare("strcmp") /*|| !FuncName.compare("xmlStrcmp") || !FuncName.compare("xmlStrEqual") || !FuncName.compare("curl_strequal") || !FuncName.compare("strcsequal") || - !FuncName.compare("g_strcmp0")); + !FuncName.compare("g_strcmp0")*/); isMemcmp &= (!FuncName.compare("memcmp") || !FuncName.compare("bcmp") || !FuncName.compare("CRYPTO_memcmp") || !FuncName.compare("OPENSSL_memcmp") || !FuncName.compare("memcmp_const_time") || !FuncName.compare("memcmpct")); - isStrncmp &= (!FuncName.compare("strncmp") || + isStrncmp &= (!FuncName.compare("strncmp")/* || !FuncName.compare("curl_strnequal") || - !FuncName.compare("xmlStrncmp")); + !FuncName.compare("xmlStrncmp")*/); isStrcasecmp &= (!FuncName.compare("strcasecmp") || !FuncName.compare("stricmp") || !FuncName.compare("ap_cstr_casecmp") || !FuncName.compare("OPENSSL_strcasecmp") || - !FuncName.compare("xmlStrcasecmp") || + /*!FuncName.compare("xmlStrcasecmp") || !FuncName.compare("g_strcasecmp") || !FuncName.compare("g_ascii_strcasecmp") || !FuncName.compare("Curl_strcasecompare") || - !FuncName.compare("Curl_safe_strcasecompare") || + !FuncName.compare("Curl_safe_strcasecompare") ||*/ !FuncName.compare("cmsstrcasecmp")); isStrncasecmp &= (!FuncName.compare("strncasecmp") || !FuncName.compare("strnicmp") || !FuncName.compare("ap_cstr_casecmpn") || - !FuncName.compare("OPENSSL_strncasecmp") || + !FuncName.compare("OPENSSL_strncasecmp") /*|| !FuncName.compare("xmlStrncasecmp") || !FuncName.compare("g_ascii_strncasecmp") || !FuncName.compare("Curl_strncasecompare") || - !FuncName.compare("g_strncasecmp")); + !FuncName.compare("g_strncasecmp")*/); isIntMemcpy &= !FuncName.compare("llvm.memcpy.p0i8.p0i8.i64"); if (!isStrcmp && !isMemcmp && !isStrncmp && !isStrcasecmp && @@ -465,8 +465,19 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, bool isCaseInsensitive = false; bool needs_null = false; bool success_is_one = false; + bool nullCheck = false; Function *Callee = callInst->getCalledFunction(); + fprintf(stderr, "%s - %s - %s\n", + callInst->getParent() + ->getParent() + ->getParent() + ->getName() + .str() + .c_str(), + callInst->getParent()->getParent()->getName().str().c_str(), + Callee ? Callee->getName().str().c_str() : "NULL"); + if (Callee) { if (!Callee->getName().compare("memcmp") || @@ -520,6 +531,11 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, } if (!isSizedcmp) needs_null = true; + if (Callee->getName().startswith("g_") || + Callee->getName().startswith("curl_") || + Callee->getName().startswith("Curl_") || + Callee->getName().startswith("xml")) + nullCheck = true; Value *sizedValue = isSizedcmp ? callInst->getArgOperand(2) : NULL; bool isConstSized = sizedValue && isa(sizedValue); @@ -604,8 +620,10 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, /* split before the call instruction */ BasicBlock *bb = callInst->getParent(); BasicBlock *end_bb = bb->splitBasicBlock(BasicBlock::iterator(callInst)); - BasicBlock *next_lenchk_bb = NULL; + + if (nullCheck) { fprintf(stderr, "TODO: null check\n"); } + if (isSizedcmp && !isConstSized) { next_lenchk_bb = -- cgit 1.4.1