diff options
| author | Ben Harris <bjh21@bjh21.me.uk> | 2023-01-12 10:12:26 +0000 |
|---|---|---|
| committer | Ben Harris <bjh21@bjh21.me.uk> | 2023-01-12 22:21:45 +0000 |
| commit | 311d227ba6d101cc2c3096eefd4bc795f98303da (patch) | |
| tree | ee9342eeacfb5ad6b6e31fa345b3327c1f9f9502 /fuzzpuzz.c | |
| parent | 69924f376bd58932c7c3aa3234b9f12eb1866edc (diff) | |
| download | puzzles-311d227ba6d101cc2c3096eefd4bc795f98303da.zip puzzles-311d227ba6d101cc2c3096eefd4bc795f98303da.tar.gz puzzles-311d227ba6d101cc2c3096eefd4bc795f98303da.tar.bz2 puzzles-311d227ba6d101cc2c3096eefd4bc795f98303da.tar.xz | |
Merge the two versions of fuzzpuzz back together
Now there's a single version of the main loop that runs once in normal
mode and repeatedly in AFL++ persistent mode. In persistent mode,
fmemopen() allows the loop to read the shared-memory buffer as though
it were a stdio stream. fmemopen() is POSIX-only, but so is AFL++.
Diffstat (limited to 'fuzzpuzz.c')
| -rw-r--r-- | fuzzpuzz.c | 145 |
1 files changed, 55 insertions, 90 deletions
@@ -13,78 +13,16 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#ifdef __AFL_FUZZ_TESTCASE_LEN +# include <unistd.h> /* read() is used by __AFL_FUZZ_TESTCASE_LEN. */ +#endif #include "puzzles.h" -#ifdef __AFL_FUZZ_TESTCASE_LEN -/* - * AFL persistent mode, where we fuzz from a RAM buffer provided by - * AFL in a loop. This version can still be run standalone if - * necessary, for instance to diagnose a crash. - */ -#include <unistd.h> - +#ifdef __AFL_FUZZ_INIT __AFL_FUZZ_INIT(); - -struct memfile { - unsigned char *buf; - int off; - int len; -}; - -static bool memfile_read(void *wctx, void *buf, int len) -{ - struct memfile *mem = (struct memfile *)wctx; - - if (mem->len - mem->off < len) return false; - memcpy(buf, mem->buf + mem->off, min(len, mem->len - mem->off)); - mem->off += len; - return true; -} - -int main(int argc, char **argv) -{ - const char *err; - char *gamename; - int i; - const game * ourgame = NULL; - midend *me; - struct memfile mem; - -#ifdef __AFL_HAVE_MANUAL_CONTROL - __AFL_INIT(); #endif - mem.buf = __AFL_FUZZ_TESTCASE_BUF; - while (__AFL_LOOP(10000)) { - - mem.off = 0; - mem.len = __AFL_FUZZ_TESTCASE_LEN; - - err = identify_game(&gamename, memfile_read, &mem); - if (err != NULL) continue; - - for (i = 0; i < gamecount; i++) - if (strcmp(gamename, gamelist[i]->name) == 0) - ourgame = gamelist[i]; - if (ourgame == NULL) continue; - - me = midend_new(NULL, ourgame, NULL, NULL); - - mem.off = 0; - - err = midend_deserialise(me, memfile_read, &mem); - midend_free(me); - } - return 0; -} - -#else - -/* - * Standard mode, where we process a single save file from stdin. - */ - static bool savefile_read(void *wctx, void *buf, int len) { FILE *fp = (FILE *)wctx; @@ -98,39 +36,66 @@ int main(int argc, char **argv) { const char *err; char *gamename; - int i; - const game * ourgame = NULL; + int i, ret = -1; + const game *ourgame = NULL; midend *me; + FILE *in = NULL; if (argc != 1) { fprintf(stderr, "usage: %s\n", argv[0]); exit(1); } - err = identify_game(&gamename, savefile_read, stdin); - if (err != NULL) { - fprintf(stderr, "%s\n", err); - exit(1); - } +#ifdef __AFL_HAVE_MANUAL_CONTROL + __AFL_INIT(); +#endif - for (i = 0; i < gamecount; i++) - if (strcmp(gamename, gamelist[i]->name) == 0) - ourgame = gamelist[i]; - if (ourgame == NULL) { - fprintf(stderr, "Game '%s' not recognised\n", gamename); - exit(1); - } +#ifdef __AFL_FUZZ_TESTCASE_LEN + /* + * AFL persistent mode, where we fuzz from a RAM buffer provided + * by AFL in a loop. This version can still be run standalone if + * necessary, for instance to diagnose a crash. + */ - me = midend_new(NULL, ourgame, NULL, NULL); + while (__AFL_LOOP(10000)) { + if (in != NULL) fclose(in); + in = fmemopen(__AFL_FUZZ_TESTCASE_BUF, __AFL_FUZZ_TESTCASE_LEN, "r"); + if (in == NULL) { + fprintf(stderr, "fmemopen failed"); + ret = 1; + continue; + } +#else + in = stdin; + while (ret == -1) { +#endif + err = identify_game(&gamename, savefile_read, in); + if (err != NULL) { + fprintf(stderr, "%s\n", err); + ret = 1; + continue; + } - rewind(stdin); - err = midend_deserialise(me, savefile_read, stdin); - if (err != NULL) { - fprintf(stderr, "%s\n", err); - exit(1); + for (i = 0; i < gamecount; i++) + if (strcmp(gamename, gamelist[i]->name) == 0) + ourgame = gamelist[i]; + if (ourgame == NULL) { + fprintf(stderr, "Game '%s' not recognised\n", gamename); + ret = 1; + continue; + } + + me = midend_new(NULL, ourgame, NULL, NULL); + + rewind(in); + err = midend_deserialise(me, savefile_read, in); + if (err != NULL) { + fprintf(stderr, "%s\n", err); + ret = 1; + continue; + } + midend_free(me); + ret = 0; } - midend_free(me); - return 0; + return ret; } - -#endif |