diff options
-rw-r--r-- | .travis.yml | 6 | ||||
-rw-r--r-- | Makefile | 12 | ||||
-rw-r--r-- | include/alloc-inl.h | 431 | ||||
-rw-r--r-- | include/config.h | 6 | ||||
-rw-r--r-- | qemu_mode/patches/afl-qemu-cpu-translate-inl.h | 118 | ||||
-rw-r--r-- | qemu_mode/patches/afl-qemu-tcg-runtime-inl.h | 160 | ||||
-rw-r--r-- | qemu_mode/patches/tcg-runtime.diff | 20 | ||||
-rw-r--r-- | src/afl-fuzz.c | 51 | ||||
-rw-r--r-- | src/afl-gcc.c | 55 | ||||
-rw-r--r-- | src/afl-showmap.c | 11 | ||||
-rwxr-xr-x | test/test.sh | 32 |
11 files changed, 266 insertions, 636 deletions
diff --git a/.travis.yml b/.travis.yml index d58f955a..6e48adf4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -46,7 +46,7 @@ script: - gcc -v - clang -v - sudo -E ./afl-system-config - - if [ "$TRAVIS_OS_NAME" = "osx" ]; then export LLVM_CONFIG=`pwd`/"$NAME" ; make source-only ; fi - - if [ "$TRAVIS_OS_NAME" = "linux" -a "$TRAVIS_CPU_ARCH" = "amd64" ]; then make distrib ; fi - - if [ "$TRAVIS_CPU_ARCH" = "arm64" ] ; then make ; cd qemu_mode && sh ./build_qemu_support.sh ; cd .. ; fi + - if [ "$TRAVIS_OS_NAME" = "osx" ]; then export LLVM_CONFIG=`pwd`/"$NAME" ; make source-only ASAN_BUILD=1 ; fi + - if [ "$TRAVIS_OS_NAME" = "linux" -a "$TRAVIS_CPU_ARCH" = "amd64" ]; then make distrib ASAN_BUILD=1 ; fi + - if [ "$TRAVIS_CPU_ARCH" = "arm64" ] ; then make ASAN_BUILD=1 ; cd qemu_mode && sh ./build_qemu_support.sh ; cd .. ; fi - make tests diff --git a/Makefile b/Makefile index 0e20f226..1e8a894b 100644 --- a/Makefile +++ b/Makefile @@ -162,6 +162,10 @@ ifeq "$(TEST_MMAP)" "1" LDFLAGS+=-Wno-deprecated-declarations -lrt endif +ifdef ASAN_BUILD + CFLAGS+=-fsanitize=address + LDFLAGS+=-fsanitize=address +endif all: test_x86 test_shm test_python ready $(PROGS) afl-as test_build all_done @@ -254,13 +258,13 @@ afl-as: src/afl-as.c include/afl-as.h $(COMM_HDR) | test_x86 $(CC) $(CFLAGS) src/$@.c -o $@ $(LDFLAGS) ln -sf afl-as as -src/afl-common.o : src/afl-common.c include/common.h +src/afl-common.o : $(COMM_HDR) src/afl-common.c include/common.h $(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-common.c -o src/afl-common.o -src/afl-forkserver.o : src/afl-forkserver.c include/forkserver.h +src/afl-forkserver.o : $(COMM_HDR) src/afl-forkserver.c include/forkserver.h $(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-forkserver.c -o src/afl-forkserver.o -src/afl-sharedmem.o : src/afl-sharedmem.c include/sharedmem.h +src/afl-sharedmem.o : $(COMM_HDR) src/afl-sharedmem.c include/sharedmem.h $(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-sharedmem.c -o src/afl-sharedmem.o radamsa: src/third_party/libradamsa/libradamsa.so @@ -269,7 +273,7 @@ radamsa: src/third_party/libradamsa/libradamsa.so src/third_party/libradamsa/libradamsa.so: src/third_party/libradamsa/libradamsa.c src/third_party/libradamsa/radamsa.h $(MAKE) -C src/third_party/libradamsa/ CFLAGS="$(CFLAGS)" -afl-fuzz: include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o $(COMM_HDR) | test_x86 +afl-fuzz: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o | test_x86 $(CC) $(CFLAGS) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(PYFLAGS) $(LDFLAGS) afl-showmap: src/afl-showmap.c src/afl-common.o src/afl-sharedmem.o $(COMM_HDR) | test_x86 diff --git a/include/alloc-inl.h b/include/alloc-inl.h index 26ce7d22..ada08b69 100644 --- a/include/alloc-inl.h +++ b/include/alloc-inl.h @@ -34,14 +34,6 @@ #include "types.h" #include "debug.h" -/* Disable speed hack in debug mode */ - -#ifdef UNSAFE_MEMORY -#ifdef DEBUG_BUILD -#undef UNSAFE_MEMORY -#endif -#endif - /* User-facing macro to sprintf() to a dynamically allocated buffer. */ #define alloc_printf(_str...) \ @@ -75,91 +67,10 @@ \ } while (0) -/* Magic tokens used to mark used / freed chunks. */ - -#define ALLOC_MAGIC_C1 0xFF00FF00 /* Used head (dword) */ -#define ALLOC_MAGIC_F 0xFE00FE00 /* Freed head (dword) */ -#define ALLOC_MAGIC_C2 0xF0 /* Used tail (byte) */ - -/* Positions of guard tokens in relation to the user-visible pointer. */ - -#ifndef UNSAFE_MEMORY -#define ALLOC_C1(_ptr) (((u32*)(_ptr))[-2]) -#define ALLOC_S(_ptr) (((u32*)(_ptr))[-1]) -#define ALLOC_C2(_ptr) (((u8*)(_ptr))[ALLOC_S(_ptr)]) -#else -#define ALLOC_C1(_ptr) (((u32*)(_ptr))[0]) -#define ALLOC_S(_ptr) (((u32*)(_ptr))[0]) -#define ALLOC_C2(_ptr) (((u8*)(_ptr))[ALLOC_S(_ptr)]) -#endif - -#ifndef UNSAFE_MEMORY -#define ALLOC_OFF_HEAD 8 -#define ALLOC_OFF_TOTAL (ALLOC_OFF_HEAD + 1) -#else -#define ALLOC_OFF_HEAD 0 -#define ALLOC_OFF_TOTAL 0 -#endif - /* Allocator increments for ck_realloc_block(). */ #define ALLOC_BLK_INC 256 -/* Sanity-checking macros for pointers. */ - -#ifndef UNSAFE_MEMORY -#define CHECK_PTR(_p) \ - do { \ - \ - if (_p) { \ - \ - if (ALLOC_C1(_p) ^ ALLOC_MAGIC_C1) { \ - \ - if (ALLOC_C1(_p) == ALLOC_MAGIC_F) \ - ABORT("Use after free."); \ - else \ - ABORT("Corrupted head alloc canary."); \ - \ - } \ - \ - } \ - \ - } while (0) - -#else -#define CHECK_PTR(_p) \ - do { \ - \ - } while (0) -#endif - -/* #define CHECK_PTR(_p) do { \ - if (_p) { \ - if (ALLOC_C1(_p) ^ ALLOC_MAGIC_C1) {\ - if (ALLOC_C1(_p) == ALLOC_MAGIC_F) \ - ABORT("Use after free."); \ - else ABORT("Corrupted head alloc canary."); \ - - } \ - - if (ALLOC_C2(_p) ^ ALLOC_MAGIC_C2) \ - ABORT("Corrupted tail alloc canary."); \ - - } \ - - } while (0) - -*/ - -#define CHECK_PTR_EXPR(_p) \ - ({ \ - \ - typeof(_p) _tmp = (_p); \ - CHECK_PTR(_tmp); \ - _tmp; \ - \ - }) - /* Allocate a buffer, explicitly not zeroing it. Returns NULL for zero-sized requests. */ @@ -170,17 +81,9 @@ static inline void* DFL_ck_alloc_nozero(u32 size) { if (!size) return NULL; ALLOC_CHECK_SIZE(size); - ret = malloc(size + ALLOC_OFF_TOTAL); + ret = malloc(size); ALLOC_CHECK_RESULT(ret, size); -#ifndef UNSAFE_MEMORY - ret += ALLOC_OFF_HEAD; - - ALLOC_C1(ret) = ALLOC_MAGIC_C1; - ALLOC_S(ret) = size; - ALLOC_C2(ret) = ALLOC_MAGIC_C2; -#endif - return (void*)ret; } @@ -198,28 +101,11 @@ static inline void* DFL_ck_alloc(u32 size) { } -/* Free memory, checking for double free and corrupted heap. When DEBUG_BUILD - is set, the old memory will be also clobbered with 0xFF. */ +/* Free memory */ static inline void DFL_ck_free(void* mem) { - if (!mem) return; - - CHECK_PTR(mem); - -#ifdef DEBUG_BUILD - - /* Catch pointer issues sooner. */ - memset(mem, 0xFF, ALLOC_S(mem)); - -#endif /* DEBUG_BUILD */ - -#ifndef UNSAFE_MEMORY - ALLOC_C1(mem) = ALLOC_MAGIC_F; -#endif - - u8* realStart = mem; - free(realStart - ALLOC_OFF_HEAD); + free(mem); } @@ -239,64 +125,11 @@ static inline void* DFL_ck_realloc(void* orig, u32 size) { } - if (orig) { - - CHECK_PTR(orig); - -#ifndef UNSAFE_MEMORY -#ifndef DEBUG_BUILD - ALLOC_C1(orig) = ALLOC_MAGIC_F; -#endif /* !DEBUG_BUILD */ -#endif - -#ifndef UNSAFE_MEMORY - old_size = ALLOC_S(orig); - u8* origu8 = orig; - origu8 -= ALLOC_OFF_HEAD; - orig = origu8; - - ALLOC_CHECK_SIZE(old_size); -#endif - - } - ALLOC_CHECK_SIZE(size); -#ifndef DEBUG_BUILD - - ret = realloc(orig, size + ALLOC_OFF_TOTAL); + ret = realloc(orig, size); ALLOC_CHECK_RESULT(ret, size); -#else - - /* Catch pointer issues sooner: force relocation and make sure that the - original buffer is wiped. */ - - ret = malloc(size + ALLOC_OFF_TOTAL); - ALLOC_CHECK_RESULT(ret, size); - - if (orig) { - - u8* origu8 = orig; - memcpy(ret + ALLOC_OFF_HEAD, origu8 + ALLOC_OFF_HEAD, MIN(size, old_size)); - memset(origu8 + ALLOC_OFF_HEAD, 0xFF, old_size); - - ALLOC_C1(origu8 + ALLOC_OFF_HEAD) = ALLOC_MAGIC_F; - - free(orig); - - } - -#endif /* ^!DEBUG_BUILD */ - -#ifdef UNSAFE_MEMORY - ret += ALLOC_OFF_HEAD; - - ALLOC_C1(ret) = ALLOC_MAGIC_C1; - ALLOC_S(ret) = size; - ALLOC_C2(ret) = ALLOC_MAGIC_C2; -#endif - if (size > old_size) memset(ret + old_size, 0, size - old_size); return (void*)ret; @@ -308,22 +141,9 @@ static inline void* DFL_ck_realloc(void* orig, u32 size) { static inline void* DFL_ck_realloc_block(void* orig, u32 size) { -#ifndef DEBUG_BUILD - - if (orig) { - - CHECK_PTR(orig); - -#ifndef UNSAFE_MEMORY - if (ALLOC_S(orig) >= size) return orig; -#endif - + if (orig) size += ALLOC_BLK_INC; - } - -#endif /* !DEBUG_BUILD */ - return DFL_ck_realloc(orig, size); } @@ -340,17 +160,9 @@ static inline u8* DFL_ck_strdup(u8* str) { size = strlen((char*)str) + 1; ALLOC_CHECK_SIZE(size); - ret = malloc(size + ALLOC_OFF_TOTAL); + ret = malloc(size); ALLOC_CHECK_RESULT(ret, size); -#ifdef UNSAFE_MEMORY - ret += ALLOC_OFF_HEAD; - - ALLOC_C1(ret) = ALLOC_MAGIC_C1; - ALLOC_S(ret) = size; - ALLOC_C2(ret) = ALLOC_MAGIC_C2; -#endif - return memcpy(ret, str, size); } @@ -365,17 +177,9 @@ static inline void* DFL_ck_memdup(void* mem, u32 size) { if (!mem || !size) return NULL; ALLOC_CHECK_SIZE(size); - ret = malloc(size + ALLOC_OFF_TOTAL); + ret = malloc(size); ALLOC_CHECK_RESULT(ret, size); -#ifdef UNSAFE_MEMORY - ret += ALLOC_OFF_HEAD; - - ALLOC_C1(ret) = ALLOC_MAGIC_C1; - ALLOC_S(ret) = size; - ALLOC_C2(ret) = ALLOC_MAGIC_C2; -#endif - return memcpy(ret, mem, size); } @@ -390,17 +194,9 @@ static inline u8* DFL_ck_memdup_str(u8* mem, u32 size) { if (!mem || !size) return NULL; ALLOC_CHECK_SIZE(size); - ret = malloc(size + ALLOC_OFF_TOTAL + 1); + ret = malloc(size + 1); ALLOC_CHECK_RESULT(ret, size); -#ifdef UNSAFE_MEMORY - ret += ALLOC_OFF_HEAD; - - ALLOC_C1(ret) = ALLOC_MAGIC_C1; - ALLOC_S(ret) = size; - ALLOC_C2(ret) = ALLOC_MAGIC_C2; -#endif - memcpy(ret, mem, size); ret[size] = 0; @@ -408,8 +204,6 @@ static inline u8* DFL_ck_memdup_str(u8* mem, u32 size) { } -#ifndef DEBUG_BUILD - /* In non-debug mode, we just do straightforward aliasing of the above functions to user-visible names such as ck_alloc(). */ @@ -424,214 +218,5 @@ static inline u8* DFL_ck_memdup_str(u8* mem, u32 size) { #define alloc_report() -#else - -/* In debugging mode, we also track allocations to detect memory leaks, and the - flow goes through one more layer of indirection. */ - -/* Alloc tracking data structures: */ - -#define ALLOC_BUCKETS 4096 - -struct TRK_obj { - - void* ptr; - char *file, *func; - u32 line; - -}; - -#ifdef AFL_MAIN - -struct TRK_obj* TRK[ALLOC_BUCKETS]; -u32 TRK_cnt[ALLOC_BUCKETS]; - -#define alloc_report() TRK_report() - -#else - -extern struct TRK_obj* TRK[ALLOC_BUCKETS]; -extern u32 TRK_cnt[ALLOC_BUCKETS]; - -#define alloc_report() - -#endif /* ^AFL_MAIN */ - -/* Bucket-assigning function for a given pointer: */ - -#define TRKH(_ptr) (((((u32)(_ptr)) >> 16) ^ ((u32)(_ptr))) % ALLOC_BUCKETS) - -/* Add a new entry to the list of allocated objects. */ - -static inline void TRK_alloc_buf(void* ptr, const char* file, const char* func, - u32 line) { - - u32 i, bucket; - - if (!ptr) return; - - bucket = TRKH(ptr); - - /* Find a free slot in the list of entries for that bucket. */ - - for (i = 0; i < TRK_cnt[bucket]; i++) - - if (!TRK[bucket][i].ptr) { - - TRK[bucket][i].ptr = ptr; - TRK[bucket][i].file = (char*)file; - TRK[bucket][i].func = (char*)func; - TRK[bucket][i].line = line; - return; - - } - - /* No space available - allocate more. */ - - TRK[bucket] = DFL_ck_realloc_block( - TRK[bucket], (TRK_cnt[bucket] + 1) * sizeof(struct TRK_obj)); - - TRK[bucket][i].ptr = ptr; - TRK[bucket][i].file = (char*)file; - TRK[bucket][i].func = (char*)func; - TRK[bucket][i].line = line; - - TRK_cnt[bucket]++; - -} - -/* Remove entry from the list of allocated objects. */ - -static inline void TRK_free_buf(void* ptr, const char* file, const char* func, - u32 line) { - - u32 i, bucket; - - if (!ptr) return; - - bucket = TRKH(ptr); - - /* Find the element on the list... */ - - for (i = 0; i < TRK_cnt[bucket]; i++) - - if (TRK[bucket][i].ptr == ptr) { - - TRK[bucket][i].ptr = 0; - return; - - } - - WARNF("ALLOC: Attempt to free non-allocated memory in %s (%s:%u)", func, file, - line); - -} - -/* Do a final report on all non-deallocated objects. */ - -static inline void TRK_report(void) { - - u32 i, bucket; - - fflush(0); - - for (bucket = 0; bucket < ALLOC_BUCKETS; bucket++) - for (i = 0; i < TRK_cnt[bucket]; i++) - if (TRK[bucket][i].ptr) - WARNF("ALLOC: Memory never freed, created in %s (%s:%u)", - TRK[bucket][i].func, TRK[bucket][i].file, TRK[bucket][i].line); - -} - -/* Simple wrappers for non-debugging functions: */ - -static inline void* TRK_ck_alloc(u32 size, const char* file, const char* func, - u32 line) { - - void* ret = DFL_ck_alloc(size); - TRK_alloc_buf(ret, file, func, line); - return ret; - -} - -static inline void* TRK_ck_realloc(void* orig, u32 size, const char* file, - const char* func, u32 line) { - - void* ret = DFL_ck_realloc(orig, size); - TRK_free_buf(orig, file, func, line); - TRK_alloc_buf(ret, file, func, line); - return ret; - -} - -static inline void* TRK_ck_realloc_block(void* orig, u32 size, const char* file, - const char* func, u32 line) { - - void* ret = DFL_ck_realloc_block(orig, size); - TRK_free_buf(orig, file, func, line); - TRK_alloc_buf(ret, file, func, line); - return ret; - -} - -static inline void* TRK_ck_strdup(u8* str, const char* file, const char* func, - u32 line) { - - void* ret = DFL_ck_strdup(str); - TRK_alloc_buf(ret, file, func, line); - return ret; - -} - -static inline void* TRK_ck_memdup(void* mem, u32 size, const char* file, - const char* func, u32 line) { - - void* ret = DFL_ck_memdup(mem, size); - TRK_alloc_buf(ret, file, func, line); - return ret; - -} - -static inline void* TRK_ck_memdup_str(void* mem, u32 size, const char* file, - const char* func, u32 line) { - - void* ret = DFL_ck_memdup_str(mem, size); - TRK_alloc_buf(ret, file, func, line); - return ret; - -} - -static inline void TRK_ck_free(void* ptr, const char* file, const char* func, - u32 line) { - - TRK_free_buf(ptr, file, func, line); - DFL_ck_free(ptr); - -} - -/* Aliasing user-facing names to tracking functions: */ - -#define ck_alloc(_p1) TRK_ck_alloc(_p1, __FILE__, __FUNCTION__, __LINE__) - -#define ck_alloc_nozero(_p1) TRK_ck_alloc(_p1, __FILE__, __FUNCTION__, __LINE__) - -#define ck_realloc(_p1, _p2) \ - TRK_ck_realloc(_p1, _p2, __FILE__, __FUNCTION__, __LINE__) - -#define ck_realloc_block(_p1, _p2) \ - TRK_ck_realloc_block(_p1, _p2, __FILE__, __FUNCTION__, __LINE__) - -#define ck_strdup(_p1) TRK_ck_strdup(_p1, __FILE__, __FUNCTION__, __LINE__) - -#define ck_memdup(_p1, _p2) \ - TRK_ck_memdup(_p1, _p2, __FILE__, __FUNCTION__, __LINE__) - -#define ck_memdup_str(_p1, _p2) \ - TRK_ck_memdup_str(_p1, _p2, __FILE__, __FUNCTION__, __LINE__) - -#define ck_free(_p1) TRK_ck_free(_p1, __FILE__, __FUNCTION__, __LINE__) - -#endif /* ^!DEBUG_BUILD */ - #endif /* ! _HAVE_ALLOC_INL_H */ diff --git a/include/config.h b/include/config.h index c55c46c9..12e2d092 100644 --- a/include/config.h +++ b/include/config.h @@ -46,12 +46,6 @@ #define FANCY_BOXES #endif -/* Comment out to have safe memory checks (security in ck_ functions). - This will cost a little speed, so disable when developing on how - the queue works */ - -#define UNSAFE_MEMORY - /* Default timeout for fuzzed code (milliseconds). This is the upper bound, also used for detecting hangs; the actual value is auto-scaled: */ diff --git a/qemu_mode/patches/afl-qemu-cpu-translate-inl.h b/qemu_mode/patches/afl-qemu-cpu-translate-inl.h index eefe62b2..04cf2e66 100644 --- a/qemu_mode/patches/afl-qemu-cpu-translate-inl.h +++ b/qemu_mode/patches/afl-qemu-cpu-translate-inl.h @@ -41,124 +41,6 @@ #define _DEFAULT_MO MO_32 #endif -void HELPER(afl_compcov_16)(target_ulong cur_loc, target_ulong arg1, - target_ulong arg2) { - - register uintptr_t idx = cur_loc; - - if ((arg1 & 0xff00) == (arg2 & 0xff00)) { INC_AFL_AREA(idx); } - -} - -void HELPER(afl_compcov_32)(target_ulong cur_loc, target_ulong arg1, - target_ulong arg2) { - - register uintptr_t idx = cur_loc; - - if ((arg1 & 0xff000000) == (arg2 & 0xff000000)) { - - INC_AFL_AREA(idx + 2); - if ((arg1 & 0xff0000) == (arg2 & 0xff0000)) { - - INC_AFL_AREA(idx + 1); - if ((arg1 & 0xff00) == (arg2 & 0xff00)) { INC_AFL_AREA(idx); } - - } - - } - -} - -void HELPER(afl_compcov_64)(target_ulong cur_loc, target_ulong arg1, - target_ulong arg2) { - - register uintptr_t idx = cur_loc; - - if ((arg1 & 0xff00000000000000) == (arg2 & 0xff00000000000000)) { - - INC_AFL_AREA(idx + 6); - if ((arg1 & 0xff000000000000) == (arg2 & 0xff000000000000)) { - - INC_AFL_AREA(idx + 5); - if ((arg1 & 0xff0000000000) == (arg2 & 0xff0000000000)) { - - INC_AFL_AREA(idx + 4); - if ((arg1 & 0xff00000000) == (arg2 & 0xff00000000)) { - - INC_AFL_AREA(idx + 3); - if ((arg1 & 0xff000000) == (arg2 & 0xff000000)) { - - INC_AFL_AREA(idx + 2); - if ((arg1 & 0xff0000) == (arg2 & 0xff0000)) { - - INC_AFL_AREA(idx + 1); - if ((arg1 & 0xff00) == (arg2 & 0xff00)) { INC_AFL_AREA(idx); } - - } - - } - - } - - } - - } - - } - -} - -void HELPER(afl_cmplog_16)(target_ulong cur_loc, target_ulong arg1, - target_ulong arg2) { - - register uintptr_t k = (uintptr_t)cur_loc; - - u32 hits = __afl_cmp_map->headers[k].hits; - __afl_cmp_map->headers[k].hits = hits + 1; - // if (!__afl_cmp_map->headers[k].cnt) - // __afl_cmp_map->headers[k].cnt = __afl_cmp_counter++; - - __afl_cmp_map->headers[k].shape = 1; - //__afl_cmp_map->headers[k].type = CMP_TYPE_INS; - - hits &= CMP_MAP_H - 1; - __afl_cmp_map->log[k][hits].v0 = arg1; - __afl_cmp_map->log[k][hits].v1 = arg2; - -} - -void HELPER(afl_cmplog_32)(target_ulong cur_loc, target_ulong arg1, - target_ulong arg2) { - - register uintptr_t k = (uintptr_t)cur_loc; - - u32 hits = __afl_cmp_map->headers[k].hits; - __afl_cmp_map->headers[k].hits = hits + 1; - - __afl_cmp_map->headers[k].shape = 3; - - hits &= CMP_MAP_H - 1; - __afl_cmp_map->log[k][hits].v0 = arg1; - __afl_cmp_map->log[k][hits].v1 = arg2; - -} - -void HELPER(afl_cmplog_64)(target_ulong cur_loc, target_ulong arg1, - target_ulong arg2) { - - register uintptr_t k = (uintptr_t)cur_loc; - - u32 hits = __afl_cmp_map->headers[k].hits; - __afl_cmp_map->headers[k].hits = hits + 1; - - __afl_cmp_map->headers[k].shape = 7; - - hits &= CMP_MAP_H - 1; - __afl_cmp_map->log[k][hits].v0 = arg1; - __afl_cmp_map->log[k][hits].v1 = arg2; - -} - static void afl_gen_compcov(target_ulong cur_loc, TCGv arg1, TCGv arg2, TCGMemOp ot, int is_imm) { diff --git a/qemu_mode/patches/afl-qemu-tcg-runtime-inl.h b/qemu_mode/patches/afl-qemu-tcg-runtime-inl.h new file mode 100644 index 00000000..6339d41c --- /dev/null +++ b/qemu_mode/patches/afl-qemu-tcg-runtime-inl.h @@ -0,0 +1,160 @@ +/* + american fuzzy lop++ - high-performance binary-only instrumentation + ------------------------------------------------------------------- + + Originally written by Andrew Griffiths <agriffiths@google.com> and + Michal Zalewski + + TCG instrumentation and block chaining support by Andrea Biondo + <andrea.biondo965@gmail.com> + + QEMU 3.1.1 port, TCG thread-safety, CompareCoverage and NeverZero + counters by Andrea Fioraldi <andreafioraldi@gmail.com> + + Copyright 2015, 2016, 2017 Google Inc. All rights reserved. + Copyright 2019-2020 AFLplusplus Project. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at: + + http://www.apache.org/licenses/LICENSE-2.0 + + This code is a shim patched into the separately-distributed source + code of QEMU 3.1.0. It leverages the built-in QEMU tracing functionality + to implement AFL-style instrumentation and to take care of the remaining + parts of the AFL fork server logic. + + The resulting QEMU binary is essentially a standalone instrumentation + tool; for an example of how to leverage it for other purposes, you can + have a look at afl-showmap.c. + + */ + +#include "afl-qemu-common.h" +#include "tcg.h" + +void HELPER(afl_entry_routine)(CPUArchState *env) { + + afl_forkserver(ENV_GET_CPU(env)); + +} + +void HELPER(afl_compcov_16)(target_ulong cur_loc, target_ulong arg1, + target_ulong arg2) { + + register uintptr_t idx = cur_loc; + + if ((arg1 & 0xff00) == (arg2 & 0xff00)) { INC_AFL_AREA(idx); } + +} + +void HELPER(afl_compcov_32)(target_ulong cur_loc, target_ulong arg1, + target_ulong arg2) { + + register uintptr_t idx = cur_loc; + + if ((arg1 & 0xff000000) == (arg2 & 0xff000000)) { + + INC_AFL_AREA(idx + 2); + if ((arg1 & 0xff0000) == (arg2 & 0xff0000)) { + + INC_AFL_AREA(idx + 1); + if ((arg1 & 0xff00) == (arg2 & 0xff00)) { INC_AFL_AREA(idx); } + + } + + } + +} + +void HELPER(afl_compcov_64)(target_ulong cur_loc, target_ulong arg1, + target_ulong arg2) { + + register uintptr_t idx = cur_loc; + + if ((arg1 & 0xff00000000000000) == (arg2 & 0xff00000000000000)) { + + INC_AFL_AREA(idx + 6); + if ((arg1 & 0xff000000000000) == (arg2 & 0xff000000000000)) { + + INC_AFL_AREA(idx + 5); + if ((arg1 & 0xff0000000000) == (arg2 & 0xff0000000000)) { + + INC_AFL_AREA(idx + 4); + if ((arg1 & 0xff00000000) == (arg2 & 0xff00000000)) { + + INC_AFL_AREA(idx + 3); + if ((arg1 & 0xff000000) == (arg2 & 0xff000000)) { + + INC_AFL_AREA(idx + 2); + if ((arg1 & 0xff0000) == (arg2 & 0xff0000)) { + + INC_AFL_AREA(idx + 1); + if ((arg1 & 0xff00) == (arg2 & 0xff00)) { INC_AFL_AREA(idx); } + + } + + } + + } + + } + + } + + } + +} + +void HELPER(afl_cmplog_16)(target_ulong cur_loc, target_ulong arg1, + target_ulong arg2) { + + register uintptr_t k = (uintptr_t)cur_loc; + + u32 hits = __afl_cmp_map->headers[k].hits; + __afl_cmp_map->headers[k].hits = hits + 1; + // if (!__afl_cmp_map->headers[k].cnt) + // __afl_cmp_map->headers[k].cnt = __afl_cmp_counter++; + + __afl_cmp_map->headers[k].shape = 1; + //__afl_cmp_map->headers[k].type = CMP_TYPE_INS; + + hits &= CMP_MAP_H - 1; + __afl_cmp_map->log[k][hits].v0 = arg1; + __afl_cmp_map->log[k][hits].v1 = arg2; + +} + +void HELPER(afl_cmplog_32)(target_ulong cur_loc, target_ulong arg1, + target_ulong arg2) { + + register uintptr_t k = (uintptr_t)cur_loc; + + u32 hits = __afl_cmp_map->headers[k].hits; + __afl_cmp_map->headers[k].hits = hits + 1; + + __afl_cmp_map->headers[k].shape = 3; + + hits &= CMP_MAP_H - 1; + __afl_cmp_map->log[k][hits].v0 = arg1; + __afl_cmp_map->log[k][hits].v1 = arg2; + +} + +void HELPER(afl_cmplog_64)(target_ulong cur_loc, target_ulong arg1, + target_ulong arg2) { + + register uintptr_t k = (uintptr_t)cur_loc; + + u32 hits = __afl_cmp_map->headers[k].hits; + __afl_cmp_map->headers[k].hits = hits + 1; + + __afl_cmp_map->headers[k].shape = 7; + + hits &= CMP_MAP_H - 1; + __afl_cmp_map->log[k][hits].v0 = arg1; + __afl_cmp_map->log[k][hits].v1 = arg2; + +} + diff --git a/qemu_mode/patches/tcg-runtime.diff b/qemu_mode/patches/tcg-runtime.diff index 54a62ba8..15456320 100644 --- a/qemu_mode/patches/tcg-runtime.diff +++ b/qemu_mode/patches/tcg-runtime.diff @@ -1,24 +1,10 @@ diff --git a/accel/tcg/tcg-runtime.c b/accel/tcg/tcg-runtime.c -index d0d44844..46154af1 100644 +index d0d44844..009ef15a 100644 --- a/accel/tcg/tcg-runtime.c +++ b/accel/tcg/tcg-runtime.c -@@ -31,6 +31,8 @@ - #include "disas/disas.h" - #include "exec/log.h" - -+#include "../../../patches/afl-qemu-common.h" -+ - /* 32-bit helpers */ - - int32_t HELPER(div_i32)(int32_t arg1, int32_t arg2) -@@ -167,3 +169,10 @@ void HELPER(exit_atomic)(CPUArchState *env) +@@ -167,3 +167,5 @@ void HELPER(exit_atomic)(CPUArchState *env) { cpu_loop_exit_atomic(ENV_GET_CPU(env), GETPC()); } + -+ -+void HELPER(afl_entry_routine)(CPUArchState *env) { -+ -+ afl_forkserver(ENV_GET_CPU(env)); -+ -+} ++#include "../../../patches/afl-qemu-tcg-runtime-inl.h" diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 0609061c..740fb5cb 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -100,7 +100,6 @@ static void usage(u8* argv0) { " -f file - location read by the fuzzed program (stdin)\n" " -t msec - timeout for each run (auto-scaled, 50-%d ms)\n" " -m megs - memory limit for child process (%d MB)\n" - " -c program - enable CmpLog by specifying a binary compiled for it\n" " -Q - use binary-only instrumentation (QEMU mode)\n" " -U - use unicorn-based instrumentation (Unicorn mode)\n" " -W - use qemu-based instrumentation with Wine (Wine " @@ -113,7 +112,9 @@ static void usage(u8* argv0) { "entering the\n" " pacemaker mode (minutes of no new paths, 0 = " "immediately).\n" - " a recommended value is 10-60. see docs/README.MOpt\n\n" + " a recommended value is 10-60. see docs/README.MOpt\n" + " -c program - enable CmpLog by specifying a binary compiled for it.\n" + " if using QEMU, just use -c 0.\n\n" "Fuzzing behavior settings:\n" " -N - do not unlink the fuzzing input file\n" @@ -653,25 +654,6 @@ int main(int argc, char** argv, char** envp) { if (!strcmp(in_dir, out_dir)) FATAL("Input and output directories can't be the same"); - if ((tmp_dir = getenv("AFL_TMPDIR")) != NULL) { - - char tmpfile[file_extension - ? strlen(tmp_dir) + 1 + 10 + 1 + strlen(file_extension) + 1 - : strlen(tmp_dir) + 1 + 10 + 1]; - if (file_extension) { - sprintf(tmpfile, "%s/.cur_input.%s", tmp_dir, file_extension); - } else { - sprintf(tmpfile, "%s/.cur_input", tmp_dir); - } - if (access(tmpfile, F_OK) != - -1) // there is still a race condition here, but well ... - FATAL("AFL_TMPDIR already has an existing temporary input file: %s", - tmpfile); - - } else - - tmp_dir = out_dir; - if (dumb_mode) { if (crash_mode) FATAL("-C and -n are mutually exclusive"); @@ -845,6 +827,26 @@ int main(int argc, char** argv, char** envp) { if (!timeout_given) find_timeout(); + if ((tmp_dir = getenv("AFL_TMPDIR")) != NULL && !in_place_resume) { + + char tmpfile[file_extension + ? strlen(tmp_dir) + 1 + 10 + 1 + strlen(file_extension) + 1 + : strlen(tmp_dir) + 1 + 10 + 1]; + if (file_extension) { + sprintf(tmpfile, "%s/.cur_input.%s", tmp_dir, file_extension); + } else { + sprintf(tmpfile, "%s/.cur_input", tmp_dir); + } + if (access(tmpfile, F_OK) != + -1) // there is still a race condition here, but well ... + FATAL("AFL_TMPDIR already has an existing temporary input file: %s - if this is not from another instance, then just remove the file.", + tmpfile); + + } else + + tmp_dir = out_dir; + + /* If we don't have a file name chosen yet, use a safe default. */ if (!out_file) { @@ -881,7 +883,12 @@ int main(int argc, char** argv, char** envp) { if (!out_file) setup_stdio_file(); - if (cmplog_binary) check_binary(cmplog_binary); + if (cmplog_binary) { + if (unicorn_mode) + FATAL("CmpLog and Unicorn mode are not compatible at the moment, sorry"); + if (!qemu_mode) + check_binary(cmplog_binary); + } check_binary(argv[optind]); start_time = get_cur_time(); diff --git a/src/afl-gcc.c b/src/afl-gcc.c index 51c78843..ff53cc8d 100644 --- a/src/afl-gcc.c +++ b/src/afl-gcc.c @@ -342,11 +342,37 @@ static void edit_params(u32 argc, char** argv) { int main(int argc, char** argv) { + char *env_info = + "Environment variables used by afl-gcc:\n" + "AFL_CC: path to the C compiler to use\n" + "AFL_CXX: path to the C++ compiler to use\n" + "AFL_GCJ: path to the java compiler to use\n" + "AFL_PATH: path to the instrumenting assembler\n" + "AFL_DONT_OPTIMIZE: disable optimization instead of -O3\n" + "AFL_NO_BUILTIN: compile for use with libtokencap.so\n" + "AFL_QUIET: suppress verbose output\n" + "AFL_CAL_FAST: speed up the initial calibration\n" + "AFL_HARDEN: adds code hardening to catch memory bugs\n" + "AFL_USE_ASAN: activate address sanitizer\n" + "AFL_USE_MSAN: activate memory sanitizer\n" + "AFL_USE_UBSAN: activate undefined behaviour sanitizer\n" + + "\nEnvironment variables used by afl-as (called by afl-gcc):\n" + "AFL_AS: path to the assembler to use\n" + "TMPDIR: set the directory for temporary files of afl-as\n" + "TEMP: fall back path to directory for temporary files\n" + "TMP: fall back path to directory for temporary files\n" + "AFL_INST_RATIO: percentage of branches to instrument\n" + "AFL_QUIET: suppress verbose output\n" + "AFL_KEEP_ASSEMBLY: leave instrumented assembly files\n" + "AFL_AS_FORCE_INSTRUMENT: force instrumentation for asm sources\n" + ; + if (argc == 2 && strcmp(argv[1], "-h") == 0) { printf("afl-cc" VERSION " by Michal Zalewski\n\n"); printf("%s \n\n", argv[0]); - printf("afl-gcc has no command line options\n"); + printf("afl-gcc has no command line options\n\n%s", env_info); printf( "NOTE: afl-gcc is deprecated, llvm_mode is much faster and has more " "options\n"); @@ -382,32 +408,9 @@ int main(int argc, char** argv) { "You can specify custom next-stage toolchain via AFL_CC, AFL_CXX, and " "AFL_AS.\n" "Setting AFL_HARDEN enables hardening optimizations in the compiled " - "code.\n\n" + "code.\n\n%s" - "Environment variables used by afl-gcc:\n" - "AFL_CC: path to the C compiler to use\n" - "AFL_CXX: path to the C++ compiler to use\n" - "AFL_GCJ: path to the java compiler to use\n" - "AFL_PATH: path to the instrumenting assembler\n" - "AFL_DONT_OPTIMIZE: disable optimization instead of -O3\n" - "AFL_NO_BUILTIN: compile for use with libtokencap.so\n" - "AFL_QUIET: suppress verbose output\n" - "AFL_CAL_FAST: speed up the initial calibration\n" - "AFL_HARDEN: adds code hardening to catch memory bugs\n" - "AFL_USE_ASAN: activate address sanitizer\n" - "AFL_USE_MSAN: activate memory sanitizer\n" - "AFL_USE_UBSAN: activate undefined behaviour sanitizer\n" - - "\nEnvironment variables used by afl-as (called by afl-gcc):\n" - "AFL_AS: path to the assembler to use\n" - "TMPDIR: set the directory for temporary files of afl-as\n" - "TEMP: fall back path to directory for temporary files\n" - "TMP: fall back path to directory for temporary files\n" - "AFL_INST_RATIO: percentage of branches to instrument\n" - "AFL_QUIET: suppress verbose output\n" - "AFL_KEEP_ASSEMBLY: leave instrumented assembly files\n" - "AFL_AS_FORCE_INSTRUMENT: force instrumentation for asm sources\n" - , BIN_PATH, BIN_PATH); + , BIN_PATH, BIN_PATH, env_info); exit(1); diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 99022983..a46645ab 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -162,7 +162,7 @@ static void classify_counts(u8* mem, const u8* map) { static void at_exit_handler(void) { - if (out_file) unlink(out_file); /* Ignore errors */ + if (stdin_file) unlink(stdin_file); } @@ -949,7 +949,7 @@ int main(int argc, char** argv, char** envp) { } - stdin_file = alloc_printf("%s/.afl-tmin-temp-%u", use_dir, getpid()); + stdin_file = alloc_printf("%s/.afl-showmap-temp-%u", use_dir, getpid()); unlink(stdin_file); atexit(at_exit_handler); out_fd = open(stdin_file, O_RDWR | O_CREAT | O_EXCL, 0600); @@ -1014,6 +1014,13 @@ int main(int argc, char** argv, char** envp) { tcnt, highest, total, out_file); } + + if (stdin_file) { + + unlink(stdin_file); + stdin_file = NULL; + + } exit(child_crashed * 2 + child_timed_out); diff --git a/test/test.sh b/test/test.sh index ad775bd8..13fba6cc 100755 --- a/test/test.sh +++ b/test/test.sh @@ -65,6 +65,8 @@ unset AFL_PYTHON_MODULE unset AFL_PRELOAD unset LD_PRELOAD +export ASAN_OPTIONS=detect_leaks=0:allocator_may_return_null=1:abort_on_error=1:symbolize=0 + # on OpenBSD we need to work with llvm from /usr/local/bin test -e /usr/local/bin/opt && { export PATH=/usr/local/bin:${PATH} @@ -85,7 +87,7 @@ RED="\\033[0;31m" YELLOW="\\033[1;93m" RESET="\\033[0m" -MEM_LIMIT=150 +MEM_LIMIT=none export PATH=$PATH:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin @@ -170,7 +172,7 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc echo 000000000000000000000000 > in/in2 echo 111 > in/in3 mkdir -p in2 - ../afl-cmin -i in -o in2 -- ./test-instr.plain >/dev/null 2>&1 # why is afl-forkserver writing to stderr? + ../afl-cmin -m ${MEM_LIMIT} -i in -o in2 -- ./test-instr.plain >/dev/null 2>&1 # why is afl-forkserver writing to stderr? CNT=`ls in2/* 2>/dev/null | wc -l` case "$CNT" in *2) $ECHO "$GREEN[+] afl-cmin correctly minimized the number of testcases" ;; @@ -179,7 +181,7 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc ;; esac rm -f in2/in* - AFL_PATH=`pwd`/.. ../afl-cmin.bash -i in -o in2 -- ./test-instr.plain >/dev/null + AFL_PATH=`pwd`/.. ../afl-cmin.bash -m ${MEM_LIMIT} -i in -o in2 -- ./test-instr.plain >/dev/null CNT=`ls in2/* 2>/dev/null | wc -l` case "$CNT" in *2) $ECHO "$GREEN[+] afl-cmin.bash correctly minimized the number of testcases" ;; @@ -187,7 +189,7 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc CODE=1 ;; esac - ../afl-tmin -i in/in2 -o in2/in2 -- ./test-instr.plain > /dev/null 2>&1 + ../afl-tmin -m ${MEM_LIMIT} -i in/in2 -o in2/in2 -- ./test-instr.plain > /dev/null 2>&1 SIZE=`ls -l in2/in2 2> /dev/null | awk '{print$5}'` test "$SIZE" = 1 && $ECHO "$GREEN[+] afl-tmin correctly minimized the testcase" test "$SIZE" = 1 || { @@ -228,7 +230,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && { } || { $ECHO "$GREEN[+] llvm_mode instrumentation present and working correctly" TUPLES=`echo 0|../afl-showmap -m ${MEM_LIMIT} -o /dev/null -- ./test-instr.plain 2>&1 | grep Captur | awk '{print$3}'` - test "$TUPLES" -gt 3 -a "$TUPLES" -lt 6 && { + test "$TUPLES" -gt 3 -a "$TUPLES" -lt 7 && { $ECHO "$GREEN[+] llvm_mode run reported $TUPLES instrumented locations which is fine" } || { $ECHO "$RED[!] llvm_mode instrumentation produces weird numbers: $TUPLES" @@ -286,7 +288,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && { echo 000000000000000000000000 > in/in2 echo 111 > in/in3 mkdir -p in2 - ../afl-cmin -i in -o in2 -- ./test-instr.plain >/dev/null 2>&1 # why is afl-forkserver writing to stderr? + ../afl-cmin -m ${MEM_LIMIT} -i in -o in2 -- ./test-instr.plain >/dev/null 2>&1 # why is afl-forkserver writing to stderr? CNT=`ls in2/* 2>/dev/null | wc -l` case "$CNT" in *2) $ECHO "$GREEN[+] afl-cmin correctly minimized the number of testcases" ;; @@ -295,7 +297,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && { ;; esac rm -f in2/in* - AFL_PATH=`pwd`/.. ../afl-cmin.bash -i in -o in2 -- ./test-instr.plain >/dev/null + AFL_PATH=`pwd`/.. ../afl-cmin.bash -m ${MEM_LIMIT} -i in -o in2 -- ./test-instr.plain >/dev/null CNT=`ls in2/* 2>/dev/null | wc -l` case "$CNT" in *2) $ECHO "$GREEN[+] afl-cmin.bash correctly minimized the number of testcases" ;; @@ -303,7 +305,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && { CODE=1 ;; esac - ../afl-tmin -i in/in2 -o in2/in2 -- ./test-instr.plain > /dev/null 2>&1 + ../afl-tmin -m ${MEM_LIMIT} -i in/in2 -o in2/in2 -- ./test-instr.plain > /dev/null 2>&1 SIZE=`ls -l in2/in2 2> /dev/null | awk '{print$5}'` test "$SIZE" = 1 && $ECHO "$GREEN[+] afl-tmin correctly minimized the testcase" test "$SIZE" = 1 || { @@ -359,7 +361,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && { rm -f test-compcov test.out whitelist.txt ../afl-clang-fast -o test-persistent ../examples/persistent_demo/persistent_demo.c > /dev/null 2>&1 test -e test-persistent && { - echo foo | ../afl-showmap -o /dev/null -q -r ./test-persistent && { + echo foo | ../afl-showmap -m ${MEM_LIMIT} -o /dev/null -q -r ./test-persistent && { $ECHO "$GREEN[+] llvm_mode persistent mode feature works correctly" } || { $ECHO "$RED[!] llvm_mode persistent mode feature failed to work" @@ -468,7 +470,7 @@ test -e ../afl-gcc-fast -a -e ../afl-gcc-rt.o && { rm -f test-compcov test.out whitelist.txt ../afl-gcc-fast -o test-persistent ../examples/persistent_demo/persistent_demo.c > /dev/null 2>&1 test -e test-persistent && { - echo foo | ../afl-showmap -o /dev/null -q -r ./test-persistent && { + echo foo | ../afl-showmap -m ${MEM_LIMIT} -o /dev/null -q -r ./test-persistent && { $ECHO "$GREEN[+] gcc_plugin persistent mode feature works correctly" } || { $ECHO "$RED[!] gcc_plugin persistent mode feature failed to work" @@ -566,7 +568,7 @@ test -e ../afl-qemu-trace && { echo 0 > in/in $ECHO "$GREY[*] running afl-fuzz for qemu_mode, this will take approx 10 seconds" { - ../afl-fuzz -V10 -Q -i in -o out -- ./test-instr >>errors 2>&1 + ../afl-fuzz -m ${MEM_LIMIT} -V10 -Q -i in -o out -- ./test-instr >>errors 2>&1 } >>errors 2>&1 test -n "$( ls out/queue/id:000002* 2> /dev/null )" && { $ECHO "$GREEN[+] afl-fuzz is working correctly with qemu_mode" @@ -585,7 +587,7 @@ test -e ../afl-qemu-trace && { { export AFL_PRELOAD=../libcompcov.so export AFL_COMPCOV_LEVEL=2 - ../afl-fuzz -V10 -Q -i in -o out -- ./test-compcov >>errors 2>&1 + ../afl-fuzz -m ${MEM_LIMIT} -V10 -Q -i in -o out -- ./test-compcov >>errors 2>&1 } >>errors 2>&1 test -n "$( ls out/queue/id:000002* 2> /dev/null )" && { $ECHO "$GREEN[+] afl-fuzz is working correctly with qemu_mode libcompcov" @@ -609,7 +611,7 @@ test -e ../afl-qemu-trace && { export AFL_QEMU_PERSISTENT_GPR=1 $ECHO "Info: AFL_QEMU_PERSISTENT_ADDR=$AFL_QEMU_PERSISTENT_ADDR <= $(nm test-instr | grep "T main" | awk '{print $1}')" file test-instr - ../afl-fuzz -V10 -Q -i in -o out -- ./test-instr + ../afl-fuzz -m ${MEM_LIMIT} -V10 -Q -i in -o out -- ./test-instr } >>errors 2>&1 test -n "$( ls out/queue/id:000002* 2> /dev/null )" && { $ECHO "$GREEN[+] afl-fuzz is working correctly with persistent qemu_mode" @@ -723,7 +725,7 @@ test -d ../unicorn_mode/unicornafl && { { $ECHO "$GREY[*] running afl-fuzz for unicorn_mode, this will take approx 25 seconds" { - ../afl-fuzz -V25 -U -i in -o out -d -- "$PY" ../unicorn_mode/samples/simple/simple_test_harness.py @@ >>errors 2>&1 + ../afl-fuzz -m ${MEM_LIMIT} -V25 -U -i in -o out -d -- "$PY" ../unicorn_mode/samples/simple/simple_test_harness.py @@ >>errors 2>&1 } >>errors 2>&1 test -n "$( ls out/queue/id:000002* 2> /dev/null )" && { $ECHO "$GREEN[+] afl-fuzz is working correctly with unicorn_mode" @@ -742,7 +744,7 @@ test -d ../unicorn_mode/unicornafl && { $ECHO "$GREY[*] running afl-fuzz for unicorn_mode compcov, this will take approx 35 seconds" { export AFL_COMPCOV_LEVEL=2 - ../afl-fuzz -V35 -U -i in -o out -d -- "$PY" ../unicorn_mode/samples/compcov_x64/compcov_test_harness.py @@ >>errors 2>&1 + ../afl-fuzz -m ${MEM_LIMIT} -V35 -U -i in -o out -d -- "$PY" ../unicorn_mode/samples/compcov_x64/compcov_test_harness.py @@ >>errors 2>&1 } >>errors 2>&1 test -n "$( ls out/queue/id:000001* 2> /dev/null )" && { $ECHO "$GREEN[+] afl-fuzz is working correctly with unicorn_mode compcov" |