diff --git a/fuzz.c b/fuzz.c index 6765cce3d..a429b5686 100644 --- a/fuzz.c +++ b/fuzz.c @@ -127,6 +127,7 @@ static void fuzz_setDynamicMainState(run_t* run) { .timeExecUSecs = 1, .path = "[DYNAMIC-0-SIZE]", .timedout = false, + .imported = false, .data = (uint8_t*)"", }; dynfile_t* tmp_dynfile = run->dynfile; @@ -277,12 +278,26 @@ static void fuzz_perfFeedback(run_t* run) { run->dynfile->cov[1] = softCurCmp; run->dynfile->cov[2] = run->hwCnts.cpuInstrCnt + run->hwCnts.cpuBranchCnt; run->dynfile->cov[3] = run->dynfile->size ? (64 - util_Log2(run->dynfile->size)) : 64; + + /* Push useful imported input to dynamic queue again for the further mutations */ + if (run->dynfile->imported) { + LOG_I("File imported: %s", run->dynfile->path); + run->dynfile->imported = false; + } input_addDynamicInput(run); if (run->global->socketFuzzer.enabled) { LOG_D("SocketFuzzer: fuzz: new BB (perf)"); fuzz_notifySocketFuzzerNewCov(run->global); } + } else if (run->dynfile->imported) { + /* Remove useless imported inputs from corpus */ + LOG_D("Removing useless imported file: %s", run->dynfile->path); + char fname[PATH_MAX]; + snprintf(fname, PATH_MAX, "%s/%s", + run->global->io.outputDir ? run->global->io.outputDir : run->global->io.inputDir, + run->dynfile->path); + unlink(fname); } } diff --git a/honggfuzz.c b/honggfuzz.c index ebacfad1f..aa0174bb3 100644 --- a/honggfuzz.c +++ b/honggfuzz.c @@ -265,10 +265,13 @@ static uint8_t mainThreadLoop(honggfuzz_t* hfuzz) { setupSignalsMainThread(); setupMainThreadTimer(); + uint64_t dynamicQueuePollTime = time(NULL); for (;;) { - if (hfuzz->io.dynamicInputDir) { + if (hfuzz->io.dynamicInputDir && + time(NULL) - dynamicQueuePollTime > _HF_SYNC_TIME) { LOG_D("Loading files from the dynamic input queue..."); input_enqueueDynamicInputs(hfuzz); + dynamicQueuePollTime = time(NULL); } if (hfuzz->display.useScreen) { diff --git a/honggfuzz.h b/honggfuzz.h index 6aa98d238..e86148196 100644 --- a/honggfuzz.h +++ b/honggfuzz.h @@ -77,6 +77,9 @@ /* Default maximum size of produced inputs */ #define _HF_INPUT_DEFAULT_SIZE (1024ULL * 8) +/* Time (seconds) between checking dynamic input directory to import files */ +#define _HF_SYNC_TIME 10 + /* Per-thread bitmap */ #define _HF_PERTHREAD_BITMAP_FD 1018 /* FD used to report back used int/str constants from the fuzzed process */ @@ -156,6 +159,7 @@ struct _dynfile_t { fuzzState_t phase; bool timedout; uint8_t* data; + bool imported; TAILQ_ENTRY(_dynfile_t) pointers; }; diff --git a/input.c b/input.c index ec59bd8f4..fa73ac264 100644 --- a/input.c +++ b/input.c @@ -377,6 +377,7 @@ void input_addDynamicInput(run_t* run) { dynfile->timeExecUSecs = util_timeNowUSecs() - run->timeStartedUSecs; dynfile->data = (uint8_t*)util_AllocCopy(run->dynfile->data, run->dynfile->size); dynfile->src = run->dynfile->src; + dynfile->imported = run->dynfile->imported, memcpy(dynfile->cov, run->dynfile->cov, sizeof(dynfile->cov)); if (run->dynfile->src) { ATOMIC_POST_INC(run->dynfile->src->refs); @@ -551,7 +552,13 @@ bool input_prepareDynamicInput(run_t* run, bool needs_mangle) { run->current = run->global->io.dynfileqCurrent; run->global->io.dynfileqCurrent = TAILQ_NEXT(run->global->io.dynfileqCurrent, pointers); + /* Do not count skip_factor on unmeasured (imported) inputs */ + if (run->current->imported) { + break; + } + int skip_factor = input_skipFactor(run, run->current); + if (skip_factor <= 0) { run->triesLeft = -(skip_factor); break; @@ -569,10 +576,21 @@ bool input_prepareDynamicInput(run_t* run, bool needs_mangle) { run->dynfile->refs = 0; run->dynfile->phase = fuzz_getState(run->global); run->dynfile->timedout = run->current->timedout; + run->dynfile->imported = run->current->imported; memcpy(run->dynfile->cov, run->current->cov, sizeof(run->dynfile->cov)); snprintf(run->dynfile->path, sizeof(run->dynfile->path), "%s", run->current->path); memcpy(run->dynfile->data, run->current->data, run->current->size); + /* Run unmangled imported input to measure coverage. It would be added + to dynamic queue again in case of profit. + */ + if (run->current->imported) { + TAILQ_REMOVE(&run->global->io.dynfileq, run->current, pointers); + ATOMIC_POST_DEC(run->global->io.newUnitsAdded); + run->triesLeft = 0; + return true; + } + if (needs_mangle) { mangle_mangleContent(run); } @@ -677,6 +695,7 @@ void input_enqueueDynamicInputs(honggfuzz_t* hfuzz) { .timeExecUSecs = 1, .path = "", .timedout = false, + .imported = true, .data = dynamicFile, }; tmp_run.timeStartedUSecs = util_timeNowUSecs() - 1;