From c05e4efbe9b4e7d1ff078b7a392621f2ca7572e6 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 1 Dec 2020 14:40:30 +0100 Subject: renamed examples/ to utils/ --- utils/persistent_mode/Makefile | 10 +++ utils/persistent_mode/persistent_demo.c | 112 ++++++++++++++++++++++++++ utils/persistent_mode/persistent_demo_new.c | 117 ++++++++++++++++++++++++++++ utils/persistent_mode/test-instr.c | 69 ++++++++++++++++ 4 files changed, 308 insertions(+) create mode 100644 utils/persistent_mode/Makefile create mode 100644 utils/persistent_mode/persistent_demo.c create mode 100644 utils/persistent_mode/persistent_demo_new.c create mode 100644 utils/persistent_mode/test-instr.c (limited to 'utils/persistent_mode') diff --git a/utils/persistent_mode/Makefile b/utils/persistent_mode/Makefile new file mode 100644 index 00000000..6fa1c30e --- /dev/null +++ b/utils/persistent_mode/Makefile @@ -0,0 +1,10 @@ +all: + afl-clang-fast -o persistent_demo persistent_demo.c + afl-clang-fast -o persistent_demo_new persistent_demo_new.c + AFL_DONT_OPTIMIZE=1 afl-clang-fast -o test-instr test-instr.c + +document: + AFL_DONT_OPTIMIZE=1 afl-clang-fast -D_AFL_DOCUMENT_MUTATIONS -o test-instr test-instr.c + +clean: + rm -f persistent_demo persistent_demo_new test-instr diff --git a/utils/persistent_mode/persistent_demo.c b/utils/persistent_mode/persistent_demo.c new file mode 100644 index 00000000..4cedc32c --- /dev/null +++ b/utils/persistent_mode/persistent_demo.c @@ -0,0 +1,112 @@ +/* + american fuzzy lop++ - persistent mode example + -------------------------------------------- + + Originally written by Michal Zalewski + + Copyright 2015 Google Inc. 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 file demonstrates the high-performance "persistent mode" that may be + suitable for fuzzing certain fast and well-behaved libraries, provided that + they are stateless or that their internal state can be easily reset + across runs. + + To make this work, the library and this shim need to be compiled in LLVM + mode using afl-clang-fast (other compiler wrappers will *not* work). + + */ + +#include +#include +#include +#include +#include + +/* Main entry point. */ + +int main(int argc, char **argv) { + + ssize_t len; /* how much input did we read? */ + char buf[100]; /* Example-only buffer, you'd replace it with other global or + local variables appropriate for your use case. */ + + /* The number passed to __AFL_LOOP() controls the maximum number of + iterations before the loop exits and the program is allowed to + terminate normally. This limits the impact of accidental memory leaks + and similar hiccups. */ + + __AFL_INIT(); + while (__AFL_LOOP(1000)) { + + /*** PLACEHOLDER CODE ***/ + + /* STEP 1: Fully re-initialize all critical variables. In our example, this + involves zeroing buf[], our input buffer. */ + + memset(buf, 0, 100); + + /* STEP 2: Read input data. When reading from stdin, no special preparation + is required. When reading from a named file, you need to close + the old descriptor and reopen the file first! + + Beware of reading from buffered FILE* objects such as stdin. Use + raw file descriptors or call fopen() / fdopen() in every pass. */ + + len = read(0, buf, 100); + + /* STEP 3: This is where we'd call the tested library on the read data. + We just have some trivial inline code that faults on 'foo!'. */ + + /* do we have enough data? */ + if (len < 8) continue; + + if (buf[0] == 'f') { + + printf("one\n"); + if (buf[1] == 'o') { + + printf("two\n"); + if (buf[2] == 'o') { + + printf("three\n"); + if (buf[3] == '!') { + + printf("four\n"); + if (buf[4] == '!') { + + printf("five\n"); + if (buf[5] == '!') { + + printf("six\n"); + abort(); + + } + + } + + } + + } + + } + + } + + /*** END PLACEHOLDER CODE ***/ + + } + + /* Once the loop is exited, terminate normally - AFL will restart the process + when this happens, with a clean slate when it comes to allocated memory, + leftover file descriptors, etc. */ + + return 0; + +} + diff --git a/utils/persistent_mode/persistent_demo_new.c b/utils/persistent_mode/persistent_demo_new.c new file mode 100644 index 00000000..a29792ff --- /dev/null +++ b/utils/persistent_mode/persistent_demo_new.c @@ -0,0 +1,117 @@ +/* + american fuzzy lop++ - persistent mode example + -------------------------------------------- + + Originally written by Michal Zalewski + + Copyright 2015 Google Inc. 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 file demonstrates the high-performance "persistent mode" that may be + suitable for fuzzing certain fast and well-behaved libraries, provided that + they are stateless or that their internal state can be easily reset + across runs. + + To make this work, the library and this shim need to be compiled in LLVM + mode using afl-clang-fast (other compiler wrappers will *not* work). + + */ + +#include +#include +#include +#include +#include + +/* this lets the source compile without afl-clang-fast/lto */ +#ifndef __AFL_FUZZ_TESTCASE_LEN + +ssize_t fuzz_len; +unsigned char fuzz_buf[1024000]; + + #define __AFL_FUZZ_TESTCASE_LEN fuzz_len + #define __AFL_FUZZ_TESTCASE_BUF fuzz_buf + #define __AFL_FUZZ_INIT() void sync(void); + #define __AFL_LOOP(x) \ + ((fuzz_len = read(0, fuzz_buf, sizeof(fuzz_buf))) > 0 ? 1 : 0) + #define __AFL_INIT() sync() + +#endif + +__AFL_FUZZ_INIT(); + +/* Main entry point. */ + +int main(int argc, char **argv) { + + ssize_t len; /* how much input did we read? */ + unsigned char *buf; /* test case buffer pointer */ + + /* The number passed to __AFL_LOOP() controls the maximum number of + iterations before the loop exits and the program is allowed to + terminate normally. This limits the impact of accidental memory leaks + and similar hiccups. */ + + __AFL_INIT(); + buf = __AFL_FUZZ_TESTCASE_BUF; // this must be assigned before __AFL_LOOP! + + while (__AFL_LOOP(1000)) { // increase if you have good stability + + len = __AFL_FUZZ_TESTCASE_LEN; // do not use the macro directly in a call! + + fprintf(stderr, "input: %zd \"%s\"\n", len, buf); + + /* do we have enough data? */ + if (len < 8) continue; + + if (strcmp((char *)buf, "thisisateststring") == 0) printf("teststring\n"); + + if (buf[0] == 'f') { + + printf("one\n"); + if (buf[1] == 'o') { + + printf("two\n"); + if (buf[2] == 'o') { + + printf("three\n"); + if (buf[3] == '!') { + + printf("four\n"); + if (buf[4] == '!') { + + printf("five\n"); + if (buf[6] == '!') { + + printf("six\n"); + abort(); + + } + + } + + } + + } + + } + + } + + /*** END PLACEHOLDER CODE ***/ + + } + + /* Once the loop is exited, terminate normally - AFL will restart the process + when this happens, with a clean slate when it comes to allocated memory, + leftover file descriptors, etc. */ + + return 0; + +} + diff --git a/utils/persistent_mode/test-instr.c b/utils/persistent_mode/test-instr.c new file mode 100644 index 00000000..a6188b22 --- /dev/null +++ b/utils/persistent_mode/test-instr.c @@ -0,0 +1,69 @@ +/* + american fuzzy lop++ - a trivial program to test the build + -------------------------------------------------------- + Originally written by Michal Zalewski + Copyright 2014 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 + */ + +#include +#include +#include +#include +#include +#include +#include + +__AFL_FUZZ_INIT(); + +int main(int argc, char **argv) { + + __AFL_INIT(); + unsigned char *buf = __AFL_FUZZ_TESTCASE_BUF; + + while (__AFL_LOOP(2147483647)) { // MAX_INT if you have 100% stability + + unsigned int len = __AFL_FUZZ_TESTCASE_LEN; + +#ifdef _AFL_DOCUMENT_MUTATIONS + static unsigned int counter = 0; + char fn[32]; + sprintf(fn, "%09u:test-instr", counter); + int fd_doc = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600); + if (fd_doc >= 0) { + + if (write(fd_doc, buf, len) != __afl_fuzz_len) { + + fprintf(stderr, "write of mutation file failed: %s\n", fn); + unlink(fn); + + } + + close(fd_doc); + + } + + counter++; +#endif + + // fprintf(stderr, "len: %u\n", len); + + if (!len) continue; + + if (buf[0] == '0') + printf("Looks like a zero to me!\n"); + else if (buf[0] == '1') + printf("Pretty sure that is a one!\n"); + else + printf("Neither one or zero? How quaint!\n"); + + } + + return 0; + +} + -- cgit 1.4.1 From 6e61b2345cc35f101bac7594089dc57999f33b89 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 8 Dec 2020 20:33:41 +0100 Subject: more reporting on errors --- instrumentation/afl-compiler-rt.o.c | 25 +++++++++++++++++++++++-- src/afl-forkserver.c | 7 +++++++ utils/persistent_mode/persistent_demo_new.c | 2 +- 3 files changed, 31 insertions(+), 3 deletions(-) (limited to 'utils/persistent_mode') diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index b07aeb83..e29c4483 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -163,6 +163,12 @@ static void __afl_map_shm_fuzz() { char *id_str = getenv(SHM_FUZZ_ENV_VAR); + if (getenv("AFL_DEBUG")) { + + fprintf(stderr, "DEBUG: fuzzcase shmem %s\n", id_str ? id_str : "none"); + + } + if (id_str) { u8 *map = NULL; @@ -196,6 +202,7 @@ static void __afl_map_shm_fuzz() { if (!map || map == (void *)-1) { perror("Could not access fuzzing shared memory"); + send_forkserver_error(FS_ERROR_SHM_OPEN); exit(1); } @@ -212,6 +219,7 @@ static void __afl_map_shm_fuzz() { } else { fprintf(stderr, "Error: variable for fuzzing shared memory is not set\n"); + send_forkserver_error(FS_ERROR_SHM_OPEN); exit(1); } @@ -335,6 +343,8 @@ static void __afl_map_shm(void) { send_forkserver_error(FS_ERROR_MAP_ADDR); else send_forkserver_error(FS_ERROR_MMAP); + perror("shmat for map"); + exit(2); } @@ -349,12 +359,14 @@ static void __afl_map_shm(void) { /* Whooooops. */ - if (__afl_area_ptr == (void *)-1) { + if (!__afl_area_ptr || __afl_area_ptr == (void *)-1) { if (__afl_map_addr) send_forkserver_error(FS_ERROR_MAP_ADDR); else send_forkserver_error(FS_ERROR_SHMAT); + + perror("shmat for map"); _exit(1); } @@ -376,6 +388,7 @@ static void __afl_map_shm(void) { fprintf(stderr, "can not acquire mmap for address %p\n", (void *)__afl_map_addr); + send_forkserver_error(FS_ERROR_SHM_OPEN); exit(1); } @@ -411,6 +424,7 @@ static void __afl_map_shm(void) { if (shm_fd == -1) { fprintf(stderr, "shm_open() failed\n"); + send_forkserver_error(FS_ERROR_SHM_OPEN); exit(1); } @@ -424,6 +438,7 @@ static void __afl_map_shm(void) { shm_fd = -1; fprintf(stderr, "mmap() failed\n"); + send_forkserver_error(FS_ERROR_SHM_OPEN); exit(2); } @@ -435,7 +450,13 @@ static void __afl_map_shm(void) { __afl_cmp_map = shmat(shm_id, NULL, 0); #endif - if (__afl_cmp_map == (void *)-1) _exit(1); + if (!__afl_cmp_map || __afl_cmp_map == (void *)-1) { + + perror("shmat for cmplog"); + send_forkserver_error(FS_ERROR_SHM_OPEN); + _exit(1); + + } } diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 20117c1d..b1c29ba6 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -1069,6 +1069,13 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, if (fsrv->child_pid <= 0) { if (*stop_soon_p) { return 0; } + + if ((fsrv->child_pid & FS_OPT_ERROR) && + FS_OPT_GET_ERROR(fsrv->child_pid) == FS_ERROR_SHM_OPEN) + FATAL( + "Target reported shared memory access failed (perhaps increase " + "shared memory available)."); + FATAL("Fork server is misbehaving (OOM?)"); } diff --git a/utils/persistent_mode/persistent_demo_new.c b/utils/persistent_mode/persistent_demo_new.c index a29792ff..0d24a51e 100644 --- a/utils/persistent_mode/persistent_demo_new.c +++ b/utils/persistent_mode/persistent_demo_new.c @@ -86,7 +86,7 @@ int main(int argc, char **argv) { if (buf[4] == '!') { printf("five\n"); - if (buf[6] == '!') { + if (buf[5] == '!') { printf("six\n"); abort(); -- cgit 1.4.1