post_process 0/NULL return support

This commit is contained in:
vanhauser-thc
2022-07-19 12:24:03 +02:00
parent b847e0f414
commit ca4a8c0f92
7 changed files with 82 additions and 15 deletions

View File

@ -9,6 +9,9 @@ Want to stay in the loop on major new features? Join our mailing list by
sending a mail to <afl-users+subscribe@googlegroups.com>.
### Version ++4.02a (dev)
- afl-fuzz:
- change post_process hook to allow returning NULL and 0 length to
tell afl-fuzz to skip this mutated input
- gcc_plugin:
- Adacore submitted CMPLOG support to the gcc_plugin! :-)
- llvm_mode:

View File

@ -159,6 +159,10 @@ def deinit(): # optional for Python
This can return any python object that implements the buffer protocol and
supports PyBUF_SIMPLE. These include bytes, bytearray, etc.
You can decide in the post_process mutator to not send the mutated data
to the target, e.g. if it is too short, too corrupted, etc. If so,
return a NULL buffer and zero length (or a 0 length string in Python).
- `queue_new_entry` (optional):
This methods is called after adding a new test case to the queue. If the

View File

@ -648,7 +648,18 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
if (afl->fsrv.exec_tmout < afl->hang_tmout) {
u8 new_fault;
len = write_to_testcase(afl, &mem, len, 0);
u32 tmp_len = write_to_testcase(afl, &mem, len, 0);
if (likely(tmp_len)) {
len = tmp_len;
} else {
len = write_to_testcase(afl, &mem, len, 1);
}
new_fault = fuzz_run_target(afl, &afl->fsrv, afl->hang_tmout);
classify_counts(&afl->fsrv);

View File

@ -48,8 +48,17 @@ void cmplog_exec_child(afl_forkserver_t *fsrv, char **argv) {
u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
u8 fault;
u32 tmp_len = write_to_testcase(afl, (void **)&out_buf, len, 0);
write_to_testcase(afl, (void **)&out_buf, len, 0);
if (likely(tmp_len)) {
len = tmp_len;
} else {
len = write_to_testcase(afl, (void **)&out_buf, len, 1);
}
fault = fuzz_run_target(afl, &afl->cmplog_fsrv, afl->fsrv.exec_tmout);

View File

@ -430,6 +430,12 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
retlen = write_to_testcase(afl, (void **)&retbuf, retlen, 0);
if (unlikely(!retlen)) {
++afl->trim_execs;
} else {
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
++afl->trim_execs;
@ -440,6 +446,8 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
}
}
if (likely(retlen && cksum == q->exec_cksum)) {
/* Let's save a clean trace, which will be needed by

View File

@ -535,7 +535,16 @@ size_t post_process_py(void *py_mutator, u8 *buf, size_t buf_size,
Py_DECREF(py_value);
if (unlikely(py->post_process_buf.len == 0)) {
*out_buf = NULL;
} else {
*out_buf = (u8 *)py->post_process_buf.buf;
}
return py->post_process_buf.len;
} else {

View File

@ -109,17 +109,36 @@ write_to_testcase(afl_state_t *afl, void **mem, u32 len, u32 fix) {
if (unlikely(!new_buf && new_size <= 0)) {
FATAL("Custom_post_process failed (ret: %lu)",
(long unsigned)new_size);
new_size = 0;
new_buf = new_mem;
// FATAL("Custom_post_process failed (ret: %lu)", (long
// unsigned)new_size);
}
} else {
new_mem = new_buf;
}
}
});
if (unlikely(!new_size)) {
// perform dummy runs (fix = 1), but skip all others
if (fix) {
new_size = len;
} else {
return 0;
}
}
if (unlikely(new_size < afl->min_length && !fix)) {
new_size = afl->min_length;
@ -969,7 +988,11 @@ common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
u8 fault;
len = write_to_testcase(afl, (void **)&out_buf, len, 0);
if (unlikely(len = write_to_testcase(afl, (void **)&out_buf, len, 0) == 0)) {
return 0;
}
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);