aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/afl-cc.c130
-rw-r--r--src/afl-common.c2
-rw-r--r--src/afl-forkserver.c17
-rw-r--r--src/afl-fuzz-bitmap.c91
-rw-r--r--src/afl-fuzz-init.c11
-rw-r--r--src/afl-fuzz-mutators.c7
-rw-r--r--src/afl-fuzz-one.c14
-rw-r--r--src/afl-fuzz-python.c78
-rw-r--r--src/afl-fuzz-queue.c7
-rw-r--r--src/afl-fuzz-run.c4
-rw-r--r--src/afl-fuzz-state.c6
-rw-r--r--src/afl-fuzz.c56
-rw-r--r--src/afl-gotcpu.c1
-rw-r--r--src/afl-showmap.c6
-rw-r--r--src/afl-tmin.c7
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);