diff options
-rw-r--r-- | docs/Changelog.md | 8 | ||||
-rw-r--r-- | include/envs.h | 2 | ||||
-rw-r--r-- | llvm_mode/LLVMInsTrim.so.cc | 95 | ||||
-rw-r--r-- | llvm_mode/afl-llvm-rt.o.c | 2 | ||||
-rw-r--r-- | src/afl-as.c | 3 | ||||
-rw-r--r-- | src/afl-fuzz-one.c | 4 | ||||
-rw-r--r-- | src/afl-fuzz-redqueen.c | 10 |
7 files changed, 87 insertions, 37 deletions
diff --git a/docs/Changelog.md b/docs/Changelog.md index 5d781545..0d67e807 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -17,6 +17,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>. - the memory safety checks are now disabled for a little more speed during fuzzing (only affects creating queue entries), can be toggled in config.h - afl-fuzz: + - MOpt out of bounds writing crash fixed - now prints the real python version support compiled in - set stronger performance compile options and little tweaks - Android: prefer bigcores when selecting a CPU @@ -28,7 +29,12 @@ sending a mail to <afl-users+subscribe@googlegroups.com>. - bugfix for dictionary insert stage count (fix via Google repo PR) - added warning if -M is used together with custom mutators with _ONLY option - AFL_TMPDIR checks are now later and better explained if they fail - - llvm_mode InsTrim: no pointless instrumentation of 1 block functions + - llvm_mode + - InsTrim: three bug fixes: + 1. (minor) no pointless instrumentation of 1 block functions + 2. (medium) path bug that leads a few blocks not instrumented that + should be + 3. (major) incorrect prev_loc was written, fixed! - afl-clang-fast: - show in the help output for which llvm version it was compiled for - now does not need to be recompiled between trace-pc and pass diff --git a/include/envs.h b/include/envs.h index 4650dc54..8e6e3731 100644 --- a/include/envs.h +++ b/include/envs.h @@ -59,7 +59,7 @@ const char *afl_environment_variables[] = { "AFL_NO_CPU_RED", "AFL_NO_FORKSRV", "AFL_NO_UI", - "AFL_NO_X86", // not really an env but we dont want to warn on it + "AFL_NO_X86", // not really an env but we dont want to warn on it "AFL_PATH", "AFL_PERFORMANCE_FILE", "AFL_PERSISTENT", diff --git a/llvm_mode/LLVMInsTrim.so.cc b/llvm_mode/LLVMInsTrim.so.cc index 08d3f68f..afe89ec7 100644 --- a/llvm_mode/LLVMInsTrim.so.cc +++ b/llvm_mode/LLVMInsTrim.so.cc @@ -382,19 +382,64 @@ struct InsTrim : public ModulePass { } - auto *EBB = &F.getEntryBlock(); - if (succ_begin(EBB) == succ_end(EBB)) { + // Bugfix #1: remove single block function instrumentation - MS.insert(EBB); - total_rs += 1; + for (BasicBlock &BB : F) { - } + if (MarkSetOpt && MS.find(&BB) == MS.end()) { - for (BasicBlock &BB : F) { + // Bugfix #2: instrument blocks that should be but InsTrim + // doesn't due to an algorithmic bug + int more_than_one = -1; + + for (pred_iterator PI = pred_begin(&BB), E = pred_end(&BB); PI != E; + ++PI) { + + BasicBlock *Pred = *PI; + int count = 0; + + if (more_than_one == -1) more_than_one = 0; + for (succ_iterator SI = succ_begin(Pred), E = succ_end(Pred); + SI != E; ++SI) { + + BasicBlock *Succ = *SI; + if (Succ != NULL) count++; + + } + + if (count > 1) more_than_one = 1; + + } + + if (more_than_one != 1) continue; + for (succ_iterator SI = succ_begin(&BB), E = succ_end(&BB); SI != E; + ++SI) { + + BasicBlock *Succ = *SI; + if (Succ != NULL && MS.find(Succ) == MS.end()) { + + int cnt = 0; + for (succ_iterator SI2 = succ_begin(Succ), E2 = succ_end(Succ); + SI2 != E2; ++SI2) { + + BasicBlock *Succ2 = *SI2; + if (Succ2 != NULL) cnt++; + + } - if (MS.find(&BB) == MS.end()) { continue; } - IRBuilder<> IRB(&*BB.getFirstInsertionPt()); - IRB.CreateStore(ConstantInt::get(Int32Ty, genLabel()), OldPrev); + if (cnt == 0) { + + // fprintf(stderr, "INSERT!\n"); + MS.insert(Succ); + total_rs += 1; + + } + + } + + } + + } } @@ -402,33 +447,24 @@ struct InsTrim : public ModulePass { for (BasicBlock &BB : F) { - auto PI = pred_begin(&BB); - auto PE = pred_end(&BB); if (MarkSetOpt && MS.find(&BB) == MS.end()) { continue; } IRBuilder<> IRB(&*BB.getFirstInsertionPt()); Value * L = NULL; - if (PI == PE) { - L = ConstantInt::get(Int32Ty, genLabel()); + auto *PN = PHINode::Create(Int32Ty, 0, "", &*BB.begin()); + DenseMap<BasicBlock *, unsigned> PredMap; + for (auto PI = pred_begin(&BB), PE = pred_end(&BB); PI != PE; ++PI) { - } else { - - auto *PN = PHINode::Create(Int32Ty, 0, "", &*BB.begin()); - DenseMap<BasicBlock *, unsigned> PredMap; - for (auto PI = pred_begin(&BB), PE = pred_end(&BB); PI != PE; ++PI) { - - BasicBlock *PBB = *PI; - auto It = PredMap.insert({PBB, genLabel()}); - unsigned Label = It.first->second; - PN->addIncoming(ConstantInt::get(Int32Ty, Label), PBB); - - } - - L = PN; + BasicBlock *PBB = *PI; + auto It = PredMap.insert({PBB, genLabel()}); + unsigned Label = It.first->second; + PN->addIncoming(ConstantInt::get(Int32Ty, Label), PBB); } + L = PN; + /* Load prev_loc */ LoadInst *PrevLoc = IRB.CreateLoad(OldPrev); PrevLoc->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); @@ -475,6 +511,11 @@ struct InsTrim : public ModulePass { IRB.CreateStore(Incr, MapPtrIdx) ->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); + // Bugfix #3: save the actually location ID to OldPrev + Value *Shr = IRB.CreateLShr(L, One); + IRB.CreateStore(Shr, OldPrev) + ->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); + total_instr++; } diff --git a/llvm_mode/afl-llvm-rt.o.c b/llvm_mode/afl-llvm-rt.o.c index 53852320..93b03bb2 100644 --- a/llvm_mode/afl-llvm-rt.o.c +++ b/llvm_mode/afl-llvm-rt.o.c @@ -129,7 +129,7 @@ static void __afl_map_shm(void) { __afl_area_ptr[0] = 1; } - + id_str = getenv(CMPLOG_SHM_ENV_VAR); if (id_str) { diff --git a/src/afl-as.c b/src/afl-as.c index acb026df..98bd3ff5 100644 --- a/src/afl-as.c +++ b/src/afl-as.c @@ -530,7 +530,8 @@ int main(int argc, char** argv) { "Rarely, when dealing with extremely complex projects, it may be " "advisable\n" - "to set AFL_INST_RATIO to a value less than 100 in order to reduce the\n" + "to set AFL_INST_RATIO to a value less than 100 in order to reduce " + "the\n" "odds of instrumenting every discovered branch.\n\n" "Environment variables used:\n" "AFL_AS: path to assembler to use for instrumented files\n" diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 0ddeeb8a..f1efe2df 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -3714,7 +3714,7 @@ pacemaker_fuzzing: case 1: if (temp_len < 2) break; - temp_len_puppet = UR((temp_len << 3) -1); + temp_len_puppet = UR((temp_len << 3) - 1); FLIP_BIT(out_buf, temp_len_puppet); FLIP_BIT(out_buf, temp_len_puppet + 1); MOpt_globals.cycles_v2[STAGE_FLIP2] += 1; @@ -3722,7 +3722,7 @@ pacemaker_fuzzing: case 2: if (temp_len < 2) break; - temp_len_puppet = UR((temp_len << 3) -3); + temp_len_puppet = UR((temp_len << 3) - 3); FLIP_BIT(out_buf, temp_len_puppet); FLIP_BIT(out_buf, temp_len_puppet + 1); FLIP_BIT(out_buf, temp_len_puppet + 2); diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 6cb229e3..19fc51f0 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -243,7 +243,7 @@ u8 cmp_extend_encoding(struct cmp_header* h, u64 pattern, u64 repl, u32 idx, if (SHAPE_BYTES(h->shape) == 8) { - if (its_len >= 8 && *buf_64 == pattern) {// && *o_buf_64 == pattern) { + if (its_len >= 8 && *buf_64 == pattern) { // && *o_buf_64 == pattern) { *buf_64 = repl; if (unlikely(its_fuzz(buf, len, status))) return 1; @@ -261,7 +261,8 @@ u8 cmp_extend_encoding(struct cmp_header* h, u64 pattern, u64 repl, u32 idx, if (SHAPE_BYTES(h->shape) == 4 || *status == 2) { - if (its_len >= 4 && *buf_32 == (u32)pattern) {// && *o_buf_32 == (u32)pattern) { + if (its_len >= 4 && + *buf_32 == (u32)pattern) { // && *o_buf_32 == (u32)pattern) { *buf_32 = (u32)repl; if (unlikely(its_fuzz(buf, len, status))) return 1; @@ -279,7 +280,8 @@ u8 cmp_extend_encoding(struct cmp_header* h, u64 pattern, u64 repl, u32 idx, if (SHAPE_BYTES(h->shape) == 2 || *status == 2) { - if (its_len >= 2 && *buf_16 == (u16)pattern) {// && *o_buf_16 == (u16)pattern) { + if (its_len >= 2 && + *buf_16 == (u16)pattern) { // && *o_buf_16 == (u16)pattern) { *buf_16 = (u16)repl; if (unlikely(its_fuzz(buf, len, status))) return 1; @@ -531,7 +533,7 @@ u8 input_to_state_stage(char** argv, u8* orig_buf, u8* buf, u32 len, stage_max += MIN(cmp_map->headers[k].hits, CMP_MAP_RTN_H); } - + for (k = 0; k < CMP_MAP_W; ++k) { if (!cmp_map->headers[k].hits) continue; |