AFLplusplus / AFLplusplus

The fuzzer afl++ is afl with community patches, qemu 5.1 upgrade, collision-free coverage, enhanced laf-intel & redqueen, AFLfast++ power schedules, MOpt mutators, unicorn_mode, and a lot more!

Home Page:https://aflplus.plus

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

sync_fuzzers logic bug

wtfbillx opened this issue · comments

sync_fuzzers call write_to_testcase[1] fuzz_run_target[2] and check if new sample is interesting,if the answer is yes,then call save_if_interesting[3] to write new sample to disk.
[3]https://github1s.com/AFLplusplus/AFLplusplus/blob/stable/src/afl-fuzz-run.c#L822-L823

But the problem is,write_to_testcase will call afl_custom_post_process if custom mutator is on,and the return length may not be the same with st.st_size,so [3]'s length param should be the value returned from [1].

I find this when using custom mutator,and i hope you can fix in the main branch to help more lost person.XD

patch should be like:

...
if (st.st_size && st.st_size <= MAX_FILE) {

    u8  fault;
    u8 *mem = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);

    if (mem == MAP_FAILED) { PFATAL("Unable to mmap '%s'", path); }

    /* See what happens. We rely on save_if_interesting() to catch major
       errors and save the test case. */

    u32 len = write_to_testcase(afl, (void **)&mem, st.st_size, 1);

    fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);

    if (afl->stop_soon) { goto close_sync; }

    afl->syncing_party = sd_ent->d_name;
    afl->queued_imported +=
        save_if_interesting(afl, mem, len, fault);
    afl->syncing_party = 0;

    munmap(mem, st.st_size);

  }

...

Correct me if I miss something cause my local code write like this and don't want to trigger some unwanted bug.XD

thanks for reporting!
can you please send a PR? I am not sure I understand you fix proposal :)

2 line code changed here:

1.save write_to_testcase return value:
https://github.com/AFLplusplus/AFLplusplus/blob/stable/src/afl-fuzz-run.c#L814

u32 len = write_to_testcase(afl, (void **)&mem, st.st_size, 1);

2.change save_if_interesting length param:
https://github.com/AFLplusplus/AFLplusplus/blob/stable/src/afl-fuzz-run.c#L822

save_if_interesting(afl, mem, len, fault);

you know you can make local changes in your git checkout and then just do git diff and have the changes displayed? that is less error prone than such a text description :)

so this is what you mean?

$ git diff
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c
index 1c6ce56a..edcddc8e 100644
--- a/src/afl-fuzz-run.c
+++ b/src/afl-fuzz-run.c
@@ -822,7 +822,7 @@ void sync_fuzzers(afl_state_t *afl) {
         /* See what happens. We rely on save_if_interesting() to catch major
            errors and save the test case. */
 
-        (void)write_to_testcase(afl, (void **)&mem, st.st_size, 1);
+        u32 new_len = write_to_testcase(afl, (void **)&mem, st.st_size, 1);
 
         fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
 
@@ -830,7 +830,7 @@ void sync_fuzzers(afl_state_t *afl) {
 
         afl->syncing_party = sd_ent->d_name;
         afl->queued_imported +=
-            save_if_interesting(afl, mem, st.st_size, fault);
+            save_if_interesting(afl, mem, new_len, fault);
         afl->syncing_party = 0;
 
         munmap(mem, st.st_size);

It's exactly what I mean,

I know I can diff my local git change,but my changed code not only includes here,XD

merged into dev, thanks.