fix caller/ctx change, support dlopen in afl-compiler-rt
MODIFY
docs/Changelog.md
docs/Changelog.md
@@ -14,6 +14,16 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
- afl-cc
- fixed a crash that can occur with ASAN + CMPLOG together plus
better support for unicode (thanks to @stbergmann for reporting!)
+ - handle erroneous setups in which multiple afl-compiler-rt are
+ compiled into the target. This now also supports dlopen instrumented
+ libs loaded before the forkserver.
+ - Renamed CTX to CALLER, added correct/real CTX implemenation to CLASSIC
+ - qemu_mode
+ - added AFL_QEMU_EXCLUDE_RANGES env by @realmadsci, thanks!
+ - if no new/updated checkout is wanted, build with:
+ NO_CHECKOUT=1 ./build_qemu_support.sh
+ - we no longer perform a "git drop"
+
### Version ++3.10c (release)
- Mac OS ARM64 support

MODIFY
instrumentation/LLVMInsTrim.so.cc
instrumentation/LLVMInsTrim.so.cc
@@ -135,7 +135,7 @@ struct InsTrim : public ModulePass {
unsigned int PrevLocSize = 0;
char * ngram_size_str = getenv("AFL_LLVM_NGRAM_SIZE");
if (!ngram_size_str) ngram_size_str = getenv("AFL_NGRAM_SIZE");
- char *ctx_str = getenv("AFL_LLVM_CTX");
+ char *caller_str = getenv("AFL_LLVM_CALLER");
#ifdef AFL_HAVE_VECTOR_INTRINSICS
unsigned int ngram_size = 0;
@@ -197,9 +197,9 @@ struct InsTrim : public ModulePass {
GlobalValue::ExternalLinkage, 0, "__afl_area_ptr");
GlobalVariable *AFLPrevLoc;
GlobalVariable *AFLContext = NULL;
- LoadInst * PrevCtx = NULL; // for CTX sensitive coverage
+ LoadInst * PrevCaller = NULL; // for CALLER sensitive coverage
- if (ctx_str)
+ if (caller_str)
#if defined(__ANDROID__) || defined(__HAIKU__)
AFLContext = new GlobalVariable(
M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_ctx");
@@ -398,10 +398,10 @@ struct InsTrim : public ModulePass {
unsigned int cur_loc;
// Context sensitive coverage
- if (ctx_str && &BB == &F.getEntryBlock()) {
+ if (caller_str && &BB == &F.getEntryBlock()) {
- PrevCtx = IRB.CreateLoad(AFLContext);
- PrevCtx->setMetadata(M.getMDKindID("nosanitize"),
+ PrevCaller = IRB.CreateLoad(AFLContext);
+ PrevCaller->setMetadata(M.getMDKindID("nosanitize"),
MDNode::get(C, None));
// does the function have calls? and is any of the calls larger than
@@ -441,7 +441,7 @@ struct InsTrim : public ModulePass {
}
- } // END of ctx_str
+ } // END of caller_str
if (MarkSetOpt && MS.find(&BB) == MS.end()) { continue; }
@@ -485,9 +485,9 @@ struct InsTrim : public ModulePass {
#endif
PrevLocTrans = IRB.CreateZExt(PrevLoc, IRB.getInt32Ty());
- if (ctx_str)
+ if (caller_str)
PrevLocTrans =
- IRB.CreateZExt(IRB.CreateXor(PrevLocTrans, PrevCtx), Int32Ty);
+ IRB.CreateZExt(IRB.CreateXor(PrevLocTrans, PrevCaller), Int32Ty);
/* Load SHM pointer */
LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr);
@@ -535,16 +535,17 @@ struct InsTrim : public ModulePass {
IRB.CreateStore(Incr, MapPtrIdx)
->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
- if (ctx_str && has_calls) {
+ if (caller_str && has_calls) {
- // in CTX mode we have to restore the original context for the
+ // in CALLER mode we have to restore the original context for the
// caller - she might be calling other functions which need the
- // correct CTX
+ // correct CALLER
Instruction *Inst = BB.getTerminator();
if (isa<ReturnInst>(Inst) || isa<ResumeInst>(Inst)) {
IRBuilder<> Post_IRB(Inst);
- StoreInst * RestoreCtx = Post_IRB.CreateStore(PrevCtx, AFLContext);
+ StoreInst * RestoreCtx =
+ Post_IRB.CreateStore(PrevCaller, AFLContext);
RestoreCtx->setMetadata(M.getMDKindID("nosanitize"),
MDNode::get(C, None));

MODIFY
instrumentation/afl-compiler-rt.o.c
instrumentation/afl-compiler-rt.o.c
@@ -123,6 +123,17 @@ static u8 is_persistent;
static u8 _is_sancov;
+/* Debug? */
+
+static u32 __afl_debug;
+
+/* Already initialized markers */
+
+static u32 __afl_already_initialized_shm;
+static u32 __afl_already_initialized_forkserver;
+static u32 __afl_already_initialized_first;
+static u32 __afl_already_initialized_second;
+
/* Dummy pipe for area_is_valid() */
static int __afl_dummy_fd[2] = {2, 2};
@@ -176,7 +187,7 @@ static void __afl_map_shm_fuzz() {
char *id_str = getenv(SHM_FUZZ_ENV_VAR);
- if (getenv("AFL_DEBUG")) {
+ if (__afl_debug) {
fprintf(stderr, "DEBUG: fuzzcase shmem %s\n", id_str ? id_str : "none");
@@ -222,7 +233,7 @@ static void __afl_map_shm_fuzz() {
__afl_fuzz_len = (u32 *)map;
__afl_fuzz_ptr = map + sizeof(u32);
- if (getenv("AFL_DEBUG")) {
+ if (__afl_debug) {
fprintf(stderr, "DEBUG: successfully got fuzzing shared memory\n");
@@ -242,7 +253,6 @@ static void __afl_map_shm_fuzz() {
static void __afl_map_shm(void) {
- static u32 __afl_already_initialized_shm = 0;
if (__afl_already_initialized_shm) return;
__afl_already_initialized_shm = 1;
@@ -303,7 +313,7 @@ static void __afl_map_shm(void) {
early-stage __afl_area_initial region that is needed to allow some really
hacky .init code to work correctly in projects such as OpenSSL. */
- if (getenv("AFL_DEBUG"))
+ if (__afl_debug)
fprintf(stderr,
"DEBUG: id_str %s, __afl_area_ptr %p, __afl_area_initial %p, "
"__afl_map_addr 0x%llx, MAP_SIZE %u, __afl_final_loc %u, "
@@ -359,17 +369,18 @@ static void __afl_map_shm(void) {
}
+ close(shm_fd);
+
if (shm_base == MAP_FAILED) {
- close(shm_fd);
shm_fd = -1;
-
fprintf(stderr, "mmap() failed\n");
+ perror("mmap for map");
+
if (__afl_map_addr)
send_forkserver_error(FS_ERROR_MAP_ADDR);
else
send_forkserver_error(FS_ERROR_MMAP);
- perror("mmap for map");
exit(2);
@@ -476,7 +487,7 @@ static void __afl_map_shm(void) {
id_str = getenv(CMPLOG_SHM_ENV_VAR);
- if (getenv("AFL_DEBUG")) {
+ if (__afl_debug) {
fprintf(stderr, "DEBUG: cmplog id_str %s\n",
id_str == NULL ? "<null>" : id_str);
@@ -541,6 +552,58 @@ static void __afl_map_shm(void) {
}
+/* unmap SHM. */
+
+static void __afl_unmap_shm(void) {
+
+ if (!__afl_already_initialized_shm) return;
+
+ char *id_str = getenv(SHM_ENV_VAR);
+
+ if (id_str) {
+
+#ifdef USEMMAP
+
+ munmap((void *)__afl_area_ptr, __afl_map_size);
+
+#else
+
+ shmdt((void *)__afl_area_ptr);
+
+#endif
+
+ } else if ((!__afl_area_ptr || __afl_area_ptr == __afl_area_initial) &&
+
+ __afl_map_addr) {
+
+ munmap((void *)__afl_map_addr, __afl_map_size);
+
+ }
+
+ __afl_area_ptr = __afl_area_ptr_dummy;
+
+ id_str = getenv(CMPLOG_SHM_ENV_VAR);
+
+ if (id_str) {
+
+#ifdef USEMMAP
+
+ munmap((void *)__afl_cmp_map, __afl_map_size);
+
+#else
+
+ shmdt((void *)__afl_cmp_map);
+
+#endif
+
+ __afl_cmp_map = NULL;
+
+ }
+
+ __afl_already_initialized_shm = 0;
+
+}
+
#ifdef __linux__
static void __afl_start_snapshots(void) {
@@ -569,7 +632,7 @@ static void __afl_start_snapshots(void) {
if (read(FORKSRV_FD, &was_killed, 4) != 4) { _exit(1); }
- if (getenv("AFL_DEBUG")) {
+ if (__afl_debug) {
fprintf(stderr, "target forkserver recv: %08x\n", was_killed);
@@ -746,7 +809,6 @@ static void __afl_start_snapshots(void) {
static void __afl_start_forkserver(void) {
- static u32 __afl_already_initialized_forkserver = 0;
if (__afl_already_initialized_forkserver) return;
__afl_already_initialized_forkserver = 1;
@@ -800,7 +862,7 @@ static void __afl_start_forkserver(void) {
if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1);
- if (getenv("AFL_DEBUG")) {
+ if (__afl_debug) {
fprintf(stderr, "target forkserver recv: %08x\n", was_killed);
@@ -1035,7 +1097,7 @@ void __afl_manual_init(void) {
__afl_sharedmem_fuzzing = 0;
if (__afl_area_ptr == NULL) __afl_area_ptr = __afl_area_ptr_dummy;
- if (getenv("AFL_DEBUG"))
+ if (__afl_debug)
fprintf(stderr,
"DEBUG: disabled instrumentation because of "
"AFL_DISABLE_LLVM_INSTRUMENTATION\n");
@@ -1079,10 +1141,11 @@ __attribute__((constructor(CTOR_PRIO))) void __afl_auto_early(void) {
__attribute__((constructor(1))) void __afl_auto_second(void) {
- static u32 __afl_already_initialized_second = 0;
if (__afl_already_initialized_second) return;
__afl_already_initialized_second = 1;
+ if (getenv("AFL_DEBUG")) { __afl_debug = 1; }
+
if (getenv("AFL_DISABLE_LLVM_INSTRUMENTATION")) return;
u8 *ptr;
@@ -1114,7 +1177,6 @@ __attribute__((constructor(1))) void __afl_auto_second(void) {
__attribute__((constructor(0))) void __afl_auto_first(void) {
- static u32 __afl_already_initialized_first = 0;
if (__afl_already_initialized_first) return;
__afl_already_initialized_first = 1;
@@ -1198,7 +1260,7 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
_is_sancov = 1;
- if (getenv("AFL_DEBUG")) {
+ if (__afl_debug) {
fprintf(stderr,
"Running __sanitizer_cov_trace_pc_guard_init: %p-%p (%lu edges)\n",
@@ -1235,6 +1297,28 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
}
+ if (__afl_debug) {
+
+ fprintf(stderr,
+ "Done __sanitizer_cov_trace_pc_guard_init: __afl_final_loc = %u\n",
+ __afl_final_loc);
+
+ }
+
+ if (__afl_already_initialized_shm && __afl_final_loc > __afl_map_size) {
+
+ if (__afl_debug) {
+
+ fprintf(stderr, "Reinit shm necessary (+%u)\n",
+ __afl_final_loc - __afl_map_size);
+
+ }
+
+ __afl_unmap_shm();
+ __afl_map_shm();
+
+ }
+
}
///// CmpLog instrumentation

MODIFY
src/afl-cc.c
src/afl-cc.c
@@ -89,7 +89,7 @@ char instrument_mode_string[18][18] = {
"GCC",
"CLANG",
"CTX",
- "",
+ "CALLER",
"",
"",
"",
@@ -1514,12 +1514,13 @@ int main(int argc, char **argv, char **envp) {
" CLASSIC %s no yes module yes yes "
"yes\n"
" - NORMAL\n"
+ " - CALLER\n"
" - CTX\n"
" - NGRAM-{2-16}\n"
" INSTRIM no yes module yes yes "
" yes\n"
" - NORMAL\n"
- " - CTX\n"
+ " - CALLER\n"
" - NGRAM-{2-16}\n"
" [GCC_PLUGIN] gcc plugin: %s%s\n"
" CLASSIC DEFAULT no yes no no no "
@@ -1566,7 +1567,10 @@ int main(int argc, char **argv, char **envp) {
NATIVE_MSG
" CLASSIC: decision target instrumentation (README.llvm.md)\n"
- " CTX: CLASSIC + callee context (instrumentation/README.ctx.md)\n"
+ " CALLER: CLASSIC + single callee context "
+ "(instrumentation/README.ctx.md)\n"
+ " CTX: CLASSIC + full callee context "
+ "(instrumentation/README.ctx.md)\n"
" NGRAM-x: CLASSIC + previous path "
"((instrumentation/README.ngram.md)\n"
" INSTRIM: Dominator tree (for LLVM <= 6.0) "
@@ -1660,15 +1664,17 @@ int main(int argc, char **argv, char **envp) {
" AFL_LLVM_CMPLOG: log operands of comparisons (RedQueen "
"mutator)\n"
" AFL_LLVM_INSTRUMENT: set instrumentation mode:\n"
- " CLASSIC, INSTRIM, PCGUARD, LTO, GCC, CLANG, CTX, NGRAM-2 ... "
- "NGRAM-16\n"
+ " CLASSIC, INSTRIM, PCGUARD, LTO, GCC, CLANG, CALLER, CTX, "
+ "NGRAM-2 ..-16\n"
" You can also use the old environment variables instead:\n"
" AFL_LLVM_USE_TRACE_PC: use LLVM trace-pc-guard instrumentation\n"
" AFL_LLVM_INSTRIM: use light weight instrumentation InsTrim\n"
" AFL_LLVM_INSTRIM_LOOPHEAD: optimize loop tracing for speed "
"(option to INSTRIM)\n"
- " AFL_LLVM_CTX: use context sensitive coverage (for CLASSIC and "
- "INSTRIM)\n"
+ " AFL_LLVM_CALLER: use single context sensitive coverage (for "
+ "CLASSIC)\n"
+ " AFL_LLVM_CTX: use full context sensitive coverage (for "
+ "CLASSIC)\n"
" AFL_LLVM_NGRAM_SIZE: use ngram prev_loc count coverage (for "
"CLASSIC & INSTRIM)\n");
@@ -1814,11 +1820,14 @@ int main(int argc, char **argv, char **envp) {
"(requires LLVM 11 or higher)");
#endif
- if (instrument_opt_mode && instrument_mode != INSTRUMENT_CLASSIC &&
- instrument_mode != INSTRUMENT_CFG)
+ if (instrument_opt_mode && instrument_mode == INSTRUMENT_CFG &&
+ instrument_opt_mode & INSTRUMENT_OPT_CTX)
+ FATAL("CFG instrumentation mode supports NGRAM and CALLER, but not CTX.");
+ else if (instrument_opt_mode && instrument_mode != INSTRUMENT_CLASSIC)
+ // we will drop CFG/INSTRIM in the future so do not advertise
FATAL(
- "CTX and NGRAM instrumentation options can only be used with LLVM and "
- "CFG or CLASSIC instrumentation modes!");
+ "CALLER, CTX and NGRAM instrumentation options can only be used with "
+ "the LLVM CLASSIC instrumentation mode.");
if (getenv("AFL_LLVM_SKIP_NEVERZERO") && getenv("AFL_LLVM_NOT_ZERO"))
FATAL(

fix caller/ctx change, support dlopen in afl-compiler-rt