summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrobertswiecki <robert@swiecki.net>2019-04-08 22:46:28 +0200
committerGitHub <noreply@github.com>2019-04-08 22:46:28 +0200
commit7bf82afd97be1728674e996bdcf9f838f7807d5c (patch)
treedfd5e57434a8e6ebf4da2c397c0233b2b0d2328b
parent868dccfed95dcbbaf7840683c4e9ca466be7bb9c (diff)
parentc7566f6a86ec3197dc9fadd099708b9aa950838b (diff)
downloadhonggfuzz-7bf82afd97be1728674e996bdcf9f838f7807d5c.tar.gz
Merge pull request #250 from arnow117/master-add-support
Add support for external custom feedback data mutator command
-rw-r--r--cmdline.c5
-rw-r--r--fuzz.c21
-rw-r--r--honggfuzz.h1
-rw-r--r--input.c42
-rw-r--r--input.h5
5 files changed, 65 insertions, 9 deletions
diff --git a/cmdline.c b/cmdline.c
index fe40c86b..9d203fa0 100644
--- a/cmdline.c
+++ b/cmdline.c
@@ -274,6 +274,7 @@ bool cmdlineParse(int argc, char* argv[], honggfuzz_t* hfuzz) {
.fuzzStdin = false,
.externalCommand = NULL,
.postExternalCommand = NULL,
+ .feedbackMutateCommand = NULL,
.persistent = false,
.netDriver = false,
.asLimit = 0U,
@@ -420,6 +421,7 @@ bool cmdlineParse(int argc, char* argv[], honggfuzz_t* hfuzz) {
{ { "stackhash_bl", required_argument, NULL, 'B' }, "Stackhashes blacklist file (one entry per line)" },
{ { "mutate_cmd", required_argument, NULL, 'c' }, "External command producing fuzz files (instead of internal mutators)" },
{ { "pprocess_cmd", required_argument, NULL, 0x104 }, "External command postprocessing files produced by internal mutators" },
+ { { "ffmutate_cmd", required_argument, NULL, 0x110 }, "External command mutating files which have effective coverage feedback" },
{ { "run_time", required_argument, NULL, 0x109 }, "Number of seconds this fuzzing session will last (default: 0 [no limit])" },
{ { "iterations", required_argument, NULL, 'N' }, "Number of fuzzing iterations (default: 0 [no limit])" },
{ { "rlimit_as", required_argument, NULL, 0x100 }, "Per process RLIMIT_AS in MiB (default: 0 [no limit])" },
@@ -594,6 +596,9 @@ bool cmdlineParse(int argc, char* argv[], honggfuzz_t* hfuzz) {
case 0x104:
hfuzz->exe.postExternalCommand = optarg;
break;
+ case 0x110:
+ hfuzz->exe.feedbackMutateCommand = optarg;
+ break;
case 0x105:
if ((strcasecmp(optarg, "0") == 0) || (strcasecmp(optarg, "false") == 0)) {
hfuzz->cfg.monitorSIGABRT = false;
diff --git a/fuzz.c b/fuzz.c
index 0e2e8dc0..29e7a99b 100644
--- a/fuzz.c
+++ b/fuzz.c
@@ -314,7 +314,7 @@ static bool fuzz_fetchInput(run_t* run) {
fuzzState_t st = fuzz_getState(run->global);
if (st == _HF_STATE_DYNAMIC_DRY_RUN || st == _HF_STATE_DYNAMIC_SWITCH_TO_MAIN) {
run->mutationsPerRun = 0U;
- if (input_prepareStaticFile(run, /* rewind= */ false)) {
+ if (input_prepareStaticFile(run, /* rewind= */ false, true)) {
return true;
}
fuzz_setDynamicMainState(run);
@@ -328,7 +328,12 @@ static bool fuzz_fetchInput(run_t* run) {
LOG_E("input_prepareFileExternally() failed");
return false;
}
- } else if (!input_prepareDynamicInput(run)) {
+ } else if (run->global->exe.feedbackMutateCommand){
+ if (!input_prepareDynamicInput(run, false)){
+ LOG_E("input_prepareFileDynamically() failed");
+ return false;
+ }
+ } else if (!input_prepareDynamicInput(run, true)) {
LOG_E("input_prepareFileDynamically() failed");
return false;
}
@@ -340,7 +345,12 @@ static bool fuzz_fetchInput(run_t* run) {
LOG_E("input_prepareFileExternally() failed");
return false;
}
- } else if (!input_prepareStaticFile(run, true /* rewind */)) {
+ } else if (run->global->exe.feedbackMutateCommand){
+ if (!input_prepareStaticFile(run, true, false)){
+ LOG_E("input_prepareFileDynamically() failed");
+ return false;
+ }
+ } else if (!input_prepareStaticFile(run, true /* rewind */, true)) {
LOG_E("input_prepareFile() failed");
return false;
}
@@ -351,6 +361,11 @@ static bool fuzz_fetchInput(run_t* run) {
return false;
}
+ if (run->global->exe.feedbackMutateCommand && !input_feedbackMutateFile(run)) {
+ LOG_E("input_feedbackMutateFile() failed");
+ return false;
+ }
+
return true;
}
diff --git a/honggfuzz.h b/honggfuzz.h
index 5847c036..8be9b283 100644
--- a/honggfuzz.h
+++ b/honggfuzz.h
@@ -207,6 +207,7 @@ typedef struct {
bool fuzzStdin;
const char* externalCommand;
const char* postExternalCommand;
+ const char* feedbackMutateCommand;
bool netDriver;
bool persistent;
uint64_t asLimit;
diff --git a/input.c b/input.c
index b3de4c37..3a9db7d5 100644
--- a/input.c
+++ b/input.c
@@ -311,7 +311,7 @@ bool input_parseBlacklist(honggfuzz_t* hfuzz) {
return true;
}
-bool input_prepareDynamicInput(run_t* run) {
+bool input_prepareDynamicInput(run_t* run, bool need_mangele) {
{
MX_SCOPED_RWLOCK_READ(&run->global->io.dynfileq_mutex);
@@ -332,12 +332,13 @@ bool input_prepareDynamicInput(run_t* run) {
input_setSize(run, run->dynfileqCurrent->size);
memcpy(run->dynamicFile, run->dynfileqCurrent->data, run->dynfileqCurrent->size);
- mangle_mangleContent(run);
+ if (need_mangele)
+ mangle_mangleContent(run);
return true;
}
-bool input_prepareStaticFile(run_t* run, bool rewind) {
+bool input_prepareStaticFile(run_t* run, bool rewind, bool need_mangele) {
char fname[PATH_MAX];
if (!input_getNext(run, fname, /* rewind= */ rewind)) {
return false;
@@ -352,7 +353,8 @@ bool input_prepareStaticFile(run_t* run, bool rewind) {
}
input_setSize(run, fileSz);
- mangle_mangleContent(run);
+ if (need_mangele)
+ mangle_mangleContent(run);
return true;
}
@@ -421,3 +423,35 @@ bool input_postProcessFile(run_t* run) {
input_setSize(run, (size_t)sz);
return true;
}
+
+bool input_feedbackMutateFile(run_t* run) {
+ int fd =
+ files_writeBufToTmpFile(run->global->io.workDir, run->dynamicFile, run->dynamicFileSz, 0);
+ if (fd == -1) {
+ LOG_E("Couldn't write input file to a temporary buffer");
+ return false;
+ }
+ defer {
+ close(fd);
+ };
+
+ char fname[PATH_MAX];
+ snprintf(fname, sizeof(fname), "/dev/fd/%d", fd);
+
+ const char* const argv[] = {run->global->exe.feedbackMutateCommand, fname, NULL};
+ if (subproc_System(run, argv) != 0) {
+ LOG_E("Subprocess '%s' returned abnormally", run->global->exe.feedbackMutateCommand);
+ return false;
+ }
+ LOG_D("Subporcess '%s' finished with success", run->global->exe.externalCommand);
+
+ input_setSize(run, run->global->mutate.maxFileSz);
+ ssize_t sz = files_readFromFdSeek(fd, run->dynamicFile, run->global->mutate.maxFileSz, 0);
+ if (sz == -1) {
+ LOG_E("Couldn't read file from fd=%d", fd);
+ return false;
+ }
+
+ input_setSize(run, (size_t)sz);
+ return true;
+} \ No newline at end of file
diff --git a/input.h b/input.h
index 769335a5..15664ce7 100644
--- a/input.h
+++ b/input.h
@@ -31,9 +31,10 @@ extern bool input_getNext(run_t* run, char* fname, bool rewind);
extern bool input_init(honggfuzz_t* hfuzz);
extern bool input_parseDictionary(honggfuzz_t* hfuzz);
extern bool input_parseBlacklist(honggfuzz_t* hfuzz);
-extern bool input_prepareDynamicInput(run_t* run);
-extern bool input_prepareStaticFile(run_t* run, bool rewind);
+extern bool input_prepareDynamicInput(run_t* run, bool need_mangele);
+extern bool input_prepareStaticFile(run_t* run, bool rewind, bool need_mangele);
extern bool input_prepareExternalFile(run_t* run);
extern bool input_postProcessFile(run_t* run);
+extern bool input_feedbackMutateFile(run_t* run);
#endif /* ifndef _HF_INPUT_H_ */