forked from mirrors/gecko-dev
847 lines
28 KiB
Diff
847 lines
28 KiB
Diff
From 705d24fb3ad80af5544b43ade6927d24a9367a69 Mon Sep 17 00:00:00 2001
|
|
From: "Christian Holler (:decoder)" <choller@mozilla.com>
|
|
Date: Thu, 14 Oct 2021 20:59:27 +0200
|
|
Subject: [PATCH 01/10] Initial commit for compiler, preload and userspace
|
|
tools
|
|
|
|
---
|
|
config.h | 2 +
|
|
llvm_mode/Makefile | 20 +++------
|
|
llvm_mode/afl-llvm-pass.so.cc | 3 +-
|
|
llvm_mode/afl-llvm-rt.o.c | 83 ++++++++++++++++++++++++++++++++---
|
|
4 files changed, 87 insertions(+), 21 deletions(-)
|
|
|
|
diff --git a/config.h b/config.h
|
|
index ea6aac4..b21298d 100644
|
|
--- a/config.h
|
|
+++ b/config.h
|
|
@@ -328,6 +328,8 @@
|
|
#define MAP_SIZE_POW2 16
|
|
#define MAP_SIZE (1 << MAP_SIZE_POW2)
|
|
|
|
+#define STATE_STR_LEN 12
|
|
+
|
|
/* Maximum allocator request size (keep well under INT_MAX): */
|
|
|
|
#define MAX_ALLOC 0x40000000
|
|
diff --git a/llvm_mode/Makefile b/llvm_mode/Makefile
|
|
index 7617f91..823e959 100644
|
|
--- a/llvm_mode/Makefile
|
|
+++ b/llvm_mode/Makefile
|
|
@@ -23,6 +23,7 @@ BIN_PATH = $(PREFIX)/bin
|
|
VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2)
|
|
|
|
LLVM_CONFIG ?= llvm-config
|
|
+LLVM_BINPATH = $(shell $(LLVM_CONFIG) --bindir)
|
|
|
|
CFLAGS ?= -O3 -funroll-loops
|
|
CFLAGS += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign \
|
|
@@ -51,8 +52,8 @@ endif
|
|
# probably better.
|
|
|
|
ifeq "$(origin CC)" "default"
|
|
- CC = clang
|
|
- CXX = clang++
|
|
+ CC = $(LLVM_BINPATH)/clang
|
|
+ CXX = $(LLVM_BINPATH)/clang++
|
|
endif
|
|
|
|
ifndef AFL_TRACE_PC
|
|
@@ -61,7 +62,7 @@ else
|
|
PROGS = ../afl-clang-fast ../afl-llvm-rt.o ../afl-llvm-rt-32.o ../afl-llvm-rt-64.o
|
|
endif
|
|
|
|
-all: test_deps $(PROGS) test_build all_done
|
|
+all: test_deps $(PROGS) all_done
|
|
|
|
test_deps:
|
|
ifndef AFL_TRACE_PC
|
|
@@ -94,18 +95,7 @@ endif
|
|
@printf "[*] Building 64-bit variant of the runtime (-m64)... "
|
|
@$(CC) $(CFLAGS) -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
|
|
|
|
-test_build: $(PROGS)
|
|
- @echo "[*] Testing the CC wrapper and instrumentation output..."
|
|
- unset AFL_USE_ASAN AFL_USE_MSAN AFL_INST_RATIO; AFL_QUIET=1 AFL_PATH=. AFL_CC=$(CC) ../afl-clang-fast $(CFLAGS) ../test-instr.c -o test-instr $(LDFLAGS)
|
|
-# Use /dev/null to avoid problems with optimization messing up expected
|
|
-# branches. See https://github.com/google/AFL/issues/30.
|
|
- ../afl-showmap -m none -q -o .test-instr0 ./test-instr < /dev/null
|
|
- echo 1 | ../afl-showmap -m none -q -o .test-instr1 ./test-instr
|
|
- @rm -f test-instr
|
|
- @cmp -s .test-instr0 .test-instr1; DR="$$?"; rm -f .test-instr0 .test-instr1; if [ "$$DR" = "0" ]; then echo; echo "Oops, the instrumentation does not seem to be behaving correctly!"; echo; echo "Please ping <lcamtuf@google.com> to troubleshoot the issue."; echo; exit 1; fi
|
|
- @echo "[+] All right, the instrumentation seems to be working!"
|
|
-
|
|
-all_done: test_build
|
|
+all_done:
|
|
@echo "[+] All done! You can now use '../afl-clang-fast' to compile programs."
|
|
|
|
.NOTPARALLEL: clean
|
|
diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc
|
|
index 154a5db..0bfbfdf 100644
|
|
--- a/llvm_mode/afl-llvm-pass.so.cc
|
|
+++ b/llvm_mode/afl-llvm-pass.so.cc
|
|
@@ -105,7 +105,8 @@ bool AFLCoverage::runOnModule(Module &M) {
|
|
|
|
GlobalVariable *AFLMapPtr =
|
|
new GlobalVariable(M, PointerType::get(Int8Ty, 0), false,
|
|
- GlobalValue::ExternalLinkage, 0, "__afl_area_ptr");
|
|
+ GlobalVariable::ExternalLinkage, 0, "__afl_area_ptr",
|
|
+ 0, GlobalVariable::GeneralDynamicTLSModel, 0, false);
|
|
|
|
GlobalVariable *AFLPrevLoc = new GlobalVariable(
|
|
M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_loc",
|
|
diff --git a/llvm_mode/afl-llvm-rt.o.c b/llvm_mode/afl-llvm-rt.o.c
|
|
index 60475c9..536adb9 100644
|
|
--- a/llvm_mode/afl-llvm-rt.o.c
|
|
+++ b/llvm_mode/afl-llvm-rt.o.c
|
|
@@ -41,6 +41,10 @@
|
|
#include <sys/shm.h>
|
|
#include <sys/wait.h>
|
|
#include <sys/types.h>
|
|
+#include <syscall.h>
|
|
+
|
|
+#define gettid() ((pid_t)syscall(SYS_gettid))
|
|
+
|
|
|
|
/* This is a somewhat ugly hack for the experimental 'trace-pc-guard' mode.
|
|
Basically, we need to make sure that the forkserver is initialized after
|
|
@@ -53,12 +57,23 @@
|
|
#endif /* ^USE_TRACE_PC */
|
|
|
|
|
|
+void enable_afl_tracing(void);
|
|
+void disable_afl_tracing(void);
|
|
+void init_afl_tracing(void);
|
|
+
|
|
+
|
|
/* Globals needed by the injected instrumentation. The __afl_area_initial region
|
|
is used for instrumentation output before __afl_map_shm() has a chance to run.
|
|
It will end up as .comm, so it shouldn't be too wasteful. */
|
|
|
|
+#define FIREFOX_CONTROL_AREA_ADDR 0x100000
|
|
+
|
|
+u8*** __firefox_afl_control_areas = NULL;
|
|
+
|
|
u8 __afl_area_initial[MAP_SIZE];
|
|
-u8* __afl_area_ptr = __afl_area_initial;
|
|
+__thread u8* __afl_area_ptr = __afl_area_initial;
|
|
+
|
|
+u8* __afl_area_ptr_pre = __afl_area_initial;
|
|
|
|
__thread u32 __afl_prev_loc;
|
|
|
|
@@ -82,17 +97,15 @@ static void __afl_map_shm(void) {
|
|
|
|
u32 shm_id = atoi(id_str);
|
|
|
|
- __afl_area_ptr = shmat(shm_id, NULL, 0);
|
|
+ __afl_area_ptr_pre = shmat(shm_id, NULL, 0);
|
|
|
|
/* Whooooops. */
|
|
|
|
- if (__afl_area_ptr == (void *)-1) _exit(1);
|
|
+ if (__afl_area_ptr_pre == (void *)-1) _exit(1);
|
|
|
|
/* Write something into the bitmap so that even with low AFL_INST_RATIO,
|
|
our parent doesn't give up on us. */
|
|
|
|
- __afl_area_ptr[0] = 1;
|
|
-
|
|
}
|
|
|
|
}
|
|
@@ -256,6 +269,16 @@ void __afl_manual_init(void) {
|
|
|
|
__attribute__((constructor(CONST_PRIO))) void __afl_auto_init(void) {
|
|
|
|
+ __firefox_afl_control_areas = mmap((void*)FIREFOX_CONTROL_AREA_ADDR, 0x1000, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED , 0, 0);
|
|
+ if(__firefox_afl_control_areas == (void*)-1){
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ __firefox_afl_control_areas[0] = (u8**) enable_afl_tracing;
|
|
+ __firefox_afl_control_areas[1] = (u8**) disable_afl_tracing;
|
|
+ __firefox_afl_control_areas[2] = (u8**) init_afl_tracing;
|
|
+ __firefox_afl_control_areas[3] = (u8**) 1337;
|
|
+
|
|
is_persistent = !!getenv(PERSIST_ENV_VAR);
|
|
|
|
if (getenv(DEFER_ENV_VAR)) return;
|
|
@@ -310,5 +333,55 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t* start, uint32_t* stop) {
|
|
start++;
|
|
|
|
}
|
|
+}
|
|
+
|
|
+void enable_afl_tracing(void){
|
|
+ if(__afl_area_ptr == __afl_area_initial && __afl_area_ptr_pre != __afl_area_initial){
|
|
+ __afl_area_ptr = __afl_area_ptr_pre;
|
|
+ }
|
|
+}
|
|
+
|
|
+void disable_afl_tracing(void){
|
|
+ if(__afl_area_ptr != __afl_area_initial){
|
|
+ __afl_area_ptr = __afl_area_initial;
|
|
+ }
|
|
+}
|
|
+
|
|
+void init_afl_tracing(){
|
|
+ __afl_area_ptr_pre[0] = 1;
|
|
+}
|
|
+
|
|
+void print_afl_bitmap(void){
|
|
+ if(__afl_area_ptr_pre == __afl_area_initial){
|
|
+ return;
|
|
+ }
|
|
+ void* data = __afl_area_ptr_pre;
|
|
+ int size = 2 << 15;
|
|
+ char ascii[17];
|
|
+ size_t i, j;
|
|
+ ascii[16] = '\0';
|
|
+ for (i = 0; i < size; ++i) {
|
|
+ printf("%02X ", ((unsigned char*)data)[i]);
|
|
+ if (((unsigned char*)data)[i] >= ' ' && ((unsigned char*)data)[i] <= '~') {
|
|
+ ascii[i % 16] = ((unsigned char*)data)[i];
|
|
+ } else {
|
|
+ ascii[i % 16] = '.';
|
|
+ }
|
|
+ if ((i+1) % 8 == 0 || i+1 == size) {
|
|
+ printf(" ");
|
|
+ if ((i+1) % 16 == 0) {
|
|
+ printf("| %s \n", ascii);
|
|
+ } else if (i+1 == size) {
|
|
+ ascii[(i+1) % 16] = '\0';
|
|
+ if ((i+1) % 16 <= 8) {
|
|
+ printf(" ");
|
|
+ }
|
|
+ for (j = (i+1) % 16; j < 16; ++j) {
|
|
+ printf(" ");
|
|
+ }
|
|
+ printf("| %s \n", ascii);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
|
|
}
|
|
--
|
|
2.37.1
|
|
|
|
From 003221dd9fec462177445040c7fa57c09397c684 Mon Sep 17 00:00:00 2001
|
|
From: "Christian Holler (:decoder)" <choller@mozilla.com>
|
|
Date: Fri, 15 Oct 2021 11:55:02 +0200
|
|
Subject: [PATCH 02/10] [compiler] Add selective instrumentation through
|
|
AFL_INST_FILTER
|
|
|
|
---
|
|
llvm_mode/afl-clang-fast.c | 57 +++++++++++++++++++++++++++++++++++++-
|
|
1 file changed, 56 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c
|
|
index c154e01..b5aa521 100644
|
|
--- a/llvm_mode/afl-clang-fast.c
|
|
+++ b/llvm_mode/afl-clang-fast.c
|
|
@@ -29,6 +29,9 @@
|
|
*/
|
|
|
|
#define AFL_MAIN
|
|
+#ifndef _GNU_SOURCE
|
|
+#define _GNU_SOURCE
|
|
+#endif
|
|
|
|
#include "../config.h"
|
|
#include "../types.h"
|
|
@@ -39,6 +42,7 @@
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
+#include <linux/limits.h>
|
|
|
|
static u8* obj_path; /* Path to runtime libraries */
|
|
static u8** cc_params; /* Parameters passed to the real CC */
|
|
@@ -119,13 +123,63 @@ static void edit_params(u32 argc, char** argv) {
|
|
cc_params[0] = alt_cc ? alt_cc : (u8*)"clang";
|
|
}
|
|
|
|
+#define CPP_SUFF ".cpp"
|
|
+#define CPP_SLEN (sizeof(CPP_SUFF)-1)
|
|
+#define C_SUFF ".c"
|
|
+#define C_SLEN (sizeof(C_SUFF)-1)
|
|
+ u8 should_instrument = 1;
|
|
+
|
|
+ u8* instfilter = getenv("AFL_INST_FILTER");
|
|
+
|
|
+ if (instfilter) {
|
|
+
|
|
+ should_instrument = 0;
|
|
+
|
|
+ char cwd [PATH_MAX];
|
|
+ getcwd(cwd, sizeof(cwd));
|
|
+
|
|
+ for (u32 argi = 0; argi < argc; ++argi) {
|
|
+ u8 is_source = 0;
|
|
+ u32 arglen = strlen(argv[argi]);
|
|
+ //SAYF("Checking: %s\n", argv[argi]);
|
|
+ if (arglen > CPP_SLEN) {
|
|
+ if (!memcmp(argv[argi] + arglen - CPP_SLEN, CPP_SUFF, CPP_SLEN)) {
|
|
+ is_source = 1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!is_source && arglen > C_SLEN) {
|
|
+ if (!memcmp(argv[argi] + arglen - C_SLEN, C_SUFF, C_SLEN)) {
|
|
+ is_source = 1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (is_source) {
|
|
+ //SAYF("This is a source file: %s\n", argv[argi]);
|
|
+ char relpath [PATH_MAX];
|
|
+ strcat(relpath, cwd);
|
|
+ strcat(relpath, "/");
|
|
+ strcat(relpath, argv[argi]);
|
|
+ char abspath [PATH_MAX];
|
|
+ if (realpath(relpath, abspath)) {
|
|
+ if (strcasestr(abspath, instfilter)) {
|
|
+ should_instrument = 1;
|
|
+ SAYF("Instrumenting file %s\n", argv[argi]);
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
/* There are two ways to compile afl-clang-fast. In the traditional mode, we
|
|
use afl-llvm-pass.so to inject instrumentation. In the experimental
|
|
'trace-pc-guard' mode, we use native LLVM instrumentation callbacks
|
|
instead. The latter is a very recent addition - see:
|
|
|
|
http://clang.llvm.org/docs/SanitizerCoverage.html#tracing-pcs-with-guards */
|
|
-
|
|
+if (should_instrument) {
|
|
#ifdef USE_TRACE_PC
|
|
cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
|
|
cc_params[cc_par_cnt++] = "-mllvm";
|
|
@@ -136,6 +190,7 @@ static void edit_params(u32 argc, char** argv) {
|
|
cc_params[cc_par_cnt++] = "-Xclang";
|
|
cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-pass.so", obj_path);
|
|
#endif /* ^USE_TRACE_PC */
|
|
+}
|
|
|
|
cc_params[cc_par_cnt++] = "-Qunused-arguments";
|
|
|
|
--
|
|
2.37.1
|
|
|
|
From 3e126e0f9bf21c32cb650d49f5f088b213538854 Mon Sep 17 00:00:00 2001
|
|
From: "Christian Holler (:decoder)" <choller@mozilla.com>
|
|
Date: Tue, 22 Feb 2022 16:44:27 +0100
|
|
Subject: [PATCH 03/10] Fix AFL compiler to ignore wasm-compiled code
|
|
|
|
---
|
|
llvm_mode/afl-clang-fast.c | 1 +
|
|
1 file changed, 1 insertion(+)
|
|
|
|
diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c
|
|
index 226ee36..6d4171c 100644
|
|
--- a/llvm_mode/afl-clang-fast.c
|
|
+++ b/llvm_mode/afl-clang-fast.c
|
|
@@ -213,6 +213,7 @@ if (should_instrument) {
|
|
if (strstr(cur, "FORTIFY_SOURCE")) fortify_set = 1;
|
|
|
|
if (!strcmp(cur, "-shared")) maybe_linking = 0;
|
|
+ if (!strcmp(cur, "--target=wasm32-wasi")) maybe_linking = 0;
|
|
|
|
if (!strcmp(cur, "-Wl,-z,defs") ||
|
|
!strcmp(cur, "-Wl,--no-undefined")) continue;
|
|
--
|
|
2.37.1
|
|
|
|
From e2e269e9d00b47cc6a139045688f32b26d30fc85 Mon Sep 17 00:00:00 2001
|
|
From: "Christian Holler (:decoder)" <choller@mozilla.com>
|
|
Date: Thu, 9 Jun 2022 10:20:34 +0200
|
|
Subject: [PATCH 04/10] Update IRBuilder calls to LLVM 14 API
|
|
|
|
---
|
|
llvm_mode/afl-llvm-pass.so.cc | 10 ++++++----
|
|
1 file changed, 6 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc
|
|
index 0bfbfdf..203cffa 100644
|
|
--- a/llvm_mode/afl-llvm-pass.so.cc
|
|
+++ b/llvm_mode/afl-llvm-pass.so.cc
|
|
@@ -38,12 +38,14 @@
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
|
|
+#include "llvm/Pass.h"
|
|
#include "llvm/ADT/Statistic.h"
|
|
#include "llvm/IR/IRBuilder.h"
|
|
#include "llvm/IR/LegacyPassManager.h"
|
|
#include "llvm/IR/Module.h"
|
|
#include "llvm/Support/Debug.h"
|
|
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
|
|
+#include "llvm/Passes/OptimizationLevel.h"
|
|
|
|
using namespace llvm;
|
|
|
|
@@ -132,20 +134,20 @@ bool AFLCoverage::runOnModule(Module &M) {
|
|
|
|
/* Load prev_loc */
|
|
|
|
- LoadInst *PrevLoc = IRB.CreateLoad(AFLPrevLoc);
|
|
+ LoadInst *PrevLoc = IRB.CreateLoad(IRB.getInt32Ty(), AFLPrevLoc);
|
|
PrevLoc->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
|
|
Value *PrevLocCasted = IRB.CreateZExt(PrevLoc, IRB.getInt32Ty());
|
|
|
|
/* Load SHM pointer */
|
|
|
|
- LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr);
|
|
+ LoadInst *MapPtr = IRB.CreateLoad(PointerType::get(Int8Ty, 0), AFLMapPtr);
|
|
MapPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
|
|
Value *MapPtrIdx =
|
|
- IRB.CreateGEP(MapPtr, IRB.CreateXor(PrevLocCasted, CurLoc));
|
|
+ IRB.CreateGEP(Int8Ty, MapPtr, IRB.CreateXor(PrevLocCasted, CurLoc));
|
|
|
|
/* Update bitmap */
|
|
|
|
- LoadInst *Counter = IRB.CreateLoad(MapPtrIdx);
|
|
+ LoadInst *Counter = IRB.CreateLoad(IRB.getInt8Ty(), MapPtrIdx);
|
|
Counter->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
|
|
Value *Incr = IRB.CreateAdd(Counter, ConstantInt::get(Int8Ty, 1));
|
|
IRB.CreateStore(Incr, MapPtrIdx)
|
|
--
|
|
2.37.1
|
|
|
|
From be3f79c5b472e5a8a06266d7a74ebb162b3d8cba Mon Sep 17 00:00:00 2001
|
|
From: "Christian Holler (:decoder)" <choller@mozilla.com>
|
|
Date: Thu, 9 Jun 2022 11:37:44 +0200
|
|
Subject: [PATCH 05/10] Switch AFLCoverage pass to new pass manager
|
|
|
|
---
|
|
llvm_mode/afl-clang-fast.c | 7 ++---
|
|
llvm_mode/afl-llvm-pass.so.cc | 58 +++++++++++++++++------------------
|
|
2 files changed, 31 insertions(+), 34 deletions(-)
|
|
|
|
diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c
|
|
index 6d4171c..5e00286 100644
|
|
--- a/llvm_mode/afl-clang-fast.c
|
|
+++ b/llvm_mode/afl-clang-fast.c
|
|
@@ -178,14 +178,12 @@ static void edit_params(u32 argc, char** argv) {
|
|
http://clang.llvm.org/docs/SanitizerCoverage.html#tracing-pcs-with-guards */
|
|
if (should_instrument) {
|
|
#ifdef USE_TRACE_PC
|
|
+ #error "unsupported"
|
|
cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
|
|
cc_params[cc_par_cnt++] = "-mllvm";
|
|
cc_params[cc_par_cnt++] = "-sanitizer-coverage-block-threshold=0";
|
|
#else
|
|
- cc_params[cc_par_cnt++] = "-Xclang";
|
|
- cc_params[cc_par_cnt++] = "-load";
|
|
- cc_params[cc_par_cnt++] = "-Xclang";
|
|
- cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-pass.so", obj_path);
|
|
+ cc_params[cc_par_cnt++] = alloc_printf("-fpass-plugin=%s/afl-llvm-pass.so", obj_path);
|
|
#endif /* ^USE_TRACE_PC */
|
|
}
|
|
|
|
diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc
|
|
index 203cffa..1483943 100644
|
|
--- a/llvm_mode/afl-llvm-pass.so.cc
|
|
+++ b/llvm_mode/afl-llvm-pass.so.cc
|
|
@@ -41,44 +41,57 @@
|
|
#include "llvm/Pass.h"
|
|
#include "llvm/ADT/Statistic.h"
|
|
#include "llvm/IR/IRBuilder.h"
|
|
-#include "llvm/IR/LegacyPassManager.h"
|
|
#include "llvm/IR/Module.h"
|
|
-#include "llvm/Support/Debug.h"
|
|
-#include "llvm/Transforms/IPO/PassManagerBuilder.h"
|
|
+#include "llvm/IR/PassManager.h"
|
|
#include "llvm/Passes/OptimizationLevel.h"
|
|
+#include "llvm/Passes/PassPlugin.h"
|
|
+#include "llvm/Passes/PassBuilder.h"
|
|
+#include "llvm/Support/Debug.h"
|
|
|
|
using namespace llvm;
|
|
|
|
namespace {
|
|
|
|
- class AFLCoverage : public ModulePass {
|
|
+ class AFLCoverage : public PassInfoMixin<AFLCoverage> {
|
|
|
|
public:
|
|
|
|
- static char ID;
|
|
- AFLCoverage() : ModulePass(ID) { }
|
|
-
|
|
- bool runOnModule(Module &M) override;
|
|
-
|
|
- // StringRef getPassName() const override {
|
|
- // return "American Fuzzy Lop Instrumentation";
|
|
- // }
|
|
+ AFLCoverage() { }
|
|
|
|
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
|
|
};
|
|
|
|
}
|
|
|
|
+extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
|
|
+llvmGetPassPluginInfo() {
|
|
+
|
|
+ return {LLVM_PLUGIN_API_VERSION, "AFLCoverage", "v0.1",
|
|
+ /* lambda to insert our pass into the pass pipeline. */
|
|
+ [](PassBuilder &PB) {
|
|
|
|
-char AFLCoverage::ID = 0;
|
|
+ #if LLVM_VERSION_MAJOR <= 13
|
|
+ using OptimizationLevel = typename PassBuilder::OptimizationLevel;
|
|
+ #endif
|
|
+ PB.registerOptimizerLastEPCallback(
|
|
+ [](ModulePassManager &MPM, OptimizationLevel OL) {
|
|
|
|
+ MPM.addPass(AFLCoverage());
|
|
|
|
-bool AFLCoverage::runOnModule(Module &M) {
|
|
+ });
|
|
+ }};
|
|
+
|
|
+}
|
|
+
|
|
+PreservedAnalyses AFLCoverage::run(Module &M, ModuleAnalysisManager &MAM) {
|
|
|
|
LLVMContext &C = M.getContext();
|
|
|
|
IntegerType *Int8Ty = IntegerType::getInt8Ty(C);
|
|
IntegerType *Int32Ty = IntegerType::getInt32Ty(C);
|
|
|
|
+ auto PA = PreservedAnalyses::all();
|
|
+
|
|
/* Show a banner */
|
|
|
|
char be_quiet = 0;
|
|
@@ -175,21 +188,6 @@ bool AFLCoverage::runOnModule(Module &M) {
|
|
|
|
}
|
|
|
|
- return true;
|
|
+ return PA;
|
|
|
|
}
|
|
-
|
|
-
|
|
-static void registerAFLPass(const PassManagerBuilder &,
|
|
- legacy::PassManagerBase &PM) {
|
|
-
|
|
- PM.add(new AFLCoverage());
|
|
-
|
|
-}
|
|
-
|
|
-
|
|
-static RegisterStandardPasses RegisterAFLPass(
|
|
- PassManagerBuilder::EP_ModuleOptimizerEarly, registerAFLPass);
|
|
-
|
|
-static RegisterStandardPasses RegisterAFLPass0(
|
|
- PassManagerBuilder::EP_EnabledOnOptLevel0, registerAFLPass);
|
|
--
|
|
2.37.1
|
|
|
|
From bd47b9066e616fdfdad1808ec0365992a4962ff2 Mon Sep 17 00:00:00 2001
|
|
From: Jesse Schwartzentruber <truber@mozilla.com>
|
|
Date: Tue, 9 Aug 2022 17:18:15 -0400
|
|
Subject: [PATCH 06/10] Add install step for afl-clang-fast only
|
|
|
|
---
|
|
llvm_mode/Makefile | 10 ++++++++++
|
|
1 file changed, 10 insertions(+)
|
|
|
|
diff --git a/llvm_mode/Makefile b/llvm_mode/Makefile
|
|
index 823e959..b155eb5 100644
|
|
--- a/llvm_mode/Makefile
|
|
+++ b/llvm_mode/Makefile
|
|
@@ -103,3 +103,13 @@ all_done:
|
|
clean:
|
|
rm -f *.o *.so *~ a.out core core.[1-9][0-9]* test-instr .test-instr0 .test-instr1
|
|
rm -f $(PROGS) ../afl-clang-fast++
|
|
+
|
|
+install: all
|
|
+ mkdir -p -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(HELPER_PATH)
|
|
+ifndef AFL_TRACE_PC
|
|
+ if [ -f ../afl-clang-fast -a -f ../afl-llvm-pass.so -a -f ../afl-llvm-rt.o ]; then set -e; install -m 755 ../afl-clang-fast $${DESTDIR}$(BIN_PATH); ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-fast++; install -m 755 ../afl-llvm-pass.so ../afl-llvm-rt.o $${DESTDIR}$(HELPER_PATH); fi
|
|
+else
|
|
+ if [ -f ../afl-clang-fast -a -f ../afl-llvm-rt.o ]; then set -e; install -m 755 ../afl-clang-fast $${DESTDIR}$(BIN_PATH); ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-fast++; install -m 755 ../afl-llvm-rt.o $${DESTDIR}$(HELPER_PATH); fi
|
|
+endif
|
|
+ if [ -f ../afl-llvm-rt-32.o ]; then set -e; install -m 755 ../afl-llvm-rt-32.o $${DESTDIR}$(HELPER_PATH); fi
|
|
+ if [ -f ../afl-llvm-rt-64.o ]; then set -e; install -m 755 ../afl-llvm-rt-64.o $${DESTDIR}$(HELPER_PATH); fi
|
|
--
|
|
2.37.1
|
|
|
|
From 11f8b04786239bc8daa2c7a207b5e19f5c19ec6e Mon Sep 17 00:00:00 2001
|
|
From: Jesse Schwartzentruber <truber@mozilla.com>
|
|
Date: Thu, 11 Aug 2022 11:39:37 -0400
|
|
Subject: [PATCH 07/10] Reenable instrumentation tests
|
|
|
|
---
|
|
config.h | 4 ++++
|
|
llvm_mode/Makefile | 15 +++++++++++++--
|
|
llvm_mode/afl-llvm-rt.o.c | 1 +
|
|
3 files changed, 18 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/config.h b/config.h
|
|
index b21298d..c035af2 100644
|
|
--- a/config.h
|
|
+++ b/config.h
|
|
@@ -285,6 +285,10 @@
|
|
#define PERSIST_ENV_VAR "__AFL_PERSISTENT"
|
|
#define DEFER_ENV_VAR "__AFL_DEFER_FORKSRV"
|
|
|
|
+/* Enable tracing by default at startup */
|
|
+
|
|
+#define TRACE_ENV_VAR "__AFL_ENABLE_TRACE"
|
|
+
|
|
/* In-code signatures for deferred and persistent mode. */
|
|
|
|
#define PERSIST_SIG "##SIG_AFL_PERSISTENT##"
|
|
diff --git a/llvm_mode/Makefile b/llvm_mode/Makefile
|
|
index b155eb5..4f460ff 100644
|
|
--- a/llvm_mode/Makefile
|
|
+++ b/llvm_mode/Makefile
|
|
@@ -62,7 +62,7 @@ else
|
|
PROGS = ../afl-clang-fast ../afl-llvm-rt.o ../afl-llvm-rt-32.o ../afl-llvm-rt-64.o
|
|
endif
|
|
|
|
-all: test_deps $(PROGS) all_done
|
|
+all: test_deps $(PROGS) test_build all_done
|
|
|
|
test_deps:
|
|
ifndef AFL_TRACE_PC
|
|
@@ -95,7 +95,18 @@ endif
|
|
@printf "[*] Building 64-bit variant of the runtime (-m64)... "
|
|
@$(CC) $(CFLAGS) -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
|
|
|
|
-all_done:
|
|
+test_build: $(PROGS)
|
|
+ @echo "[*] Testing the CC wrapper and instrumentation output..."
|
|
+ unset AFL_USE_ASAN AFL_USE_MSAN AFL_INST_RATIO; AFL_QUIET=1 AFL_PATH=. AFL_CC=$(CC) ../afl-clang-fast $(CFLAGS) ../test-instr.c -o test-instr $(LDFLAGS)
|
|
+# Use /dev/null to avoid problems with optimization messing up expected
|
|
+# branches. See https://github.com/google/AFL/issues/30.
|
|
+ __AFL_ENABLE_TRACE=1 ../afl-showmap -m none -q -o .test-instr0 ./test-instr < /dev/null
|
|
+ echo 1 | __AFL_ENABLE_TRACE=1 ../afl-showmap -m none -q -o .test-instr1 ./test-instr
|
|
+ @rm -f test-instr
|
|
+ @cmp -s .test-instr0 .test-instr1; DR="$$?"; rm -f .test-instr0 .test-instr1; if [ "$$DR" = "0" ]; then echo; echo "Oops, the instrumentation does not seem to be behaving correctly!"; echo; echo "Please ping <lcamtuf@google.com> to troubleshoot the issue."; echo; exit 1; fi
|
|
+ @echo "[+] All right, the instrumentation seems to be working!"
|
|
+
|
|
+all_done: test_build
|
|
@echo "[+] All done! You can now use '../afl-clang-fast' to compile programs."
|
|
|
|
.NOTPARALLEL: clean
|
|
diff --git a/llvm_mode/afl-llvm-rt.o.c b/llvm_mode/afl-llvm-rt.o.c
|
|
index 536adb9..c3b710f 100644
|
|
--- a/llvm_mode/afl-llvm-rt.o.c
|
|
+++ b/llvm_mode/afl-llvm-rt.o.c
|
|
@@ -285,6 +285,7 @@ __attribute__((constructor(CONST_PRIO))) void __afl_auto_init(void) {
|
|
|
|
__afl_manual_init();
|
|
|
|
+ if (getenv(TRACE_ENV_VAR)) enable_afl_tracing();
|
|
}
|
|
|
|
|
|
--
|
|
2.37.1
|
|
|
|
From dd1050393281f2ea4c9b6521f5e48bec365b0a8a Mon Sep 17 00:00:00 2001
|
|
From: Jesse Schwartzentruber <truber@mozilla.com>
|
|
Date: Thu, 11 Aug 2022 13:17:34 -0400
|
|
Subject: [PATCH 08/10] Add search in HELPER_PATH for libraries.
|
|
|
|
---
|
|
llvm_mode/afl-clang-fast.c | 10 ++++++++++
|
|
1 file changed, 10 insertions(+)
|
|
|
|
diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c
|
|
index 5e00286..70b6af2 100644
|
|
--- a/llvm_mode/afl-clang-fast.c
|
|
+++ b/llvm_mode/afl-clang-fast.c
|
|
@@ -85,6 +85,16 @@ static void find_obj(u8* argv0) {
|
|
return;
|
|
}
|
|
|
|
+ ck_free(tmp);
|
|
+ tmp = alloc_printf("%s/../lib/afl/afl-llvm-rt.o", dir);
|
|
+
|
|
+ if (!access(tmp, R_OK)) {
|
|
+ ck_free(tmp);
|
|
+ obj_path = alloc_printf("%s/../lib/afl", dir);
|
|
+ ck_free(dir);
|
|
+ return;
|
|
+ }
|
|
+
|
|
ck_free(tmp);
|
|
ck_free(dir);
|
|
|
|
--
|
|
2.37.1
|
|
|
|
From 9eb9eaf26d473bb8479df380f918a1bf83250029 Mon Sep 17 00:00:00 2001
|
|
From: Jesse Schwartzentruber <truber@mozilla.com>
|
|
Date: Thu, 11 Aug 2022 19:16:36 -0400
|
|
Subject: [PATCH 09/10] Don't instrument at all for wasm
|
|
|
|
---
|
|
llvm_mode/afl-clang-fast.c | 41 ++++++++++++++++++++------------------
|
|
1 file changed, 22 insertions(+), 19 deletions(-)
|
|
|
|
diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c
|
|
index 70b6af2..0d1e76b 100644
|
|
--- a/llvm_mode/afl-clang-fast.c
|
|
+++ b/llvm_mode/afl-clang-fast.c
|
|
@@ -180,23 +180,6 @@ static void edit_params(u32 argc, char** argv) {
|
|
|
|
}
|
|
|
|
- /* There are two ways to compile afl-clang-fast. In the traditional mode, we
|
|
- use afl-llvm-pass.so to inject instrumentation. In the experimental
|
|
- 'trace-pc-guard' mode, we use native LLVM instrumentation callbacks
|
|
- instead. The latter is a very recent addition - see:
|
|
-
|
|
- http://clang.llvm.org/docs/SanitizerCoverage.html#tracing-pcs-with-guards */
|
|
-if (should_instrument) {
|
|
-#ifdef USE_TRACE_PC
|
|
- #error "unsupported"
|
|
- cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
|
|
- cc_params[cc_par_cnt++] = "-mllvm";
|
|
- cc_params[cc_par_cnt++] = "-sanitizer-coverage-block-threshold=0";
|
|
-#else
|
|
- cc_params[cc_par_cnt++] = alloc_printf("-fpass-plugin=%s/afl-llvm-pass.so", obj_path);
|
|
-#endif /* ^USE_TRACE_PC */
|
|
-}
|
|
-
|
|
cc_params[cc_par_cnt++] = "-Qunused-arguments";
|
|
|
|
/* Detect stray -v calls from ./configure scripts. */
|
|
@@ -222,7 +204,10 @@ if (should_instrument) {
|
|
if (strstr(cur, "FORTIFY_SOURCE")) fortify_set = 1;
|
|
|
|
if (!strcmp(cur, "-shared")) maybe_linking = 0;
|
|
- if (!strcmp(cur, "--target=wasm32-wasi")) maybe_linking = 0;
|
|
+ if (!strcmp(cur, "--target=wasm32-wasi")) {
|
|
+ maybe_linking = 0;
|
|
+ should_instrument = 0;
|
|
+ }
|
|
|
|
if (!strcmp(cur, "-Wl,-z,defs") ||
|
|
!strcmp(cur, "-Wl,--no-undefined")) continue;
|
|
@@ -231,6 +216,23 @@ if (should_instrument) {
|
|
|
|
}
|
|
|
|
+ /* There are two ways to compile afl-clang-fast. In the traditional mode, we
|
|
+ use afl-llvm-pass.so to inject instrumentation. In the experimental
|
|
+ 'trace-pc-guard' mode, we use native LLVM instrumentation callbacks
|
|
+ instead. The latter is a very recent addition - see:
|
|
+
|
|
+ http://clang.llvm.org/docs/SanitizerCoverage.html#tracing-pcs-with-guards */
|
|
+ if (should_instrument) {
|
|
+#ifdef USE_TRACE_PC
|
|
+ #error "unsupported"
|
|
+ cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
|
|
+ cc_params[cc_par_cnt++] = "-mllvm";
|
|
+ cc_params[cc_par_cnt++] = "-sanitizer-coverage-block-threshold=0";
|
|
+#else
|
|
+ cc_params[cc_par_cnt++] = alloc_printf("-fpass-plugin=%s/afl-llvm-pass.so", obj_path);
|
|
+#endif /* ^USE_TRACE_PC */
|
|
+ }
|
|
+
|
|
if (getenv("AFL_HARDEN")) {
|
|
|
|
cc_params[cc_par_cnt++] = "-fstack-protector-all";
|
|
--
|
|
2.37.1
|
|
|
|
From 6ea1771e95d6f4c19453047996b0fc4ffa3fdeda Mon Sep 17 00:00:00 2001
|
|
From: Jesse Schwartzentruber <truber@mozilla.com>
|
|
Date: Wed, 20 Apr 2022 15:39:28 -0400
|
|
Subject: [PATCH 10/10] fix instrumentation for
|
|
-Werror,-Wunused-but-set-variable
|
|
|
|
`used` is so it isn't optimized out. `unused` is to avoid the warning.
|
|
---
|
|
llvm_mode/afl-clang-fast.c | 4 ++--
|
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c
|
|
index 0d1e76b..3bc0daa 100644
|
|
--- a/llvm_mode/afl-clang-fast.c
|
|
+++ b/llvm_mode/afl-clang-fast.c
|
|
@@ -321,7 +321,7 @@ static void edit_params(u32 argc, char** argv) {
|
|
*/
|
|
|
|
cc_params[cc_par_cnt++] = "-D__AFL_LOOP(_A)="
|
|
- "({ static volatile char *_B __attribute__((used)); "
|
|
+ "({ static volatile char *_B __attribute__((used,unused)); "
|
|
" _B = (char*)\"" PERSIST_SIG "\"; "
|
|
#ifdef __APPLE__
|
|
"__attribute__((visibility(\"default\"))) "
|
|
@@ -333,7 +333,7 @@ static void edit_params(u32 argc, char** argv) {
|
|
"_L(_A); })";
|
|
|
|
cc_params[cc_par_cnt++] = "-D__AFL_INIT()="
|
|
- "do { static volatile char *_A __attribute__((used)); "
|
|
+ "do { static volatile char *_A __attribute__((used,unused)); "
|
|
" _A = (char*)\"" DEFER_SIG "\"; "
|
|
#ifdef __APPLE__
|
|
"__attribute__((visibility(\"default\"))) "
|
|
--
|
|
2.37.1
|
|
|
|
From 0884906de0cdd007b28b15aae35cee484d1bc31d Mon Sep 17 00:00:00 2001
|
|
From: Mike Hommey <mh@glandium.org>
|
|
Date: Tue, 6 Sep 2022 11:08:55 +0900
|
|
Subject: [PATCH] Fix build failures with clang 15
|
|
|
|
---
|
|
Makefile | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/Makefile b/Makefile
|
|
index 5e800db..c875f2d 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -50,7 +50,7 @@ ifndef AFL_NO_X86
|
|
|
|
test_x86:
|
|
@echo "[*] Checking for the ability to compile x86 code..."
|
|
- @echo 'main() { __asm__("xorb %al, %al"); }' | $(CC) -w -x c - -o .test || ( echo; echo "Oops, looks like your compiler can't generate x86 code."; echo; echo "Don't panic! You can use the LLVM or QEMU mode, but see docs/INSTALL first."; echo "(To ignore this error, set AFL_NO_X86=1 and try again.)"; echo; exit 1 )
|
|
+ @echo 'int main() { __asm__("xorb %al, %al"); }' | $(CC) -w -x c - -o .test || ( echo; echo "Oops, looks like your compiler can't generate x86 code."; echo; echo "Don't panic! You can use the LLVM or QEMU mode, but see docs/INSTALL first."; echo "(To ignore this error, set AFL_NO_X86=1 and try again.)"; echo; exit 1 )
|
|
@rm -f .test
|
|
@echo "[+] Everything seems to be working, ready to compile."
|
|
|
|
--
|
|
2.37.1.1.g659da70093
|
|
|
|
From 0544d02715a26a032f109984d5f70360b80f3875 Mon Sep 17 00:00:00 2001
|
|
From: Mike Hommey <mh@glandium.org>
|
|
Date: Wed, 14 Dec 2022 16:25:53 +0900
|
|
Subject: [PATCH] Add missing include
|
|
|
|
---
|
|
llvm_mode/afl-llvm-pass.so.cc | 1 +
|
|
1 file changed, 1 insertion(+)
|
|
|
|
diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc
|
|
index 1483943..0a7c37a 100644
|
|
--- a/llvm_mode/afl-llvm-pass.so.cc
|
|
+++ b/llvm_mode/afl-llvm-pass.so.cc
|
|
@@ -39,6 +39,7 @@
|
|
#include <unistd.h>
|
|
|
|
#include "llvm/Pass.h"
|
|
+#include "llvm/ADT/None.h"
|
|
#include "llvm/ADT/Statistic.h"
|
|
#include "llvm/IR/IRBuilder.h"
|
|
#include "llvm/IR/Module.h"
|
|
--
|
|
2.38.1.1.g6d9df9d320
|
|
|