update honggfuzz custom mutator. make update is all it takes to stay current :)

This commit is contained in:
van Hauser
2020-08-04 23:33:35 +02:00
parent c8354d7516
commit 8ed6207b5c
4 changed files with 261 additions and 337 deletions

View File

@ -7,6 +7,8 @@ honggfuzz.so: honggfuzz.c input.h mangle.c ../../src/afl-performance.c
$(CC) $(CFLAGS) -I../../include -I. -shared -o honggfuzz.so honggfuzz.c mangle.c ../../src/afl-performance.c $(CC) $(CFLAGS) -I../../include -I. -shared -o honggfuzz.so honggfuzz.c mangle.c ../../src/afl-performance.c
update: update:
@# seriously? --unlink is a dud option? sigh ...
rm -f mangle.c mangle.h honggfuzz.h
wget --unlink https://github.com/google/honggfuzz/raw/master/mangle.c wget --unlink https://github.com/google/honggfuzz/raw/master/mangle.c
wget --unlink https://github.com/google/honggfuzz/raw/master/mangle.h wget --unlink https://github.com/google/honggfuzz/raw/master/mangle.h
wget --unlink https://github.com/google/honggfuzz/raw/master/honggfuzz.h wget --unlink https://github.com/google/honggfuzz/raw/master/honggfuzz.h

View File

@ -39,10 +39,9 @@
#include "libhfcommon/util.h" #include "libhfcommon/util.h"
#define PROG_NAME "honggfuzz" #define PROG_NAME "honggfuzz"
#define PROG_VERSION "2.2" #define PROG_VERSION "2.3"
/* Name of the template which will be replaced with the proper name of the file /* Name of the template which will be replaced with the proper name of the file */
*/
#define _HF_FILE_PLACEHOLDER "___FILE___" #define _HF_FILE_PLACEHOLDER "___FILE___"
/* Default name of the report created with some architectures */ /* Default name of the report created with some architectures */
@ -63,8 +62,7 @@
/* Number of crash verifier iterations before tag crash as stable */ /* Number of crash verifier iterations before tag crash as stable */
#define _HF_VERIFIER_ITER 5 #define _HF_VERIFIER_ITER 5
/* Size (in bytes) for report data to be stored in stack before written to file /* Size (in bytes) for report data to be stored in stack before written to file */
*/
#define _HF_REPORT_SIZE 32768 #define _HF_REPORT_SIZE 32768
/* Perf bitmap size */ /* Perf bitmap size */
@ -105,30 +103,24 @@ static const uint8_t HFReadyTag = 'R';
/* Maximum number of active fuzzing threads */ /* Maximum number of active fuzzing threads */
#define _HF_THREAD_MAX 1024U #define _HF_THREAD_MAX 1024U
/* Persistent-binary signature - if found within file, it means it's a /* Persistent-binary signature - if found within file, it means it's a persistent mode binary */
* persistent mode binary */
#define _HF_PERSISTENT_SIG "\x01_LIBHFUZZ_PERSISTENT_BINARY_SIGNATURE_\x02\xFF" #define _HF_PERSISTENT_SIG "\x01_LIBHFUZZ_PERSISTENT_BINARY_SIGNATURE_\x02\xFF"
/* HF NetDriver signature - if found within file, it means it's a /* HF NetDriver signature - if found within file, it means it's a NetDriver-based binary */
* NetDriver-based binary */
#define _HF_NETDRIVER_SIG "\x01_LIBHFUZZ_NETDRIVER_BINARY_SIGNATURE_\x02\xFF" #define _HF_NETDRIVER_SIG "\x01_LIBHFUZZ_NETDRIVER_BINARY_SIGNATURE_\x02\xFF"
/* printf() nonmonetary separator. According to MacOSX's man it's supported /* printf() nonmonetary separator. According to MacOSX's man it's supported there as well */
* there as well */
#define _HF_NONMON_SEP "'" #define _HF_NONMON_SEP "'"
typedef enum { typedef enum {
_HF_DYNFILE_NONE = 0x0, _HF_DYNFILE_NONE = 0x0,
_HF_DYNFILE_INSTR_COUNT = 0x1, _HF_DYNFILE_INSTR_COUNT = 0x1,
_HF_DYNFILE_BRANCH_COUNT = 0x2, _HF_DYNFILE_BRANCH_COUNT = 0x2,
_HF_DYNFILE_BTS_EDGE = 0x10, _HF_DYNFILE_BTS_EDGE = 0x10,
_HF_DYNFILE_IPT_BLOCK = 0x20, _HF_DYNFILE_IPT_BLOCK = 0x20,
_HF_DYNFILE_SOFT = 0x40, _HF_DYNFILE_SOFT = 0x40,
} dynFileMethod_t; } dynFileMethod_t;
typedef struct { typedef struct {
uint64_t cpuInstrCnt; uint64_t cpuInstrCnt;
uint64_t cpuBranchCnt; uint64_t cpuBranchCnt;
uint64_t bbCnt; uint64_t bbCnt;
@ -136,54 +128,44 @@ typedef struct {
uint64_t softCntPc; uint64_t softCntPc;
uint64_t softCntEdge; uint64_t softCntEdge;
uint64_t softCntCmp; uint64_t softCntCmp;
} hwcnt_t; } hwcnt_t;
typedef enum { typedef enum {
_HF_STATE_UNSET = 0, _HF_STATE_UNSET = 0,
_HF_STATE_STATIC, _HF_STATE_STATIC,
_HF_STATE_DYNAMIC_DRY_RUN, _HF_STATE_DYNAMIC_DRY_RUN,
_HF_STATE_DYNAMIC_MAIN, _HF_STATE_DYNAMIC_MAIN,
_HF_STATE_DYNAMIC_MINIMIZE, _HF_STATE_DYNAMIC_MINIMIZE,
} fuzzState_t; } fuzzState_t;
typedef enum { typedef enum {
HF_MAYBE = -1, HF_MAYBE = -1,
HF_NO = 0, HF_NO = 0,
HF_YES = 1, HF_YES = 1,
} tristate_t; } tristate_t;
struct _dynfile_t { struct _dynfile_t {
size_t size; size_t size;
uint64_t cov[4]; uint64_t cov[4];
size_t idx; size_t idx;
int fd; int fd;
uint64_t timeExecUSecs; uint64_t timeExecUSecs;
char path[PATH_MAX]; char path[PATH_MAX];
struct _dynfile_t *src; struct _dynfile_t* src;
uint32_t refs; uint32_t refs;
uint8_t * data; uint8_t* data;
TAILQ_ENTRY(_dynfile_t) pointers; TAILQ_ENTRY(_dynfile_t) pointers;
}; };
typedef struct _dynfile_t dynfile_t; typedef struct _dynfile_t dynfile_t;
struct strings_t { struct strings_t {
size_t len; size_t len;
TAILQ_ENTRY(strings_t) pointers; TAILQ_ENTRY(strings_t) pointers;
char s[]; char s[];
}; };
typedef struct { typedef struct {
uint8_t pcGuardMap[_HF_PC_GUARD_MAX]; uint8_t pcGuardMap[_HF_PC_GUARD_MAX];
uint8_t bbMapPc[_HF_PERF_BITMAP_SIZE_16M]; uint8_t bbMapPc[_HF_PERF_BITMAP_SIZE_16M];
uint32_t bbMapCmp[_HF_PERF_BITMAP_SIZE_16M]; uint32_t bbMapCmp[_HF_PERF_BITMAP_SIZE_16M];
@ -194,66 +176,53 @@ typedef struct {
uint64_t pidTotalPC[_HF_THREAD_MAX]; uint64_t pidTotalPC[_HF_THREAD_MAX];
uint64_t pidTotalEdge[_HF_THREAD_MAX]; uint64_t pidTotalEdge[_HF_THREAD_MAX];
uint64_t pidTotalCmp[_HF_THREAD_MAX]; uint64_t pidTotalCmp[_HF_THREAD_MAX];
} feedback_t; } feedback_t;
typedef struct { typedef struct {
uint32_t cnt; uint32_t cnt;
struct { struct {
uint8_t val[32]; uint8_t val[32];
uint32_t len; uint32_t len;
} valArr[1024 * 16]; } valArr[1024 * 16];
} cmpfeedback_t; } cmpfeedback_t;
typedef struct { typedef struct {
struct { struct {
size_t threadsMax; size_t threadsMax;
size_t threadsFinished; size_t threadsFinished;
uint32_t threadsActiveCnt; uint32_t threadsActiveCnt;
pthread_t mainThread; pthread_t mainThread;
pid_t mainPid; pid_t mainPid;
pthread_t threads[_HF_THREAD_MAX]; pthread_t threads[_HF_THREAD_MAX];
} threads; } threads;
struct { struct {
const char* inputDir;
const char *inputDir; const char* outputDir;
const char *outputDir; DIR* inputDirPtr;
DIR * inputDirPtr;
size_t fileCnt; size_t fileCnt;
size_t testedFileCnt; size_t testedFileCnt;
const char *fileExtn; const char* fileExtn;
size_t maxFileSz; size_t maxFileSz;
size_t newUnitsAdded; size_t newUnitsAdded;
char workDir[PATH_MAX]; char workDir[PATH_MAX];
const char *crashDir; const char* crashDir;
const char *covDirNew; const char* covDirNew;
bool saveUnique; bool saveUnique;
size_t dynfileqMaxSz; size_t dynfileqMaxSz;
size_t dynfileqCnt; size_t dynfileqCnt;
dynfile_t * dynfileqCurrent; dynfile_t* dynfileqCurrent;
dynfile_t * dynfileq2Current; dynfile_t* dynfileq2Current;
TAILQ_HEAD(dyns_t, _dynfile_t) dynfileq; TAILQ_HEAD(dyns_t, _dynfile_t) dynfileq;
bool exportFeedback; bool exportFeedback;
} io; } io;
struct { struct {
int argc; int argc;
const char *const *cmdline; const char* const* cmdline;
bool nullifyStdio; bool nullifyStdio;
bool fuzzStdin; bool fuzzStdin;
const char * externalCommand; const char* externalCommand;
const char * postExternalCommand; const char* postExternalCommand;
const char * feedbackMutateCommand; const char* feedbackMutateCommand;
bool netDriver; bool netDriver;
bool persistent; bool persistent;
uint64_t asLimit; uint64_t asLimit;
@ -262,162 +231,122 @@ typedef struct {
uint64_t coreLimit; uint64_t coreLimit;
uint64_t stackLimit; uint64_t stackLimit;
bool clearEnv; bool clearEnv;
char * env_ptrs[128]; char* env_ptrs[128];
char env_vals[128][4096]; char env_vals[128][4096];
sigset_t waitSigSet; sigset_t waitSigSet;
} exe; } exe;
struct { struct {
time_t timeStart; time_t timeStart;
time_t runEndTime; time_t runEndTime;
time_t tmOut; time_t tmOut;
time_t lastCovUpdate; time_t lastCovUpdate;
int64_t timeOfLongestUnitUSecs; int64_t timeOfLongestUnitUSecs;
bool tmoutVTALRM; bool tmoutVTALRM;
} timing; } timing;
struct { struct {
struct { struct {
uint8_t val[256]; uint8_t val[256];
size_t len; size_t len;
} dictionary[1024]; } dictionary[1024];
size_t dictionaryCnt; size_t dictionaryCnt;
const char *dictionaryFile; const char* dictionaryFile;
size_t mutationsMax; size_t mutationsMax;
unsigned mutationsPerRun; unsigned mutationsPerRun;
size_t maxInputSz; size_t maxInputSz;
} mutate; } mutate;
struct { struct {
bool useScreen; bool useScreen;
char cmdline_txt[65]; char cmdline_txt[65];
int64_t lastDisplayUSecs; int64_t lastDisplayUSecs;
} display; } display;
struct { struct {
bool useVerifier; bool useVerifier;
bool exitUponCrash; bool exitUponCrash;
const char *reportFile; const char* reportFile;
size_t dynFileIterExpire; size_t dynFileIterExpire;
bool only_printable; bool only_printable;
bool minimize; bool minimize;
bool switchingToFDM; bool switchingToFDM;
} cfg; } cfg;
struct { struct {
bool enable; bool enable;
bool del_report; bool del_report;
} sanitizer; } sanitizer;
struct { struct {
fuzzState_t state; fuzzState_t state;
feedback_t * covFeedbackMap; feedback_t* covFeedbackMap;
int covFeedbackFd; int covFeedbackFd;
cmpfeedback_t * cmpFeedbackMap; cmpfeedback_t* cmpFeedbackMap;
int cmpFeedbackFd; int cmpFeedbackFd;
bool cmpFeedback; bool cmpFeedback;
const char * blacklistFile; const char* blacklistFile;
uint64_t * blacklist; uint64_t* blacklist;
size_t blacklistCnt; size_t blacklistCnt;
bool skipFeedbackOnTimeout; bool skipFeedbackOnTimeout;
uint64_t maxCov[4]; uint64_t maxCov[4];
dynFileMethod_t dynFileMethod; dynFileMethod_t dynFileMethod;
hwcnt_t hwCnts; hwcnt_t hwCnts;
} feedback; } feedback;
struct { struct {
size_t mutationsCnt; size_t mutationsCnt;
size_t crashesCnt; size_t crashesCnt;
size_t uniqueCrashesCnt; size_t uniqueCrashesCnt;
size_t verifiedCrashesCnt; size_t verifiedCrashesCnt;
size_t blCrashesCnt; size_t blCrashesCnt;
size_t timeoutedCnt; size_t timeoutedCnt;
} cnts; } cnts;
struct { struct {
bool enabled; bool enabled;
int serverSocket; int serverSocket;
int clientSocket; int clientSocket;
} socketFuzzer; } socketFuzzer;
struct { struct {
pthread_rwlock_t dynfileq; pthread_rwlock_t dynfileq;
pthread_mutex_t feedback; pthread_mutex_t feedback;
pthread_mutex_t report; pthread_mutex_t report;
pthread_mutex_t state; pthread_mutex_t state;
pthread_mutex_t input; pthread_mutex_t input;
pthread_mutex_t timing; pthread_mutex_t timing;
} mutex; } mutex;
/* For the Linux code */ /* For the Linux code */
struct { struct {
int exeFd; int exeFd;
uint64_t dynamicCutOffAddr; uint64_t dynamicCutOffAddr;
bool disableRandomization; bool disableRandomization;
void * ignoreAddr; void* ignoreAddr;
const char *symsBlFile; const char* symsBlFile;
char ** symsBl; char** symsBl;
size_t symsBlCnt; size_t symsBlCnt;
const char *symsWlFile; const char* symsWlFile;
char ** symsWl; char** symsWl;
size_t symsWlCnt; size_t symsWlCnt;
uintptr_t cloneFlags; uintptr_t cloneFlags;
tristate_t useNetNs; tristate_t useNetNs;
bool kernelOnly; bool kernelOnly;
bool useClone; bool useClone;
} arch_linux; } arch_linux;
/* For the NetBSD code */ /* For the NetBSD code */
struct { struct {
void* ignoreAddr;
void * ignoreAddr; const char* symsBlFile;
const char *symsBlFile; char** symsBl;
char ** symsBl;
size_t symsBlCnt; size_t symsBlCnt;
const char *symsWlFile; const char* symsWlFile;
char ** symsWl; char** symsWl;
size_t symsWlCnt; size_t symsWlCnt;
} arch_netbsd; } arch_netbsd;
} honggfuzz_t; } honggfuzz_t;
typedef enum { typedef enum {
_HF_RS_UNKNOWN = 0, _HF_RS_UNKNOWN = 0,
_HF_RS_WAITING_FOR_INITIAL_READY = 1, _HF_RS_WAITING_FOR_INITIAL_READY = 1,
_HF_RS_WAITING_FOR_READY = 2, _HF_RS_WAITING_FOR_READY = 2,
_HF_RS_SEND_DATA = 3, _HF_RS_SEND_DATA = 3,
} runState_t; } runState_t;
typedef struct { typedef struct {
honggfuzz_t* global;
honggfuzz_t *global;
pid_t pid; pid_t pid;
int64_t timeStartedUSecs; int64_t timeStartedUSecs;
char crashFileName[PATH_MAX]; char crashFileName[PATH_MAX];
@ -428,33 +357,29 @@ typedef struct {
char report[_HF_REPORT_SIZE]; char report[_HF_REPORT_SIZE];
bool mainWorker; bool mainWorker;
unsigned mutationsPerRun; unsigned mutationsPerRun;
dynfile_t * dynfile; dynfile_t* dynfile;
bool staticFileTryMore; bool staticFileTryMore;
uint32_t fuzzNo; uint32_t fuzzNo;
int persistentSock; int persistentSock;
runState_t runState; runState_t runState;
bool tmOutSignaled; bool tmOutSignaled;
char * args[_HF_ARGS_MAX + 1]; char* args[_HF_ARGS_MAX + 1];
int perThreadCovFeedbackFd; int perThreadCovFeedbackFd;
unsigned triesLeft; unsigned triesLeft;
dynfile_t * current; dynfile_t* current;
#if !defined(_HF_ARCH_DARWIN) #if !defined(_HF_ARCH_DARWIN)
timer_t timerId; timer_t timerId;
#endif // !defined(_HF_ARCH_DARWIN) #endif // !defined(_HF_ARCH_DARWIN)
hwcnt_t hwCnts; hwcnt_t hwCnts;
struct { struct {
/* For Linux code */ /* For Linux code */
uint8_t *perfMmapBuf; uint8_t* perfMmapBuf;
uint8_t *perfMmapAux; uint8_t* perfMmapAux;
int cpuInstrFd; int cpuInstrFd;
int cpuBranchFd; int cpuBranchFd;
int cpuIptBtsFd; int cpuIptBtsFd;
} arch_linux; } arch_linux;
} run_t; } run_t;
#endif #endif

View File

@ -51,7 +51,7 @@ static inline size_t mangle_LenLeft(run_t *run, size_t off) {
} }
/* Get a random value between <1:max> with x^2 distribution */ /* Get a random value <1:max>, but prefer smaller ones - up to 4KiB */
static inline size_t mangle_getLen(size_t max) { static inline size_t mangle_getLen(size_t max) {
if (max > _HF_INPUT_MAX_SIZE) { if (max > _HF_INPUT_MAX_SIZE) {
@ -64,27 +64,25 @@ static inline size_t mangle_getLen(size_t max) {
if (max == 0) { LOG_F("max == 0"); } if (max == 0) { LOG_F("max == 0"); }
if (max == 1) { return 1; } if (max == 1) { return 1; }
const uint64_t max2 = (uint64_t)max * max; /* Give 50% chance the the uniform distribution */
const uint64_t max3 = (uint64_t)max * max * max; switch (util_rndGet(0, 9)) {
const uint64_t rnd = util_rndGet(1, max2 - 1);
uint64_t ret = rnd * rnd; case 0:
ret /= max3; return (size_t)util_rndGet(1, HF_MIN(16, max));
ret += 1; case 1:
return (size_t)util_rndGet(1, HF_MIN(64, max));
if (ret < 1) { case 2:
return (size_t)util_rndGet(1, HF_MIN(256, max));
LOG_F("ret (%" PRIu64 ") < 1, max:%zu, rnd:%" PRIu64, ret, max, rnd); case 3:
return (size_t)util_rndGet(1, HF_MIN(1024, max));
case 4:
return (size_t)util_rndGet(1, HF_MIN(4096, max));
default:
break;
} }
if (ret > max) { return (size_t)util_rndGet(1, max);
LOG_F("ret (%" PRIu64 ") > max (%zu), rnd:%" PRIu64, ret, max, rnd);
}
return (size_t)ret;
} }

View File

@ -26,7 +26,6 @@
#include "honggfuzz.h" #include "honggfuzz.h"
extern void mangle_mangleContent(run_t *run, int speed_factor); extern void mangle_mangleContent(run_t* run, int speed_factor);
#endif #endif