diff options
author | van Hauser <vh@thc.org> | 2020-11-18 21:25:35 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-18 21:25:35 +0100 |
commit | 4d9eb9bda147a26fc8cbe885b6193cf0c94c6314 (patch) | |
tree | c7a903633c7d1b0b5e373535188fd3a458a7f329 /src | |
parent | 4c59c5234aec0469e4dd02561dbd84387bd53155 (diff) | |
parent | cd0a25be5e9b05a2ab6a11592cd95e7f653bf42d (diff) | |
download | afl++-4d9eb9bda147a26fc8cbe885b6193cf0c94c6314.tar.gz |
Merge pull request #607 from AFLplusplus/dev
push to stable
Diffstat (limited to 'src')
-rw-r--r-- | src/afl-cc.c | 130 | ||||
-rw-r--r-- | src/afl-common.c | 2 | ||||
-rw-r--r-- | src/afl-forkserver.c | 17 | ||||
-rw-r--r-- | src/afl-fuzz-bitmap.c | 91 | ||||
-rw-r--r-- | src/afl-fuzz-init.c | 11 | ||||
-rw-r--r-- | src/afl-fuzz-mutators.c | 7 | ||||
-rw-r--r-- | src/afl-fuzz-one.c | 14 | ||||
-rw-r--r-- | src/afl-fuzz-python.c | 78 | ||||
-rw-r--r-- | src/afl-fuzz-queue.c | 7 | ||||
-rw-r--r-- | src/afl-fuzz-run.c | 4 | ||||
-rw-r--r-- | src/afl-fuzz-state.c | 6 | ||||
-rw-r--r-- | src/afl-fuzz.c | 56 | ||||
-rw-r--r-- | src/afl-gotcpu.c | 1 | ||||
-rw-r--r-- | src/afl-showmap.c | 6 | ||||
-rw-r--r-- | src/afl-tmin.c | 7 |
15 files changed, 319 insertions, 118 deletions
diff --git a/src/afl-cc.c b/src/afl-cc.c index 771a58f5..19dc9a6a 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -49,14 +49,14 @@ static u8 * obj_path; /* Path to runtime libraries */ static u8 **cc_params; /* Parameters passed to the real CC */ static u32 cc_par_cnt = 1; /* Param count, including argv0 */ static u8 llvm_fullpath[PATH_MAX]; -static u8 instrument_mode, instrument_opt_mode, ngram_size, lto_mode, - compiler_mode, plusplus_mode; -static u8 have_gcc, have_llvm, have_gcc_plugin, have_lto; -static u8 *lto_flag = AFL_CLANG_FLTO, *argvnull; -static u8 debug; -static u8 cwd[4096]; -static u8 cmplog_mode; -u8 use_stdin; /* dummy */ +static u8 instrument_mode, instrument_opt_mode, ngram_size, lto_mode; +static u8 compiler_mode, plusplus_mode, have_instr_env = 0; +static u8 have_gcc, have_llvm, have_gcc_plugin, have_lto, have_instr_list = 0; +static u8 * lto_flag = AFL_CLANG_FLTO, *argvnull; +static u8 debug; +static u8 cwd[4096]; +static u8 cmplog_mode; +u8 use_stdin; /* dummy */ // static u8 *march_opt = CFLAGS_OPT; enum { @@ -354,19 +354,13 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (lto_mode && plusplus_mode) cc_params[cc_par_cnt++] = "-lc++"; // needed by fuzzbench, early - if (lto_mode) { - - if (getenv("AFL_LLVM_INSTRUMENT_FILE") != NULL || - getenv("AFL_LLVM_WHITELIST") || getenv("AFL_LLVM_ALLOWLIST") || - getenv("AFL_LLVM_DENYLIST") || getenv("AFL_LLVM_BLOCKLIST")) { - - 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-lto-instrumentlist.so", obj_path); + if (lto_mode && have_instr_env) { - } + 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-lto-instrumentlist.so", obj_path); } @@ -508,11 +502,25 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (instrument_mode == INSTRUMENT_PCGUARD) { #if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0) - 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/SanitizerCoveragePCGUARD.so", obj_path); + if (have_instr_list) { + + if (!be_quiet) + SAYF( + "Using unoptimized trace-pc-guard, due usage of " + "-fsanitize-coverage-allow/denylist, you can use " + "AFL_LLVM_ALLOWLIST/AFL_LLMV_DENYLIST instead.\n"); + cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard"; + + } 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/SanitizerCoveragePCGUARD.so", obj_path); + + } + #else #if LLVM_MAJOR >= 4 if (!be_quiet) @@ -590,6 +598,9 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (!strcmp(cur, "armv7a-linux-androideabi")) bit_mode = 32; if (!strcmp(cur, "-m64")) bit_mode = 64; + if (!strncmp(cur, "-fsanitize-coverage-", 20) && strstr(cur, "list=")) + have_instr_list = 1; + if (!strcmp(cur, "-fsanitize=address") || !strcmp(cur, "-fsanitize=memory")) asan_set = 1; @@ -826,7 +837,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { } - #ifndef __APPLE__ + #if !defined(__APPLE__) && !defined(__sun) if (!shared_linking) cc_params[cc_par_cnt++] = alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path); @@ -856,6 +867,14 @@ int main(int argc, char **argv, char **envp) { be_quiet = 1; + if (getenv("AFL_LLVM_INSTRUMENT_FILE") || getenv("AFL_LLVM_WHITELIST") || + getenv("AFL_LLVM_ALLOWLIST") || getenv("AFL_LLVM_DENYLIST") || + getenv("AFL_LLVM_BLOCKLIST")) { + + have_instr_env = 1; + + } + if ((ptr = strrchr(callname, '/')) != NULL) callname = ptr + 1; argvnull = (u8 *)argv[0]; check_environment_vars(envp); @@ -1015,14 +1034,14 @@ int main(int argc, char **argv, char **envp) { } - if ((getenv("AFL_LLVM_INSTRUMENT_FILE") != NULL || - getenv("AFL_LLVM_WHITELIST") || getenv("AFL_LLVM_ALLOWLIST") || - getenv("AFL_LLVM_DENYLIST") || getenv("AFL_LLVM_BLOCKLIST")) && - getenv("AFL_DONT_OPTIMIZE")) + if (have_instr_env && getenv("AFL_DONT_OPTIMIZE")) { + WARNF( "AFL_LLVM_ALLOWLIST/DENYLIST and AFL_DONT_OPTIMIZE cannot be combined " "for file matching, only function matching!"); + } + if (getenv("AFL_LLVM_INSTRIM") || getenv("INSTRIM") || getenv("INSTRIM_LIB")) { @@ -1307,15 +1326,20 @@ int main(int argc, char **argv, char **envp) { " AFL_GCC_INSTRUMENT_FILE: enable selective instrumentation by " "filename\n"); +#if LLVM_MAJOR < 9 + #define COUNTER_BEHAVIOUR \ + " AFL_LLVM_NOT_ZERO: use cycling trace counters that skip zero\n" +#else + #define COUNTER_BEHAVIOUR \ + " AFL_LLVM_SKIP_NEVERZERO: do not skip zero on trace counters\n" +#endif if (have_llvm) SAYF( "\nLLVM/LTO/afl-clang-fast/afl-clang-lto specific environment " "variables:\n" -#if LLVM_MAJOR < 9 - " AFL_LLVM_NOT_ZERO: use cycling trace counters that skip zero\n" -#else - " AFL_LLVM_SKIP_NEVERZERO: do not skip zero on trace counters\n" -#endif + + COUNTER_BEHAVIOUR + " AFL_LLVM_DICT2FILE: generate an afl dictionary based on found " "comparisons\n" " AFL_LLVM_LAF_ALL: enables all LAF splits/transforms\n" @@ -1426,22 +1450,20 @@ int main(int argc, char **argv, char **envp) { #if LLVM_MAJOR <= 6 instrument_mode = INSTRUMENT_AFL; #else - if (getenv("AFL_LLVM_INSTRUMENT_FILE") != NULL || - getenv("AFL_LLVM_WHITELIST") || getenv("AFL_LLVM_ALLOWLIST") || - getenv("AFL_LLVM_DENYLIST") || getenv("AFL_LLVM_BLOCKLIST")) { + #if LLVM_MAJOR < 11 && (LLVM_MAJOR < 10 || LLVM_MINOR < 1) + if (have_instr_env) { instrument_mode = INSTRUMENT_AFL; - WARNF( - "switching to classic instrumentation because " - "AFL_LLVM_ALLOWLIST/DENYLIST does not work with PCGUARD. Use " - "-fsanitize-coverage-allowlist=allowlist.txt or " - "-fsanitize-coverage-blocklist=denylist.txt if you want to use " - "PCGUARD. Requires llvm 12+. See https://clang.llvm.org/docs/ " - "SanitizerCoverage.html#partially-disabling-instrumentation"); + if (!be_quiet) + WARNF( + "Switching to classic instrumentation because " + "AFL_LLVM_ALLOWLIST/DENYLIST does not work with PCGUARD < 10.0.1."); } else + #endif instrument_mode = INSTRUMENT_PCGUARD; + #endif } @@ -1487,18 +1509,16 @@ int main(int argc, char **argv, char **envp) { "AFL_LLVM_NOT_ZERO and AFL_LLVM_SKIP_NEVERZERO can not be set " "together"); - if (instrument_mode == INSTRUMENT_PCGUARD && - (getenv("AFL_LLVM_INSTRUMENT_FILE") != NULL || - getenv("AFL_LLVM_WHITELIST") || getenv("AFL_LLVM_ALLOWLIST") || - getenv("AFL_LLVM_DENYLIST") || getenv("AFL_LLVM_BLOCKLIST"))) +#if LLVM_MAJOR < 11 && (LLVM_MAJOR < 10 || LLVM_MINOR < 1) + if (instrument_mode == INSTRUMENT_PCGUARD && have_instr_env) { + FATAL( "Instrumentation type PCGUARD does not support " - "AFL_LLVM_ALLOWLIST/DENYLIST! Use " - "-fsanitize-coverage-allowlist=allowlist.txt or " - "-fsanitize-coverage-blocklist=denylist.txt instead (requires llvm " - "12+), see " - "https://clang.llvm.org/docs/" - "SanitizerCoverage.html#partially-disabling-instrumentation"); + "AFL_LLVM_ALLOWLIST/DENYLIST! Use LLVM 10.0.1+ instead."); + + } + +#endif u8 *ptr2; diff --git a/src/afl-common.c b/src/afl-common.c index 19c9419b..8cf1a444 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -342,7 +342,7 @@ u8 *find_binary(u8 *fname) { if (stat(target_path, &st) || !S_ISREG(st.st_mode) || !(st.st_mode & 0111) || st.st_size < 4) { - free(target_path); + ck_free(target_path); FATAL("Program '%s' not found or not executable", fname); } diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 45be2abd..3814a77e 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -116,7 +116,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) { fsrv_to->use_fauxsrv = 0; fsrv_to->last_run_timed_out = 0; - fsrv_to->init_child_func = fsrv_exec_child; + fsrv_to->init_child_func = from->init_child_func; // Note: do not copy ->add_extra_func list_append(&fsrv_list, fsrv_to); @@ -272,7 +272,8 @@ static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) { *(u32 *)fsrv->trace_bits = EXEC_FAIL_SIG; - PFATAL("Execv failed in fauxserver."); + WARNF("Execv failed in fauxserver."); + break; } @@ -286,13 +287,13 @@ static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) { if (waitpid(child_pid, &status, 0) < 0) { // Zombie Child could not be collected. Scary! - PFATAL("Fauxserver could not determin child's exit code. "); + WARNF("Fauxserver could not determine child's exit code. "); } /* Relay wait status to AFL pipe, then loop back. */ - if (write(FORKSRV_FD + 1, &status, 4) != 4) { exit(0); } + if (write(FORKSRV_FD + 1, &status, 4) != 4) { exit(1); } } @@ -330,7 +331,7 @@ static void report_error_and_exit(int error) { "memory failed."); break; default: - FATAL("unknown error code %u from fuzzing target!", error); + FATAL("unknown error code %d from fuzzing target!", error); } @@ -355,7 +356,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if (fsrv->use_fauxsrv) { - /* TODO: Come up with sone nice way to initialize this all */ + /* TODO: Come up with some nice way to initialize this all */ if (fsrv->init_child_func != fsrv_exec_child) { @@ -520,7 +521,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, *(u32 *)fsrv->trace_bits = EXEC_FAIL_SIG; fprintf(stderr, "Error: execv to target failed\n"); - exit(0); + exit(1); } @@ -1137,7 +1138,7 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, } // Fauxserver should handle this now. - // if (tb4 == EXEC_FAIL_SIG) return FSRV_RUN_ERROR; + if (*(u32 *)fsrv->trace_bits == EXEC_FAIL_SIG) return FSRV_RUN_ERROR; return FSRV_RUN_OK; diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 735420c3..2d14b04e 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -584,12 +584,39 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { alloc_printf("%s/queue/id_%06u", afl->out_dir, afl->queued_paths); #endif /* ^!SIMPLE_FILES */ - + fd = open(queue_fn, O_WRONLY | O_CREAT | O_EXCL, 0600); + if (unlikely(fd < 0)) { PFATAL("Unable to create '%s'", queue_fn); } + ck_write(fd, mem, len, queue_fn); + close(fd); add_to_queue(afl, queue_fn, len, 0); #ifdef INTROSPECTION - fprintf(afl->introspection_file, "QUEUE %s = %s\n", afl->mutation, - afl->queue_top->fname); + if (afl->custom_mutators_count && afl->current_custom_fuzz) { + + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (afl->current_custom_fuzz == el && el->afl_custom_introspection) { + + const char *ptr = el->afl_custom_introspection(el->data); + + if (ptr != NULL && *ptr != 0) { + + fprintf(afl->introspection_file, "QUEUE CUSTOM %s = %s\n", ptr, + afl->queue_top->fname); + + } + + } + + }); + + } else if (afl->mutation[0] != 0) { + + fprintf(afl->introspection_file, "QUEUE %s = %s\n", afl->mutation, + afl->queue_top->fname); + + } + #endif if (hnb == 2) { @@ -623,11 +650,6 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { } - fd = open(queue_fn, O_WRONLY | O_CREAT | O_EXCL, 0600); - if (unlikely(fd < 0)) { PFATAL("Unable to create '%s'", queue_fn); } - ck_write(fd, mem, len, queue_fn); - close(fd); - if (likely(afl->q_testcase_max_cache_size)) { queue_testcase_store_mem(afl, afl->queue_top, mem); @@ -665,7 +687,32 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { ++afl->unique_tmouts; #ifdef INTROSPECTION - fprintf(afl->introspection_file, "UNIQUE_TIMEOUT %s\n", afl->mutation); + if (afl->custom_mutators_count && afl->current_custom_fuzz) { + + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (afl->current_custom_fuzz == el && el->afl_custom_introspection) { + + const char *ptr = el->afl_custom_introspection(el->data); + + if (ptr != NULL && *ptr != 0) { + + fprintf(afl->introspection_file, + "UNIQUE_TIMEOUT CUSTOM %s = %s\n", ptr, + afl->queue_top->fname); + + } + + } + + }); + + } else if (afl->mutation[0] != 0) { + + fprintf(afl->introspection_file, "UNIQUE_TIMEOUT %s\n", afl->mutation); + + } + #endif /* Before saving, we make sure that it's a genuine hang by re-running @@ -751,7 +798,31 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { ++afl->unique_crashes; #ifdef INTROSPECTION - fprintf(afl->introspection_file, "UNIQUE_CRASH %s\n", afl->mutation); + if (afl->custom_mutators_count && afl->current_custom_fuzz) { + + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (afl->current_custom_fuzz == el && el->afl_custom_introspection) { + + const char *ptr = el->afl_custom_introspection(el->data); + + if (ptr != NULL && *ptr != 0) { + + fprintf(afl->introspection_file, "UNIQUE_CRASH CUSTOM %s = %s\n", + ptr, afl->queue_top->fname); + + } + + } + + }); + + } else if (afl->mutation[0] != 0) { + + fprintf(afl->introspection_file, "UNIQUE_CRASH %s\n", afl->mutation); + + } + #endif if (unlikely(afl->infoexec)) { diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 19a8d77b..0360cdb0 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -355,7 +355,7 @@ void bind_to_free_cpu(afl_state_t *afl) { if (ncpus > sizeof(cpu_used)) ncpus = sizeof(cpu_used); - for (i = 0; i < ncpus; i++) { + for (i = 0; i < (s32)ncpus; i++) { k = kstat_lookup(m, "cpu_stat", i, NULL); if (kstat_read(m, k, &cs)) { @@ -2300,12 +2300,6 @@ void fix_up_sync(afl_state_t *afl) { u8 *x = afl->sync_id; - if (afl->non_instrumented_mode) { - - FATAL("-S / -M and -n are mutually exclusive"); - - } - while (*x) { if (!isalnum(*x) && *x != '_' && *x != '-') { @@ -2503,7 +2497,8 @@ void check_binary(afl_state_t *afl, u8 *fname) { } - if (afl->afl_env.afl_skip_bin_check || afl->use_wine || afl->unicorn_mode) { + if (afl->afl_env.afl_skip_bin_check || afl->use_wine || afl->unicorn_mode || + afl->non_instrumented_mode) { return; diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index c4d7233c..1d14f657 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -166,6 +166,13 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { } + /* "afl_custom_introspection", optional */ +#ifdef INTROSPECTION + mutator->afl_custom_introspection = dlsym(dh, "afl_custom_introspection"); + if (!mutator->afl_custom_introspection) + ACTF("optional symbol 'afl_custom_introspection' not found."); +#endif + /* "afl_custom_fuzz_count", optional */ mutator->afl_custom_fuzz_count = dlsym(dh, "afl_custom_fuzz_count"); if (!mutator->afl_custom_fuzz_count) diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 91bbced6..0adc3719 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1780,10 +1780,16 @@ custom_mutator_stage: orig_hit_cnt = afl->queued_paths + afl->unique_crashes; +#ifdef INTROSPECTION + afl->mutation[0] = 0; +#endif + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { if (el->afl_custom_fuzz) { + afl->current_custom_fuzz = el; + if (el->afl_custom_fuzz_count) afl->stage_max = el->afl_custom_fuzz_count(el->data, out_buf, len); else @@ -1840,12 +1846,6 @@ custom_mutator_stage: if (mutated_size > 0) { -#ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s CUSTOM-%s", - afl->queue_cur->fname, - target != NULL ? (char *)target->fname : "none"); -#endif - if (common_fuzz_stuff(afl, mutated_buf, (u32)mutated_size)) { goto abandon_entry; @@ -1889,6 +1889,8 @@ custom_mutator_stage: }); + afl->current_custom_fuzz = NULL; + if (!has_custom_fuzz) goto havoc_stage; new_hit_cnt = afl->queued_paths + afl->unique_crashes; diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index adb92649..9ac4403b 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -96,7 +96,7 @@ static size_t fuzz_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf, mutated_size = PyByteArray_Size(py_value); *out_buf = afl_realloc(BUF_PARAMS(fuzz), mutated_size); - if (unlikely(!out_buf)) { PFATAL("alloc"); } + if (unlikely(!*out_buf)) { PFATAL("alloc"); } memcpy(*out_buf, PyByteArray_AsString(py_value), mutated_size); Py_DECREF(py_value); @@ -134,6 +134,18 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { PyObject * py_module = py->py_module; PyObject **py_functions = py->py_functions; + // initialize the post process buffer; ensures it's always valid + PyObject *unused_bytes = PyByteArray_FromStringAndSize("OHAI", 4); + if (!unused_bytes) { FATAL("allocation failed!"); } + if (PyObject_GetBuffer(unused_bytes, &py->post_process_buf, PyBUF_SIMPLE) == + -1) { + + FATAL("buffer initialization failed"); + + } + + Py_DECREF(unused_bytes); + if (py_module != NULL) { u8 py_notrim = 0, py_idx; @@ -163,6 +175,8 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { PyObject_GetAttrString(py_module, "queue_get"); py_functions[PY_FUNC_QUEUE_NEW_ENTRY] = PyObject_GetAttrString(py_module, "queue_new_entry"); + py_functions[PY_FUNC_INTROSPECTION] = + PyObject_GetAttrString(py_module, "introspection"); py_functions[PY_FUNC_DEINIT] = PyObject_GetAttrString(py_module, "deinit"); if (!py_functions[PY_FUNC_DEINIT]) FATAL("deinit function not found in python module"); @@ -212,6 +226,7 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { PyErr_Print(); fprintf(stderr, "Failed to load \"%s\"\n", module_name); + free(py); return NULL; } @@ -310,7 +325,6 @@ struct custom_mutator *load_custom_mutator_py(afl_state_t *afl, struct custom_mutator *mutator; mutator = ck_alloc(sizeof(struct custom_mutator)); - mutator->post_process_buf = NULL; mutator->name = module_name; ACTF("Loading Python mutator library from '%s'...", module_name); @@ -326,9 +340,7 @@ struct custom_mutator *load_custom_mutator_py(afl_state_t *afl, if (py_functions[PY_FUNC_DEINIT]) { mutator->afl_custom_deinit = deinit_py; } - /* "afl_custom_fuzz" should not be NULL, but the interface of Python mutator - is quite different from the custom mutator. */ - mutator->afl_custom_fuzz = fuzz_py; + if (py_functions[PY_FUNC_FUZZ]) { mutator->afl_custom_fuzz = fuzz_py; } if (py_functions[PY_FUNC_POST_PROCESS]) { @@ -381,6 +393,15 @@ struct custom_mutator *load_custom_mutator_py(afl_state_t *afl, } + #ifdef INTROSPECTION + if (py_functions[PY_FUNC_INTROSPECTION]) { + + mutator->afl_custom_introspection = introspection_py; + + } + + #endif + OKF("Python mutator '%s' installed successfully.", module_name); /* Initialize the custom mutator */ @@ -393,10 +414,13 @@ struct custom_mutator *load_custom_mutator_py(afl_state_t *afl, size_t post_process_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf) { - size_t py_out_buf_size; PyObject * py_args, *py_value; py_mutator_t *py = (py_mutator_t *)py_mutator; + // buffer returned previously must be released; initialized during init + // so we don't need to do comparisons + PyBuffer_Release(&py->post_process_buf); + py_args = PyTuple_New(1); py_value = PyByteArray_FromStringAndSize(buf, buf_size); if (!py_value) { @@ -416,20 +440,20 @@ size_t post_process_py(void *py_mutator, u8 *buf, size_t buf_size, if (py_value != NULL) { - py_out_buf_size = PyByteArray_Size(py_value); - - if (unlikely(!afl_realloc(BUF_PARAMS(post_process), py_out_buf_size))) { + if (PyObject_GetBuffer(py_value, &py->post_process_buf, PyBUF_SIMPLE) == + -1) { - PFATAL("alloc"); + PyErr_Print(); + FATAL( + "Python custom mutator: post_process call return value not a " + "bytes-like object"); } - memcpy(py->post_process_buf, PyByteArray_AsString(py_value), - py_out_buf_size); Py_DECREF(py_value); - *out_buf = py->post_process_buf; - return py_out_buf_size; + *out_buf = (u8 *)py->post_process_buf.buf; + return py->post_process_buf.len; } else { @@ -569,7 +593,7 @@ size_t trim_py(void *py_mutator, u8 **out_buf) { ret = PyByteArray_Size(py_value); *out_buf = afl_realloc(BUF_PARAMS(trim), ret); - if (unlikely(!out_buf)) { PFATAL("alloc"); } + if (unlikely(!*out_buf)) { PFATAL("alloc"); } memcpy(*out_buf, PyByteArray_AsString(py_value), ret); Py_DECREF(py_value); @@ -635,7 +659,7 @@ size_t havoc_mutation_py(void *py_mutator, u8 *buf, size_t buf_size, /* A new buf is needed... */ *out_buf = afl_realloc(BUF_PARAMS(havoc), mutated_size); - if (unlikely(!out_buf)) { PFATAL("alloc"); } + if (unlikely(!*out_buf)) { PFATAL("alloc"); } } @@ -679,6 +703,28 @@ u8 havoc_mutation_probability_py(void *py_mutator) { } +const char *introspection_py(void *py_mutator) { + + PyObject *py_args, *py_value; + + py_args = PyTuple_New(0); + py_value = PyObject_CallObject( + ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_INTROSPECTION], + py_args); + Py_DECREF(py_args); + + if (py_value == NULL) { + + return NULL; + + } else { + + return PyByteArray_AsString(py_value); + + } + +} + u8 queue_get_py(void *py_mutator, const u8 *filename) { PyObject *py_args, *py_value; diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index c78df8be..f35b4f57 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -56,7 +56,12 @@ void create_alias_table(afl_state_t *afl) { int * S = (u32 *)afl_realloc(AFL_BUF_PARAM(out_scratch), n * sizeof(u32)); int * L = (u32 *)afl_realloc(AFL_BUF_PARAM(in_scratch), n * sizeof(u32)); - if (!P || !S || !L) { FATAL("could not aquire memory for alias table"); } + if (!P || !S || !L || !afl->alias_table || !afl->alias_probability) { + + FATAL("could not acquire memory for alias table"); + + } + memset((void *)afl->alias_table, 0, n * sizeof(u32)); memset((void *)afl->alias_probability, 0, n * sizeof(double)); diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index e969994d..95b3ee8a 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -332,7 +332,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, } afl_fsrv_start(&afl->fsrv, afl->argv, &afl->stop_soon, - afl->afl_env.afl_debug_child_output); + afl->afl_env.afl_debug_child); if (afl->fsrv.support_shmem_fuzz && !afl->fsrv.use_shmem_fuzz) { @@ -590,7 +590,7 @@ void sync_fuzzers(afl_state_t *afl) { while (m < n) { - if (strcmp(namelist[m]->d_name, entry)) { + if (strncmp(namelist[m]->d_name, entry, 9)) { m++; diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 61bd06b7..489d4e53 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -268,11 +268,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_bench_until_crash = get_afl_env(afl_environment_variables[i]) ? 1 : 0; - } else if (!strncmp(env, "AFL_DEBUG_CHILD_OUTPUT", + } else if (!strncmp(env, "AFL_DEBUG_CHILD", + afl_environment_variable_len) || + !strncmp(env, "AFL_DEBUG_CHILD_OUTPUT", afl_environment_variable_len)) { - afl->afl_env.afl_debug_child_output = + afl->afl_env.afl_debug_child = get_afl_env(afl_environment_variables[i]) ? 1 : 0; } else if (!strncmp(env, "AFL_AUTORESUME", diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 269ce1bf..1008f28c 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -166,7 +166,7 @@ static void usage(u8 *argv0, int more_help) { "AFL_CUSTOM_MUTATOR_ONLY: avoid AFL++'s internal mutators\n" "AFL_CYCLE_SCHEDULES: after completing a cycle, switch to a different -p schedule\n" "AFL_DEBUG: extra debugging output for Python mode trimming\n" - "AFL_DEBUG_CHILD_OUTPUT: do not suppress stdout/stderr from target\n" + "AFL_DEBUG_CHILD: do not suppress stdout/stderr from target\n" "AFL_DISABLE_TRIM: disable the trimming of test cases\n" "AFL_DUMB_FORKSRV: use fork server without feedback from target\n" "AFL_EXIT_WHEN_DONE: exit when all inputs are run and no new finds are found\n" @@ -350,6 +350,7 @@ int main(int argc, char **argv_orig, char **envp) { case 's': { + if (optarg == NULL) { FATAL("No valid seed provided. Got NULL."); } rand_set_seed(afl, strtoul(optarg, 0L, 10)); afl->fixed_seed = 1; break; @@ -419,6 +420,7 @@ int main(int argc, char **argv_orig, char **envp) { case 'i': /* input dir */ if (afl->in_dir) { FATAL("Multiple -i options not supported"); } + if (optarg == NULL) { FATAL("Invalid -i option (got NULL)."); } afl->in_dir = optarg; if (!strcmp(afl->in_dir, "-")) { afl->in_place_resume = 1; } @@ -435,9 +437,26 @@ int main(int argc, char **argv_orig, char **envp) { u8 *c; + if (afl->non_instrumented_mode) { + + FATAL("-M is not supported in non-instrumented mode"); + + } + if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); } + + /* sanity check for argument: should not begin with '-' (possible + * option) */ + if (optarg && *optarg == '-') { + + FATAL( + "argument for -M started with a dash '-', which is used for " + "options"); + + } + afl->sync_id = ck_strdup(optarg); - afl->skip_deterministic = 0; // force determinsitic fuzzing + afl->skip_deterministic = 0; // force deterministic fuzzing afl->old_seed_selection = 1; // force old queue walking seed selection if ((c = strchr(afl->sync_id, ':'))) { @@ -464,7 +483,24 @@ int main(int argc, char **argv_orig, char **envp) { case 'S': /* secondary sync id */ + if (afl->non_instrumented_mode) { + + FATAL("-S is not supported in non-instrumented mode"); + + } + if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); } + + /* sanity check for argument: should not begin with '-' (possible + * option) */ + if (optarg && *optarg == '-') { + + FATAL( + "argument for -M started with a dash '-', which is used for " + "options"); + + } + afl->sync_id = ck_strdup(optarg); afl->is_secondary_node = 1; break; @@ -620,6 +656,12 @@ int main(int argc, char **argv_orig, char **envp) { case 'n': /* dumb mode */ + if (afl->is_main_node || afl->is_secondary_node) { + + FATAL("Non instrumented mode is not supported with -M / -S"); + + } + if (afl->non_instrumented_mode) { FATAL("Multiple -n options not supported"); @@ -906,7 +948,7 @@ int main(int argc, char **argv_orig, char **envp) { afl->power_name = power_names[afl->schedule]; - if (!afl->sync_id) { + if (!afl->non_instrumented_mode && !afl->sync_id) { auto_sync = 1; afl->sync_id = ck_strdup("default"); @@ -1338,7 +1380,11 @@ int main(int argc, char **argv_orig, char **envp) { } - if (!afl->fsrv.qemu_mode) { check_binary(afl, afl->cmplog_binary); } + if (!afl->fsrv.qemu_mode && !afl->non_instrumented_mode) { + + check_binary(afl, afl->cmplog_binary); + + } } @@ -1380,7 +1426,7 @@ int main(int argc, char **argv_orig, char **envp) { afl->cmplog_fsrv.cmplog_binary = afl->cmplog_binary; afl->cmplog_fsrv.init_child_func = cmplog_exec_child; afl_fsrv_start(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon, - afl->afl_env.afl_debug_child_output); + afl->afl_env.afl_debug_child); OKF("Cmplog forkserver successfully started"); } diff --git a/src/afl-gotcpu.c b/src/afl-gotcpu.c index bd0f7de6..1aea3e40 100644 --- a/src/afl-gotcpu.c +++ b/src/afl-gotcpu.c @@ -65,7 +65,6 @@ #define cpu_set_t cpuset_t #elif defined(__NetBSD__) #include <pthread.h> - #include <sched.h> #elif defined(__APPLE__) #include <pthread.h> #include <mach/thread_act.h> diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 4b357254..69527007 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -1091,7 +1091,11 @@ int main(int argc, char **argv_orig, char **envp) { } afl_fsrv_start(fsrv, use_argv, &stop_soon, - get_afl_env("AFL_DEBUG_CHILD_OUTPUT") ? 1 : 0); + (get_afl_env("AFL_DEBUG_CHILD") || + get_afl_env("AFL_DEBUG_CHILD_OUTPUT")) + ? 1 + : 0); + map_size = fsrv->map_size; if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz) diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 06037d61..e4fb068d 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -1141,8 +1141,11 @@ int main(int argc, char **argv_orig, char **envp) { read_initial_file(); - afl_fsrv_start(fsrv, use_argv, &stop_soon, - get_afl_env("AFL_DEBUG_CHILD_OUTPUT") ? 1 : 0); + afl_fsrv_start( + fsrv, use_argv, &stop_soon, + (get_afl_env("AFL_DEBUG_CHILD") || get_afl_env("AFL_DEBUG_CHILD_OUTPUT")) + ? 1 + : 0); if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz) shm_fuzz = deinit_shmem(fsrv, shm_fuzz); |