mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 16:05:44 -07:00
Try to clean up fuzzpuzz a bit
I've separated out the various versions of main(), which has helped a little bit. I've also stopped using fmemopen() since libFuzzer might work on Windows. But I think I probably still have something fundamentally wrong in my approach.
This commit is contained in:
138
fuzzpuzz.c
138
fuzzpuzz.c
@ -23,6 +23,15 @@
|
|||||||
* cmake --build build-honggfuzz --target fuzzpuzz
|
* cmake --build build-honggfuzz --target fuzzpuzz
|
||||||
* mkdir fuzz-corpus && ln icons/''*.sav fuzz-corpus
|
* mkdir fuzz-corpus && ln icons/''*.sav fuzz-corpus
|
||||||
* honggfuzz -s -i fuzz-corpus -w fuzzpuzz.dict -- build-honggfuzz/fuzzpuzz
|
* honggfuzz -s -i fuzz-corpus -w fuzzpuzz.dict -- build-honggfuzz/fuzzpuzz
|
||||||
|
*
|
||||||
|
* You can also use libFuzzer, though it's not really a good fit for
|
||||||
|
* Puzzles. The experimental forking mode seems to work OK:
|
||||||
|
*
|
||||||
|
* CC=clang cmake -B build-clang
|
||||||
|
* cmake --build build-clang --target fuzzpuzz-libfuzzer
|
||||||
|
* mkdir fuzz-corpus && ln icons/''*.sav fuzz-corpus
|
||||||
|
* build-clang/fuzzpuzz-libfuzzer -fork=1 -ignore_crashes=1 \
|
||||||
|
* -dict=fuzzpuzz.dict fuzz-corpus
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
@ -85,28 +94,15 @@ static const char *fuzz_one(bool (*readfn)(void *, void *, int), void *rctx,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool savefile_read(void *wctx, void *buf, int len)
|
#if defined(__AFL_FUZZ_TESTCASE_LEN) || defined(HAVE_HF_ITER) || \
|
||||||
{
|
!defined(OMIT_MAIN)
|
||||||
FILE *fp = (FILE *)wctx;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = fread(buf, 1, len, fp);
|
|
||||||
return (ret == len);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void savefile_rewind(void *wctx)
|
|
||||||
{
|
|
||||||
FILE *fp = (FILE *)wctx;
|
|
||||||
|
|
||||||
rewind(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void savefile_write(void *wctx, const void *buf, int len)
|
static void savefile_write(void *wctx, const void *buf, int len)
|
||||||
{
|
{
|
||||||
FILE *fp = (FILE *)wctx;
|
FILE *fp = (FILE *)wctx;
|
||||||
|
|
||||||
fwrite(buf, 1, len, fp);
|
fwrite(buf, 1, len, fp);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
struct memread {
|
struct memread {
|
||||||
const unsigned char *buf;
|
const unsigned char *buf;
|
||||||
@ -145,66 +141,110 @@ int LLVMFuzzerTestOneInput(unsigned char *data, size_t size) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef OMIT_MAIN
|
#if defined(__AFL_FUZZ_TESTCASE_LEN) || defined(HAVE_HF_ITER)
|
||||||
int main(int argc, char **argv)
|
static const char *fuzz_one_mem(unsigned char *data, size_t size) {
|
||||||
{
|
struct memread ctx;
|
||||||
const char *err;
|
|
||||||
int ret = -1;
|
|
||||||
FILE *in = NULL;
|
|
||||||
|
|
||||||
if (argc != 1) {
|
ctx.buf = data;
|
||||||
fprintf(stderr, "usage: %s\n", argv[0]);
|
ctx.len = size;
|
||||||
exit(1);
|
ctx.pos = 0;
|
||||||
|
return fuzz_one(mem_read, &ctx, mem_rewind, savefile_write, stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __AFL_HAVE_MANUAL_CONTROL
|
|
||||||
__AFL_INIT();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __AFL_FUZZ_TESTCASE_LEN
|
/*
|
||||||
|
* Three different versions of main(), for standalone, AFL, and
|
||||||
|
* Honggfuzz modes. LibFuzzer brings its own main().
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef OMIT_MAIN
|
||||||
|
/* Nothing. */
|
||||||
|
#elif defined(__AFL_FUZZ_TESTCASE_LEN)
|
||||||
/*
|
/*
|
||||||
* AFL persistent mode, where we fuzz from a RAM buffer provided
|
* AFL persistent mode, where we fuzz from a RAM buffer provided
|
||||||
* by AFL in a loop. This version can still be run standalone if
|
* by AFL in a loop. This version can still be run standalone if
|
||||||
* necessary, for instance to diagnose a crash.
|
* necessary, for instance to diagnose a crash.
|
||||||
*/
|
*/
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
const char *err;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (argc != 1) {
|
||||||
|
fprintf(stderr, "usage: %s\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#ifdef __AFL_HAVE_MANUAL_CONTROL
|
||||||
|
__AFL_INIT();
|
||||||
|
#endif
|
||||||
while (__AFL_LOOP(10000)) {
|
while (__AFL_LOOP(10000)) {
|
||||||
if (in != NULL) fclose(in);
|
err = fuzz_one_mem(__AFL_FUZZ_TESTCASE_BUF, __AFL_FUZZ_TESTCASE_LEN);
|
||||||
in = fmemopen(__AFL_FUZZ_TESTCASE_BUF, __AFL_FUZZ_TESTCASE_LEN, "r");
|
if (err != NULL) {
|
||||||
if (in == NULL) {
|
fprintf(stderr, "%s\n", err);
|
||||||
fprintf(stderr, "fmemopen failed");
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
continue;
|
} else
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
#elif defined(HAVE_HF_ITER)
|
#elif defined(HAVE_HF_ITER)
|
||||||
/*
|
/*
|
||||||
* Honggfuzz persistent mode. Unlike AFL persistent mode, the
|
* Honggfuzz persistent mode. Unlike AFL persistent mode, the
|
||||||
* resulting executable cannot be run outside of Honggfuzz.
|
* resulting executable cannot be run outside of Honggfuzz.
|
||||||
*/
|
*/
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc != 1) {
|
||||||
|
fprintf(stderr, "usage: %s\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
unsigned char *testcase_buf;
|
unsigned char *testcase_buf;
|
||||||
size_t testcase_len;
|
size_t testcase_len;
|
||||||
if (in != NULL) fclose(in);
|
|
||||||
HF_ITER(&testcase_buf, &testcase_len);
|
HF_ITER(&testcase_buf, &testcase_len);
|
||||||
in = fmemopen(testcase_buf, testcase_len, "r");
|
fuzz_one_mem(testcase_buf, testcase_len);
|
||||||
if (in == NULL) {
|
}
|
||||||
fprintf(stderr, "fmemopen failed");
|
|
||||||
ret = 1;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
in = stdin;
|
/*
|
||||||
while (ret == -1) {
|
* Stand-alone mode: just handle a single test case on stdin.
|
||||||
|
*/
|
||||||
|
static bool savefile_read(void *wctx, void *buf, int len)
|
||||||
|
{
|
||||||
|
FILE *fp = (FILE *)wctx;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = fread(buf, 1, len, fp);
|
||||||
|
return (ret == len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void savefile_rewind(void *wctx)
|
||||||
|
{
|
||||||
|
FILE *fp = (FILE *)wctx;
|
||||||
|
|
||||||
|
rewind(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
const char *err;
|
||||||
|
|
||||||
|
if (argc != 1) {
|
||||||
|
fprintf(stderr, "usage: %s\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Might in theory use this mode under AFL. */
|
||||||
|
#ifdef __AFL_HAVE_MANUAL_CONTROL
|
||||||
|
__AFL_INIT();
|
||||||
#endif
|
#endif
|
||||||
err = fuzz_one(savefile_read, in, savefile_rewind,
|
|
||||||
|
err = fuzz_one(savefile_read, stdin, savefile_rewind,
|
||||||
savefile_write, stdout);
|
savefile_write, stdout);
|
||||||
if (err == NULL) {
|
if (err != NULL) {
|
||||||
ret = 0;
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "%s\n", err);
|
fprintf(stderr, "%s\n", err);
|
||||||
ret = 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
return 0;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user