ref: 311d227ba6d101cc2c3096eefd4bc795f98303da
parent: 69924f376bd58932c7c3aa3234b9f12eb1866edc
author: Ben Harris <bjh21@bjh21.me.uk>
date: Thu Jan 12 05:12:26 EST 2023
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++.
--- a/fuzzpuzz.c
+++ b/fuzzpuzz.c
@@ -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,9 +36,10 @@
{
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]);
@@ -107,30 +46,56 @@
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