From d9ff84e39ecad47deec8808ea127fd90d9f5e8ef Mon Sep 17 00:00:00 2001 From: Heiko Eißfeldt Date: Sun, 30 Jun 2019 10:06:20 +0200 Subject: Refactor to use an alternative method for shared memory. If USEMMAP is defined, the shared memory segment is created/attached etc. now by shm_open() and mmap(). This API is hopefully more often available (at least for iOS). In order to reduce code duplication I have added new files sharedmem.[ch] which now encapsulate the shared memory method. This is based on the work of Proteas to support iOS fuzzing (thanks). https://github.com/Proteas/afl-ios/commit/866af8ad1cb230d5d753b546380a4af1e55d6946 Currently this is in an experimental status yet. Please report whether this variant works on 32 and 64 bit and on the supported platforms. This branch enables USEMMAP and has been tested on Linux. There is no auto detection for the mmap API yet. --- afl-showmap.c | 41 ++++------------------------------------- 1 file changed, 4 insertions(+), 37 deletions(-) (limited to 'afl-showmap.c') diff --git a/afl-showmap.c b/afl-showmap.c index 316490d8..a5d7568a 100644 --- a/afl-showmap.c +++ b/afl-showmap.c @@ -28,6 +28,7 @@ #include "debug.h" #include "alloc-inl.h" #include "hash.h" +#include "sharedmem.h" #include #include @@ -48,7 +49,7 @@ static s32 child_pid; /* PID of the tested program */ -static u8* trace_bits; /* SHM with instrumentation bitmap */ + u8* trace_bits; /* SHM with instrumentation bitmap */ static u8 *out_file, /* Trace output file */ *doc_path, /* Path to docs */ @@ -59,8 +60,6 @@ static u32 exec_tmout; /* Exec timeout (ms) */ static u64 mem_limit = MEM_LIMIT; /* Memory limit (MB) */ -static s32 shm_id; /* ID of the SHM region */ - static u8 quiet_mode, /* Hide non-essential messages? */ edges_only, /* Ignore hit counts? */ cmin_mode, /* Generate output in afl-cmin mode? */ @@ -72,6 +71,7 @@ static volatile u8 child_timed_out, /* Child timed out? */ child_crashed; /* Child crashed? */ + /* Classify tuple counts. Instead of mapping to individual bits, as in afl-fuzz.c, we map to more user-friendly numbers between 1 and 8. */ @@ -126,39 +126,6 @@ static void classify_counts(u8* mem, const u8* map) { } -/* Get rid of shared memory (atexit handler). */ - -static void remove_shm(void) { - - shmctl(shm_id, IPC_RMID, NULL); - -} - - -/* Configure shared memory. */ - -static void setup_shm(void) { - - u8* shm_str; - - shm_id = shmget(IPC_PRIVATE, MAP_SIZE, IPC_CREAT | IPC_EXCL | 0600); - - if (shm_id < 0) PFATAL("shmget() failed"); - - atexit(remove_shm); - - shm_str = alloc_printf("%d", shm_id); - - setenv(SHM_ENV_VAR, shm_str, 1); - - ck_free(shm_str); - - trace_bits = shmat(shm_id, NULL, 0); - - if (!trace_bits) PFATAL("shmat() failed"); - -} - /* Write results. */ static u32 write_results(void) { @@ -741,7 +708,7 @@ int main(int argc, char** argv) { if (optind == argc || !out_file) usage(argv[0]); - setup_shm(); + setup_shm(0); setup_signal_handlers(); set_up_environment(); -- cgit 1.4.1 From f45332e1ab1f7b82c38c6fcc3c451fca35d5a9ce Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 13 Jul 2019 08:09:19 +0200 Subject: portability fix: getcwd(NULL, 0) is a non-POSIX glibc extension. Refactor detect_file_args() in a separate file in order to avoid multiple copies. --- Makefile | 11 +++++---- afl-analyze.c | 45 ++--------------------------------- afl-common.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++ afl-common.h | 5 ++++ afl-fuzz.c | 76 ++++++++++++++++++----------------------------------------- afl-showmap.c | 47 ++---------------------------------- afl-tmin.c | 45 ++--------------------------------- 7 files changed, 110 insertions(+), 188 deletions(-) create mode 100644 afl-common.c create mode 100644 afl-common.h (limited to 'afl-showmap.c') diff --git a/Makefile b/Makefile index cb3beb11..7c151f8b 100644 --- a/Makefile +++ b/Makefile @@ -131,20 +131,23 @@ afl-as: afl-as.c afl-as.h $(COMM_HDR) | test_x86 $(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS) ln -sf afl-as as +afl-common.o : afl-common.c + $(CC) $(CFLAGS) -c afl-common.c + sharedmem.o : sharedmem.c $(CC) $(CFLAGS) -c sharedmem.c afl-fuzz: afl-fuzz.c sharedmem.o $(COMM_HDR) | test_x86 - $(CC) $(CFLAGS) $@.c sharedmem.o -o $@ $(LDFLAGS) $(PYFLAGS) + $(CC) $(CFLAGS) $@.c afl-common.o sharedmem.o -o $@ $(LDFLAGS) $(PYFLAGS) afl-showmap: afl-showmap.c sharedmem.o $(COMM_HDR) | test_x86 - $(CC) $(CFLAGS) $@.c sharedmem.o -o $@ $(LDFLAGS) + $(CC) $(CFLAGS) $@.c afl-common.o sharedmem.o -o $@ $(LDFLAGS) afl-tmin: afl-tmin.c sharedmem.o $(COMM_HDR) | test_x86 - $(CC) $(CFLAGS) $@.c sharedmem.o -o $@ $(LDFLAGS) + $(CC) $(CFLAGS) $@.c afl-common.o sharedmem.o -o $@ $(LDFLAGS) afl-analyze: afl-analyze.c sharedmem.o $(COMM_HDR) | test_x86 - $(CC) $(CFLAGS) $@.c sharedmem.o -o $@ $(LDFLAGS) + $(CC) $(CFLAGS) $@.c afl-common.o sharedmem.o -o $@ $(LDFLAGS) afl-gotcpu: afl-gotcpu.c $(COMM_HDR) | test_x86 $(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS) diff --git a/afl-analyze.c b/afl-analyze.c index 834a0357..be470317 100644 --- a/afl-analyze.c +++ b/afl-analyze.c @@ -27,6 +27,7 @@ #include "alloc-inl.h" #include "hash.h" #include "sharedmem.h" +#include "afl-common.h" #include #include @@ -725,48 +726,6 @@ static void setup_signal_handlers(void) { } -/* Detect @@ in args. */ - -static void detect_file_args(char** argv) { - - u32 i = 0; - u8* cwd = getcwd(NULL, 0); - - if (!cwd) PFATAL("getcwd() failed"); - - while (argv[i]) { - - u8* aa_loc = strstr(argv[i], "@@"); - - if (aa_loc) { - - u8 *aa_subst, *n_arg; - - /* Be sure that we're always using fully-qualified paths. */ - - if (prog_in[0] == '/') aa_subst = prog_in; - else aa_subst = alloc_printf("%s/%s", cwd, prog_in); - - /* Construct a replacement argv value. */ - - *aa_loc = 0; - n_arg = alloc_printf("%s%s%s", argv[i], aa_subst, aa_loc + 2); - argv[i] = n_arg; - *aa_loc = '@'; - - if (prog_in[0] != '/') ck_free(aa_subst); - - } - - i++; - - } - - free(cwd); /* not tracked */ - -} - - /* Display usage hints. */ static void usage(u8* argv0) { @@ -1018,7 +977,7 @@ int main(int argc, char** argv) { set_up_environment(); find_binary(argv[optind]); - detect_file_args(argv + optind); + detect_file_args(argv + optind, prog_in); if (qemu_mode) use_argv = get_qemu_argv(argv[0], argv + optind, argc - optind); diff --git a/afl-common.c b/afl-common.c new file mode 100644 index 00000000..ea3bfa6c --- /dev/null +++ b/afl-common.c @@ -0,0 +1,69 @@ +/* + gather some functions common to multiple executables + + detect_file_args + */ + +#include +#include +#include + +#include "debug.h" +#include "alloc-inl.h" + +/* Detect @@ in args. */ +#ifndef __glibc__ +#include +#endif +void detect_file_args(char** argv, u8* prog_in) { + + u32 i = 0; +#ifdef __glibc__ + u8* cwd = getcwd(NULL, 0); /* non portable glibc extension */ +#else + u8* cwd; + char *buf; + long size = pathconf(".", _PC_PATH_MAX); + if ((buf = (char *)malloc((size_t)size)) != NULL) { + cwd = getcwd(buf, (size_t)size); /* portable version */ + } else { + PFATAL("getcwd() failed"); + } +#endif + + if (!cwd) PFATAL("getcwd() failed"); + + while (argv[i]) { + + u8* aa_loc = strstr(argv[i], "@@"); + + if (aa_loc) { + + u8 *aa_subst, *n_arg; + + if (!prog_in) FATAL("@@ syntax is not supported by this tool."); + + /* Be sure that we're always using fully-qualified paths. */ + + if (prog_in[0] == '/') aa_subst = prog_in; + else aa_subst = alloc_printf("%s/%s", cwd, prog_in); + + /* Construct a replacement argv value. */ + + *aa_loc = 0; + n_arg = alloc_printf("%s%s%s", argv[i], aa_subst, aa_loc + 2); + argv[i] = n_arg; + *aa_loc = '@'; + + if (prog_in[0] != '/') ck_free(aa_subst); + + } + + i++; + + } + + free(cwd); /* not tracked */ + +} + diff --git a/afl-common.h b/afl-common.h new file mode 100644 index 00000000..07afb75d --- /dev/null +++ b/afl-common.h @@ -0,0 +1,5 @@ +#ifndef __AFLCOMMON_H +#define __AFLCOMMON_H + +void detect_file_args(char **argv, u8 *prog_in); +#endif diff --git a/afl-fuzz.c b/afl-fuzz.c index af507c88..2e4b28e0 100644 --- a/afl-fuzz.c +++ b/afl-fuzz.c @@ -32,6 +32,7 @@ #include "alloc-inl.h" #include "hash.h" #include "sharedmem.h" +#include "afl-common.h" #include #include @@ -8068,58 +8069,6 @@ static void check_asan_opts(void) { } -/* Detect @@ in args. */ - -EXP_ST void detect_file_args(char** argv) { - - u32 i = 0; - u8* cwd = getcwd(NULL, 0); - - if (!cwd) PFATAL("getcwd() failed"); - - while (argv[i]) { - - u8* aa_loc = strstr(argv[i], "@@"); - - if (aa_loc) { - - u8 *aa_subst, *n_arg; - - /* If we don't have a file name chosen yet, use a safe default. */ - - if (!out_file) { - if (file_extension) { - out_file = alloc_printf("%s/.cur_input.%s", out_dir, file_extension); - } else { - out_file = alloc_printf("%s/.cur_input", out_dir); - } - } - - /* Be sure that we're always using fully-qualified paths. */ - - if (out_file[0] == '/') aa_subst = out_file; - else aa_subst = alloc_printf("%s/%s", cwd, out_file); - - /* Construct a replacement argv value. */ - - *aa_loc = 0; - n_arg = alloc_printf("%s%s%s", argv[i], aa_subst, aa_loc + 2); - argv[i] = n_arg; - *aa_loc = '@'; - - if (out_file[0] != '/') ck_free(aa_subst); - - } - - i++; - - } - - free(cwd); /* not tracked */ - -} - - /* Set up signal handlers. More complicated that needs to be, because libc on Solaris doesn't resume interrupted reads(), sets SA_RESETHAND when you call siginterrupt(), and does other stupid things. */ @@ -8628,7 +8577,28 @@ int main(int argc, char** argv) { if (!timeout_given) find_timeout(); - detect_file_args(argv + optind + 1); + /* If we don't have a file name chosen yet, use a safe default. */ + + if (!out_file) { + u32 i = optind + 1; + while (argv[i]) { + + u8* aa_loc = strstr(argv[i], "@@"); + + if (aa_loc && !out_file) { + if (file_extension) { + out_file = alloc_printf("%s/.cur_input.%s", out_dir, file_extension); + } else { + out_file = alloc_printf("%s/.cur_input", out_dir); + } + detect_file_args(argv + optind + 1, out_file); + break; + } + + i++; + + } + } if (!out_file) setup_stdio_file(); diff --git a/afl-showmap.c b/afl-showmap.c index a5d7568a..1382e5f0 100644 --- a/afl-showmap.c +++ b/afl-showmap.c @@ -29,6 +29,7 @@ #include "alloc-inl.h" #include "hash.h" #include "sharedmem.h" +#include "afl-common.h" #include #include @@ -380,50 +381,6 @@ static void setup_signal_handlers(void) { } -/* Detect @@ in args. */ - -static void detect_file_args(char** argv) { - - u32 i = 0; - u8* cwd = getcwd(NULL, 0); - - if (!cwd) PFATAL("getcwd() failed"); - - while (argv[i]) { - - u8* aa_loc = strstr(argv[i], "@@"); - - if (aa_loc) { - - u8 *aa_subst, *n_arg; - - if (!at_file) FATAL("@@ syntax is not supported by this tool."); - - /* Be sure that we're always using fully-qualified paths. */ - - if (at_file[0] == '/') aa_subst = at_file; - else aa_subst = alloc_printf("%s/%s", cwd, at_file); - - /* Construct a replacement argv value. */ - - *aa_loc = 0; - n_arg = alloc_printf("%s%s%s", argv[i], aa_subst, aa_loc + 2); - argv[i] = n_arg; - *aa_loc = '@'; - - if (at_file[0] != '/') ck_free(aa_subst); - - } - - i++; - - } - - free(cwd); /* not tracked */ - -} - - /* Show banner. */ static void show_banner(void) { @@ -720,7 +677,7 @@ int main(int argc, char** argv) { ACTF("Executing '%s'...\n", target_path); } - detect_file_args(argv + optind); + detect_file_args(argv + optind, at_file); if (qemu_mode) use_argv = get_qemu_argv(argv[0], argv + optind, argc - optind); diff --git a/afl-tmin.c b/afl-tmin.c index b9dbb2b5..d6fd27fc 100644 --- a/afl-tmin.c +++ b/afl-tmin.c @@ -27,6 +27,7 @@ #include "alloc-inl.h" #include "hash.h" #include "sharedmem.h" +#include "afl-common.h" #include #include @@ -881,48 +882,6 @@ static void setup_signal_handlers(void) { } -/* Detect @@ in args. */ - -static void detect_file_args(char** argv) { - - u32 i = 0; - u8* cwd = getcwd(NULL, 0); - - if (!cwd) PFATAL("getcwd() failed"); - - while (argv[i]) { - - u8* aa_loc = strstr(argv[i], "@@"); - - if (aa_loc) { - - u8 *aa_subst, *n_arg; - - /* Be sure that we're always using fully-qualified paths. */ - - if (prog_in[0] == '/') aa_subst = prog_in; - else aa_subst = alloc_printf("%s/%s", cwd, prog_in); - - /* Construct a replacement argv value. */ - - *aa_loc = 0; - n_arg = alloc_printf("%s%s%s", argv[i], aa_subst, aa_loc + 2); - argv[i] = n_arg; - *aa_loc = '@'; - - if (prog_in[0] != '/') ck_free(aa_subst); - - } - - i++; - - } - - free(cwd); /* not tracked */ - -} - - /* Display usage hints. */ static void usage(u8* argv0) { @@ -1222,7 +1181,7 @@ int main(int argc, char** argv) { set_up_environment(); find_binary(argv[optind]); - detect_file_args(argv + optind); + detect_file_args(argv + optind, prog_in); if (qemu_mode) use_argv = get_qemu_argv(argv[0], argv + optind, argc - optind); -- cgit 1.4.1