mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-15 11:28:08 +00:00
integration in fuzz_one
This commit is contained in:
@ -430,7 +430,9 @@ typedef struct afl_state {
|
|||||||
*in_bitmap, /* Input bitmap */
|
*in_bitmap, /* Input bitmap */
|
||||||
*file_extension, /* File extension */
|
*file_extension, /* File extension */
|
||||||
*orig_cmdline, /* Original command line */
|
*orig_cmdline, /* Original command line */
|
||||||
*infoexec; /* Command to execute on a new crash */
|
*infoexec, /* Command to execute on a new crash */
|
||||||
|
*taint_input_file, /* fuzz_input_one input file */
|
||||||
|
*taint_src, *taint_map;
|
||||||
|
|
||||||
u32 hang_tmout; /* Timeout used for hang det (ms) */
|
u32 hang_tmout; /* Timeout used for hang det (ms) */
|
||||||
|
|
||||||
@ -441,7 +443,8 @@ typedef struct afl_state {
|
|||||||
custom_only, /* Custom mutator only mode */
|
custom_only, /* Custom mutator only mode */
|
||||||
python_only, /* Python-only mode */
|
python_only, /* Python-only mode */
|
||||||
is_main_node, /* if this is the main node */
|
is_main_node, /* if this is the main node */
|
||||||
is_secondary_node; /* if this is a secondary instance */
|
is_secondary_node, /* if this is a secondary instance */
|
||||||
|
taint_needs_splode; /* explode fuzz input */
|
||||||
|
|
||||||
u32 stats_update_freq; /* Stats update frequency (execs) */
|
u32 stats_update_freq; /* Stats update frequency (execs) */
|
||||||
|
|
||||||
@ -502,7 +505,8 @@ typedef struct afl_state {
|
|||||||
useless_at_start, /* Number of useless starting paths */
|
useless_at_start, /* Number of useless starting paths */
|
||||||
var_byte_count, /* Bitmap bytes with var behavior */
|
var_byte_count, /* Bitmap bytes with var behavior */
|
||||||
current_entry, /* Current queue entry ID */
|
current_entry, /* Current queue entry ID */
|
||||||
havoc_div; /* Cycle count divisor for havoc */
|
havoc_div, /* Cycle count divisor for havoc */
|
||||||
|
taint_len;
|
||||||
|
|
||||||
u64 total_crashes, /* Total number of crashes */
|
u64 total_crashes, /* Total number of crashes */
|
||||||
unique_crashes, /* Crashes with unique signatures */
|
unique_crashes, /* Crashes with unique signatures */
|
||||||
|
@ -458,7 +458,80 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (unlikely(afl->fsrv.taint_mode && (afl->queue_cycle % 3))) {
|
||||||
|
|
||||||
|
if (unlikely(afl->queue_cur->cal_failed)) goto abandon_entry;
|
||||||
|
|
||||||
|
u32 dst = 0, i;
|
||||||
|
|
||||||
|
fd = open(afl->queue_cur->fname, O_RDONLY);
|
||||||
|
afl->taint_src = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
|
||||||
|
if (fd < 0 || (size_t)afl->taint_src == -1)
|
||||||
|
FATAL("unable to open '%s'", afl->queue_cur->fname);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
switch (afl->queue_cycle % 3) {
|
||||||
|
|
||||||
|
case 0: // do nothing, but cannot happen -> else
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1: // fuzz only tainted bytes
|
||||||
|
if (!afl->queue_cur->taint_bytes_all) goto abandon_entry;
|
||||||
|
afl->taint_needs_splode = 1;
|
||||||
|
|
||||||
|
fd = open(afl->taint_input_file, O_RDONLY);
|
||||||
|
len = afl->taint_len = afl->queue_cur->taint_bytes_all;
|
||||||
|
orig_in = in_buf =
|
||||||
|
mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
|
||||||
|
if (fd < 0 || (size_t)in_buf == -1)
|
||||||
|
FATAL("unable to open '%s'", afl->taint_input_file);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
fd = open(afl->queue_cur->fname_taint, O_RDWR);
|
||||||
|
afl->taint_map = mmap(0, afl->queue_cur->len, PROT_READ | PROT_WRITE,
|
||||||
|
MAP_PRIVATE, fd, 0);
|
||||||
|
if (fd < 0 || (size_t)in_buf == -1)
|
||||||
|
FATAL("unable to open '%s'", afl->queue_cur->fname_taint);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
for (i = 0; i < afl->queue_cur->len && dst < len; i++)
|
||||||
|
if (afl->taint_map[i]) in_buf[dst++] = afl->taint_src[i];
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: // fuzz only newly tainted bytes
|
||||||
|
if (!afl->queue_cur->taint_bytes_new) goto abandon_entry;
|
||||||
|
afl->taint_needs_splode = 1;
|
||||||
|
|
||||||
|
fd = open(afl->taint_input_file, O_RDONLY);
|
||||||
|
len = afl->taint_len = afl->queue_cur->taint_bytes_new;
|
||||||
|
orig_in = in_buf =
|
||||||
|
mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
|
||||||
|
if (fd < 0 || (size_t)in_buf == -1)
|
||||||
|
FATAL("unable to open '%s'", afl->taint_input_file);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
u8 *fn = alloc_printf("%s.new", afl->queue_cur->fname_taint);
|
||||||
|
fd = open(fn, O_RDWR);
|
||||||
|
afl->taint_map = mmap(0, afl->queue_cur->len, PROT_READ | PROT_WRITE,
|
||||||
|
MAP_PRIVATE, fd, 0);
|
||||||
|
if (fd < 0 || (size_t)in_buf == -1) FATAL("unable to open '%s'", fn);
|
||||||
|
close(fd);
|
||||||
|
ck_free(fn);
|
||||||
|
|
||||||
|
for (i = 0; i < afl->queue_cur->len && dst < len; i++)
|
||||||
|
if (afl->taint_map[i]) in_buf[dst++] = afl->taint_src[i];
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
goto havoc_stage; // we let the normal cycles do deterministic mode - if
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
/* Map the test case into memory. */
|
/* Map the test case into memory. */
|
||||||
|
afl->taint_needs_splode = 0;
|
||||||
|
|
||||||
fd = open(afl->queue_cur->fname, O_RDONLY);
|
fd = open(afl->queue_cur->fname, O_RDONLY);
|
||||||
|
|
||||||
@ -480,6 +553,8 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
|||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* We could mmap() out_buf as MAP_PRIVATE, but we end up clobbering every
|
/* We could mmap() out_buf as MAP_PRIVATE, but we end up clobbering every
|
||||||
single byte anyway, so it wouldn't give us any performance or memory usage
|
single byte anyway, so it wouldn't give us any performance or memory usage
|
||||||
benefits. */
|
benefits. */
|
||||||
@ -527,7 +602,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
|||||||
************/
|
************/
|
||||||
|
|
||||||
if (!afl->non_instrumented_mode && !afl->queue_cur->trim_done &&
|
if (!afl->non_instrumented_mode && !afl->queue_cur->trim_done &&
|
||||||
!afl->disable_trim) {
|
!afl->disable_trim && !afl->taint_needs_splode) {
|
||||||
|
|
||||||
u8 res = trim_case(afl, afl->queue_cur, in_buf);
|
u8 res = trim_case(afl, afl->queue_cur, in_buf);
|
||||||
|
|
||||||
@ -2568,8 +2643,18 @@ abandon_entry:
|
|||||||
|
|
||||||
++afl->queue_cur->fuzz_level;
|
++afl->queue_cur->fuzz_level;
|
||||||
|
|
||||||
|
if (afl->taint_needs_splode) {
|
||||||
|
|
||||||
|
munmap(afl->taint_src, afl->queue_cur->len);
|
||||||
|
munmap(orig_in, afl->taint_len);
|
||||||
|
munmap(afl->taint_map, afl->queue_cur->len);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
munmap(orig_in, afl->queue_cur->len);
|
munmap(orig_in, afl->queue_cur->len);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return ret_val;
|
return ret_val;
|
||||||
|
|
||||||
#undef FLIP_BIT
|
#undef FLIP_BIT
|
||||||
|
@ -863,6 +863,8 @@ abort_trimming:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size
|
||||||
|
|
||||||
/* Write a modified test case, run program, process results. Handle
|
/* Write a modified test case, run program, process results. Handle
|
||||||
error conditions, returning 1 if it's time to bail out. This is
|
error conditions, returning 1 if it's time to bail out. This is
|
||||||
a helper function for fuzz_one(). */
|
a helper function for fuzz_one(). */
|
||||||
@ -871,6 +873,27 @@ u8 common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
|
|||||||
|
|
||||||
u8 fault;
|
u8 fault;
|
||||||
|
|
||||||
|
if (unlikely(afl->taint_needs_splode)) {
|
||||||
|
|
||||||
|
s32 new_len = afl->queue_cur->len + len - afl->taint_len;
|
||||||
|
if (new_len < 4) new_len = 4;
|
||||||
|
u8 *new_buf = ck_maybe_grow(BUF_PARAMS(in_scratch), new_len);
|
||||||
|
|
||||||
|
u32 i, taint = 0;
|
||||||
|
for (i = 0; i < new_len; i++) {
|
||||||
|
|
||||||
|
if (afl->taint_map[i] || i > afl->queue_cur->len)
|
||||||
|
new_buf[i] = out_buf[taint++];
|
||||||
|
else
|
||||||
|
new_buf[i] = afl->taint_src[i];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
out_buf = new_buf;
|
||||||
|
len = new_len;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
write_to_testcase(afl, out_buf, len);
|
write_to_testcase(afl, out_buf, len);
|
||||||
|
|
||||||
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
||||||
@ -918,3 +941,5 @@ u8 common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef BUF_PARAMS
|
||||||
|
|
||||||
|
@ -1260,12 +1260,15 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
if (afl->fsrv.taint_mode) {
|
if (afl->fsrv.taint_mode) {
|
||||||
|
|
||||||
ACTF("Spawning qemu_taint forkserver");
|
ACTF("Spawning qemu_taint forkserver");
|
||||||
|
|
||||||
u8 *disable = getenv("AFL_DISABLE_LLVM_INSTRUMENTATION");
|
u8 *disable = getenv("AFL_DISABLE_LLVM_INSTRUMENTATION");
|
||||||
setenv("AFL_DISABLE_LLVM_INSTRUMENTATION", "1", 0);
|
setenv("AFL_DISABLE_LLVM_INSTRUMENTATION", "1", 0);
|
||||||
|
|
||||||
afl_fsrv_init_dup(&afl->taint_fsrv, &afl->fsrv);
|
afl_fsrv_init_dup(&afl->taint_fsrv, &afl->fsrv);
|
||||||
afl->taint_fsrv.qemu_mode = 2;
|
afl->taint_fsrv.qemu_mode = 2;
|
||||||
afl->taint_fsrv.taint_mode = 1;
|
afl->taint_fsrv.taint_mode = 1;
|
||||||
afl->taint_fsrv.trace_bits = afl->fsrv.trace_bits;
|
afl->taint_fsrv.trace_bits = afl->fsrv.trace_bits;
|
||||||
|
|
||||||
ck_free(afl->taint_fsrv.target_path);
|
ck_free(afl->taint_fsrv.target_path);
|
||||||
afl->argv_taint = ck_alloc(sizeof(char *) * (argc + 4 - optind));
|
afl->argv_taint = ck_alloc(sizeof(char *) * (argc + 4 - optind));
|
||||||
afl->taint_fsrv.target_path =
|
afl->taint_fsrv.target_path =
|
||||||
@ -1290,7 +1293,16 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
setenv("AFL_TAINT_INPUT", afl->fsrv.out_file, 1);
|
setenv("AFL_TAINT_INPUT", afl->fsrv.out_file, 1);
|
||||||
afl_fsrv_start(&afl->taint_fsrv, afl->argv_taint, &afl->stop_soon,
|
afl_fsrv_start(&afl->taint_fsrv, afl->argv_taint, &afl->stop_soon,
|
||||||
afl->afl_env.afl_debug_child_output);
|
afl->afl_env.afl_debug_child_output);
|
||||||
|
|
||||||
|
afl->taint_input_file = alloc_printf("%s/taint/.input", afl->out_dir);
|
||||||
|
int fd = open(afl->taint_input_file, O_CREAT | O_TRUNC | O_RDWR, 0644);
|
||||||
|
if (fd < 0)
|
||||||
|
FATAL("Cannot create taint inpu file '%s'", afl->taint_input_file);
|
||||||
|
lseek(fd, MAX_FILE, SEEK_SET);
|
||||||
|
ck_write(fd, "\0", 1, afl->taint_input_file);
|
||||||
|
|
||||||
if (!disable) unsetenv("AFL_DISABLE_LLVM_INSTRUMENTATION");
|
if (!disable) unsetenv("AFL_DISABLE_LLVM_INSTRUMENTATION");
|
||||||
|
|
||||||
OKF("Taint forkserver successfully started");
|
OKF("Taint forkserver successfully started");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user