From 52124813524fb0a28543066e70c86396931270a3 Mon Sep 17 00:00:00 2001 From: Michael Rodler Date: Mon, 15 Feb 2021 16:45:36 +0100 Subject: CMPLOG llvm pass: use CreateIntCast to cast to the right integer type --- instrumentation/cmplog-instructions-pass.cc | 165 +++++----------------------- 1 file changed, 27 insertions(+), 138 deletions(-) diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc index 6b071b48..9cd99f85 100644 --- a/instrumentation/cmplog-instructions-pass.cc +++ b/instrumentation/cmplog-instructions-pass.cc @@ -19,12 +19,13 @@ #include #include +#include #include #include #include #include -#include "llvm/Config/llvm-config.h" +#include "llvm/Config/llvm-config.h" #include "llvm/ADT/Statistic.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LegacyPassManager.h" @@ -323,38 +324,8 @@ bool CmpLogInstructions::hookInstrs(Module &M) { Value *CompareTo = Val; if (do_cast) { - - ConstantInt *cint = dyn_cast(Val); - if (cint) { - - uint64_t val = cint->getZExtValue(); - // fprintf(stderr, "ConstantInt: %lu\n", val); - switch (cast_size) { - - case 8: - CompareTo = ConstantInt::get(Int8Ty, val); - break; - case 16: - CompareTo = ConstantInt::get(Int16Ty, val); - break; - case 32: - CompareTo = ConstantInt::get(Int32Ty, val); - break; - case 64: - CompareTo = ConstantInt::get(Int64Ty, val); - break; - case 128: - CompareTo = ConstantInt::get(Int128Ty, val); - break; - - } - - } else { - - CompareTo = IRB.CreateBitCast(Val, IntegerType::get(C, cast_size)); - - } - + CompareTo = + IRB.CreateIntCast(CompareTo, IntegerType::get(C, cast_size), false); } for (SwitchInst::CaseIt i = SI->case_begin(), e = SI->case_end(); i != e; @@ -374,29 +345,8 @@ bool CmpLogInstructions::hookInstrs(Module &M) { Value *new_param = cint; if (do_cast) { - - uint64_t val = cint->getZExtValue(); - // fprintf(stderr, "ConstantInt: %lu\n", val); - switch (cast_size) { - - case 8: - new_param = ConstantInt::get(Int8Ty, val); - break; - case 16: - new_param = ConstantInt::get(Int16Ty, val); - break; - case 32: - new_param = ConstantInt::get(Int32Ty, val); - break; - case 64: - new_param = ConstantInt::get(Int64Ty, val); - break; - case 128: - new_param = ConstantInt::get(Int128Ty, val); - break; - - } - + new_param = + IRB.CreateIntCast(cint, IntegerType::get(C, cast_size), false); } if (new_param) { @@ -604,88 +554,27 @@ bool CmpLogInstructions::hookInstrs(Module &M) { } - if (do_cast) { - - // F*cking LLVM optimized out any kind of bitcasts of ConstantInt values - // creating illegal calls. WTF. So we have to work around this. - - ConstantInt *cint = dyn_cast(op0); - if (cint) { - - uint64_t val = cint->getZExtValue(); - // fprintf(stderr, "ConstantInt: %lu\n", val); - ConstantInt *new_param = NULL; - switch (cast_size) { - - case 8: - new_param = ConstantInt::get(Int8Ty, val); - break; - case 16: - new_param = ConstantInt::get(Int16Ty, val); - break; - case 32: - new_param = ConstantInt::get(Int32Ty, val); - break; - case 64: - new_param = ConstantInt::get(Int64Ty, val); - break; - case 128: - new_param = ConstantInt::get(Int128Ty, val); - break; - - } - - if (!new_param) { continue; } - args.push_back(new_param); - - } else { - - Value *V0 = IRB.CreateBitCast(op0, IntegerType::get(C, cast_size)); - args.push_back(V0); - - } - - cint = dyn_cast(op1); - if (cint) { - - uint64_t val = cint->getZExtValue(); - ConstantInt *new_param = NULL; - switch (cast_size) { - - case 8: - new_param = ConstantInt::get(Int8Ty, val); - break; - case 16: - new_param = ConstantInt::get(Int16Ty, val); - break; - case 32: - new_param = ConstantInt::get(Int32Ty, val); - break; - case 64: - new_param = ConstantInt::get(Int64Ty, val); - break; - case 128: - new_param = ConstantInt::get(Int128Ty, val); - break; - - } - - if (!new_param) { continue; } - args.push_back(new_param); - - } else { - - Value *V1 = IRB.CreateBitCast(op1, IntegerType::get(C, cast_size)); - args.push_back(V1); - - } - - } else { - - args.push_back(op0); - args.push_back(op1); - - } + // errs() << "[CMPLOG] cmp " << *cmpInst << "(in function " << + // cmpInst->getFunction()->getName() << ")\n"; + + // first bitcast to integer type of the same bitsize as the original + // type (this is a nop, if already integer) + Value *op0_i = IRB.CreateBitCast( + op0, IntegerType::get(C, op0->getType()->getPrimitiveSizeInBits())); + // then create a int cast, which does zext, trunc or bitcast. In our case + // usually zext to the next larger supported type (this is a nop if + // already the right type) + Value *V0 = + IRB.CreateIntCast(op0_i, IntegerType::get(C, cast_size), false); + args.push_back(V0); + Value *op1_i = IRB.CreateBitCast( + op1, IntegerType::get(C, op1->getType()->getPrimitiveSizeInBits())); + Value *V1 = + IRB.CreateIntCast(op1_i, IntegerType::get(C, cast_size), false); + args.push_back(V1); + + // errs() << "[CMPLOG] casted parameters:\n0: " << *V0 << "\n1: " << *V1 + // << "\n"; ConstantInt *attribute = ConstantInt::get(Int8Ty, attr); args.push_back(attribute); -- cgit 1.4.1 From 6caec2169cef890ba8a62715c2c26cc0608626e3 Mon Sep 17 00:00:00 2001 From: Michael Rodler Date: Mon, 15 Feb 2021 19:14:28 +0100 Subject: Revert "llvm bug workaround for lto extint" This reverts commit e3a5c31307f323452dc4b5288e0d19a02b596a33. --- docs/Changelog.md | 1 - include/envs.h | 1 - instrumentation/cmplog-instructions-pass.cc | 39 +++-------------------------- qemu_mode/libqasan/dlmalloc.c | 5 ---- src/afl-cc.c | 2 -- src/afl-fuzz-redqueen.c | 1 - 6 files changed, 4 insertions(+), 45 deletions(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index e2482f8f..71ef4c2c 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -49,7 +49,6 @@ sending a mail to . CLANG for old afl-clang - fixed a potential crash in the LAF feature - workaround for llvm 13 - - workaround for llvm internal lto bug that lets not bitcast from _ExtInt() - qemuafl - QASan (address sanitizer for Qemu) ported to qemuafl! See qemu_mode/libqasan/README.md diff --git a/include/envs.h b/include/envs.h index 36667ebc..4313e053 100644 --- a/include/envs.h +++ b/include/envs.h @@ -16,7 +16,6 @@ static char *afl_environment_deprecated[] = { static char *afl_environment_variables[] = { - "_AFL_LTO_COMPILE", "AFL_ALIGNED_ALLOC", "AFL_ALLOW_TMP", "AFL_ANALYZE_HEX", diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc index 9cd99f85..50ade9fd 100644 --- a/instrumentation/cmplog-instructions-pass.cc +++ b/instrumentation/cmplog-instructions-pass.cc @@ -114,8 +114,6 @@ bool CmpLogInstructions::hookInstrs(Module &M) { IntegerType *Int64Ty = IntegerType::getInt64Ty(C); IntegerType *Int128Ty = IntegerType::getInt128Ty(C); - char *is_lto = getenv("_AFL_LTO_COMPILE"); - #if LLVM_VERSION_MAJOR < 9 Constant * #else @@ -268,20 +266,10 @@ bool CmpLogInstructions::hookInstrs(Module &M) { unsigned int max_size = Val->getType()->getIntegerBitWidth(), cast_size; unsigned char do_cast = 0; - if (!SI->getNumCases() || max_size < 16) { continue; } - - if (max_size % 8) { - - if (is_lto) { + if (!SI->getNumCases() || max_size < 16 || max_size % 8) { - continue; // LTO cannot bitcast from _ExtInt() :( - - } else { - - max_size = (((max_size / 8) + 1) * 8); - do_cast = 1; - - } + // if (!be_quiet) errs() << "skip trivial switch..\n"; + continue; } @@ -298,7 +286,6 @@ bool CmpLogInstructions::hookInstrs(Module &M) { } - if (is_lto) { continue; } // LTO cannot bitcast _ExtInt() :( max_size = 128; do_cast = 1; @@ -315,7 +302,6 @@ bool CmpLogInstructions::hookInstrs(Module &M) { cast_size = max_size; break; default: - if (is_lto) { continue; } // LTO cannot bitcast _ExtInt() :( cast_size = 128; do_cast = 1; @@ -504,22 +490,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) { } - if (!max_size || max_size < 16) { continue; } - - if (max_size % 8) { - - if (is_lto) { - - continue; // LTO cannot bitcast from _ExtInt() :( - - } else { - - max_size = (((max_size / 8) + 1) * 8); - do_cast = 1; - - } - - } + if (!max_size || max_size % 8 || max_size < 16) { continue; } if (max_size > 128) { @@ -531,7 +502,6 @@ bool CmpLogInstructions::hookInstrs(Module &M) { } - if (is_lto) { continue; } // LTO cannot bitcast from _ExtInt() :( max_size = 128; do_cast = 1; @@ -548,7 +518,6 @@ bool CmpLogInstructions::hookInstrs(Module &M) { cast_size = max_size; break; default: - if (is_lto) { continue; } // LTO cannot bitcast from _ExtInt() :( cast_size = 128; do_cast = 1; diff --git a/qemu_mode/libqasan/dlmalloc.c b/qemu_mode/libqasan/dlmalloc.c index aff58ad5..bace0ff6 100644 --- a/qemu_mode/libqasan/dlmalloc.c +++ b/qemu_mode/libqasan/dlmalloc.c @@ -3917,7 +3917,6 @@ static void internal_malloc_stats(mstate m) { \ } else if (RTCHECK(B == smallbin_at(M, I) || \ \ - \ (ok_address(M, B) && B->fd == P))) { \ \ F->bk = B; \ @@ -4129,7 +4128,6 @@ static void internal_malloc_stats(mstate m) { \ } else \ \ - \ CORRUPTION_ERROR_ACTION(M); \ if (R != 0) { \ \ @@ -4146,7 +4144,6 @@ static void internal_malloc_stats(mstate m) { \ } else \ \ - \ CORRUPTION_ERROR_ACTION(M); \ \ } \ @@ -4159,14 +4156,12 @@ static void internal_malloc_stats(mstate m) { \ } else \ \ - \ CORRUPTION_ERROR_ACTION(M); \ \ } \ \ } else \ \ - \ CORRUPTION_ERROR_ACTION(M); \ \ } \ diff --git a/src/afl-cc.c b/src/afl-cc.c index 959c9a6f..d41f79a2 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1875,8 +1875,6 @@ int main(int argc, char **argv, char **envp) { edit_params(argc, argv, envp); - if (lto_mode) { setenv("_AFL_LTO_COMPILE", "1", 1); } - if (debug) { DEBUGF("cd '%s';", getthecwd()); diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index cf65d3c1..275af9c8 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -1547,7 +1547,6 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, is_n = 1; } - #endif for (i = 0; i < loggeds; ++i) { -- cgit 1.4.1 From 80bdbf7be0a1e7bd54b24d4376048d85fb403bf6 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 16 Feb 2021 09:54:15 +0100 Subject: minor cmplog fix --- docs/Changelog.md | 1 + instrumentation/cmplog-instructions-pass.cc | 22 ++++++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index 71ef4c2c..477498d0 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -48,6 +48,7 @@ sending a mail to . support (less performant than our own), GCC for old afl-gcc and CLANG for old afl-clang - fixed a potential crash in the LAF feature + - workaround for llvm bitcast lto bug - workaround for llvm 13 - qemuafl - QASan (address sanitizer for Qemu) ported to qemuafl! diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc index 50ade9fd..dbca9afa 100644 --- a/instrumentation/cmplog-instructions-pass.cc +++ b/instrumentation/cmplog-instructions-pass.cc @@ -266,13 +266,20 @@ bool CmpLogInstructions::hookInstrs(Module &M) { unsigned int max_size = Val->getType()->getIntegerBitWidth(), cast_size; unsigned char do_cast = 0; - if (!SI->getNumCases() || max_size < 16 || max_size % 8) { + if (!SI->getNumCases() || max_size < 16) { // if (!be_quiet) errs() << "skip trivial switch..\n"; continue; } + if (max_size % 8) { + + max_size = (((max_size / 8) + 1) * 8); + do_cast = 1; + + } + IRBuilder<> IRB(SI->getParent()); IRB.SetInsertPoint(SI); @@ -310,8 +317,10 @@ bool CmpLogInstructions::hookInstrs(Module &M) { Value *CompareTo = Val; if (do_cast) { + CompareTo = IRB.CreateIntCast(CompareTo, IntegerType::get(C, cast_size), false); + } for (SwitchInst::CaseIt i = SI->case_begin(), e = SI->case_end(); i != e; @@ -331,8 +340,10 @@ bool CmpLogInstructions::hookInstrs(Module &M) { Value *new_param = cint; if (do_cast) { + new_param = IRB.CreateIntCast(cint, IntegerType::get(C, cast_size), false); + } if (new_param) { @@ -490,7 +501,14 @@ bool CmpLogInstructions::hookInstrs(Module &M) { } - if (!max_size || max_size % 8 || max_size < 16) { continue; } + if (!max_size || max_size < 16) { continue; } + + if (max_size % 8) { + + max_size = (((max_size / 8) + 1) * 8); + do_cast = 1; + + } if (max_size > 128) { -- cgit 1.4.1 From 7d97ffb1e82cd0ddebaa5e143ed326e41a6ca25b Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Tue, 16 Feb 2021 16:27:56 +0100 Subject: check for setuptools instead of easy_install --- test/test-unicorn-mode.sh | 2 +- unicorn_mode/build_unicorn_support.sh | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test-unicorn-mode.sh b/test/test-unicorn-mode.sh index b4c6eb3e..e197e226 100755 --- a/test/test-unicorn-mode.sh +++ b/test/test-unicorn-mode.sh @@ -14,7 +14,7 @@ test -d ../unicorn_mode/unicornafl -a -e ../unicorn_mode/unicornafl/samples/shel EASY_INSTALL_FOUND=0 for PYTHON in $PYTHONS ; do - if $PYTHON -c "help('easy_install');" Date: Tue, 16 Feb 2021 11:17:55 -0500 Subject: Regression fix Previous fix was undone in a subsequent commit --- qemu_mode/libqasan/string.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu_mode/libqasan/string.c b/qemu_mode/libqasan/string.c index c850463b..4be01279 100644 --- a/qemu_mode/libqasan/string.c +++ b/qemu_mode/libqasan/string.c @@ -271,7 +271,7 @@ void *__libqasan_memmem(const void *haystack, size_t haystack_len, } - } while (h++ <= end); + } while (++h <= end); return 0; -- cgit 1.4.1 From 938512a6b9451000f40491b2554b5d360840cfe5 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 17 Feb 2021 09:48:04 +0100 Subject: minor fixes --- include/config.h | 4 ++-- include/envs.h | 1 + instrumentation/afl-compiler-rt.o.c | 2 +- qemu_mode/README.md | 22 ++++++++++------------ qemu_mode/qemuafl | 2 +- 5 files changed, 15 insertions(+), 16 deletions(-) diff --git a/include/config.h b/include/config.h index 181285cd..9f7db04d 100644 --- a/include/config.h +++ b/include/config.h @@ -42,7 +42,7 @@ * */ -/* Enable arithmetic compare solving for both path */ +/* Enable arithmetic compare solving for both branches */ #define CMPLOG_SOLVE_ARITHMETIC /* Enable transform following (XOR/ADD/SUB manipulations, hex en/decoding) */ @@ -51,7 +51,7 @@ /* if TRANSFORM is enabled, this additionally enables base64 en/decoding */ // #define CMPLOG_SOLVE_TRANSFORM_BASE64 -/* If a redqueen pass finds more than one solve, try to combine them? */ +/* If a redqueen pass finds more than one solution, try to combine them? */ #define CMPLOG_COMBINE /* Minimum % of the corpus to perform cmplog on. Default: 20% */ diff --git a/include/envs.h b/include/envs.h index 4313e053..143979c6 100644 --- a/include/envs.h +++ b/include/envs.h @@ -131,6 +131,7 @@ static char *afl_environment_variables[] = { "AFL_QEMU_DEBUG_MAPS", "AFL_QEMU_DISABLE_CACHE", "AFL_QEMU_DRIVER_NO_HOOK", + "AFL_QEMU_FORCE_DFL", "AFL_QEMU_PERSISTENT_ADDR", "AFL_QEMU_PERSISTENT_CNT", "AFL_QEMU_PERSISTENT_GPR", diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 5fb715e2..dba4dc65 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -1090,7 +1090,7 @@ __attribute__((constructor(0))) void __afl_auto_first(void) { if (getenv("AFL_DISABLE_LLVM_INSTRUMENTATION")) return; u8 *ptr; - ptr = (u8 *)malloc(2097152); + ptr = (u8 *)malloc(MAP_INITIAL_SIZE); if (ptr && (ssize_t)ptr != -1) { diff --git a/qemu_mode/README.md b/qemu_mode/README.md index 9818846d..bc4c1d2c 100644 --- a/qemu_mode/README.md +++ b/qemu_mode/README.md @@ -17,7 +17,7 @@ The idea and much of the initial implementation comes from Andrew Griffiths. The actual implementation on current QEMU (shipped as qemuafl) is from Andrea Fioraldi. Special thanks to abiondo that re-enabled TCG chaining. -## 2) How to use +## 2) How to use qemu_mode The feature is implemented with a patched QEMU. The simplest way to build it is to run ./build_qemu_support.sh. The script will download, @@ -176,7 +176,12 @@ Comparative measurements of execution speed or instrumentation coverage will be fairly meaningless if the optimization levels or instrumentation scopes don't match. -## 12) Gotchas, feedback, bugs +## 12) Other features + +With `AFL_QEMU_FORCE_DFL` you force QEMU to ignore the registered signal +handlers of the target. + +## 13) Gotchas, feedback, bugs If you need to fix up checksums or do other cleanup on mutated test cases, see utils/custom_mutators/ for a viable solution. @@ -197,19 +202,12 @@ with -march=core2, can help. Beyond that, this is an early-stage mechanism, so fields reports are welcome. You can send them to . -## 13) Alternatives: static rewriting +## 14) Alternatives: static rewriting Statically rewriting binaries just once, instead of attempting to translate them at run time, can be a faster alternative. That said, static rewriting is fraught with peril, because it depends on being able to properly and fully model program control flow without actually executing each and every code path. -The best implementation is this one: - - https://github.com/vanhauser-thc/afl-dyninst - -The issue however is Dyninst which is not rewriting the binaries so that -they run stable. A lot of crashes happen, especially in C++ programs that -use throw/catch. Try it first, and if it works for you be happy as it is -2-3x as fast as qemu_mode, however usually not as fast as QEMU persistent mode. - +Checkout the "Fuzzing binary-only targets" section in our main README.md and +the docs/binaryonly_fuzzing.md document for more information and hints. diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl index 9a258d5b..213f3b27 160000 --- a/qemu_mode/qemuafl +++ b/qemu_mode/qemuafl @@ -1 +1 @@ -Subproject commit 9a258d5b7a38c045a6e385fcfcf80a746a60e557 +Subproject commit 213f3b27dd099ef352181c48cd75c0f20a73e3f0 -- cgit 1.4.1 From 4c47b242eb976b8518ab8884733d02465f02d90a Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 17 Feb 2021 17:40:01 +0100 Subject: fix FPE in colorization --- src/afl-fuzz-redqueen.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 275af9c8..bbe35fe5 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -421,8 +421,9 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, if (taint) { - if (len / positions == 1 && positions > CMPLOG_POSITIONS_MAX && - afl->active_paths / afl->colorize_success > CMPLOG_CORPUS_PERCENT) { + if (afl->colorize_success && + (len / positions == 1 && positions > CMPLOG_POSITIONS_MAX && + afl->active_paths / afl->colorize_success > CMPLOG_CORPUS_PERCENT)) { #ifdef _DEBUG fprintf(stderr, "Colorization unsatisfactory\n"); @@ -1547,6 +1548,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, is_n = 1; } + #endif for (i = 0; i < loggeds; ++i) { -- cgit 1.4.1