ref: 69924f376bd58932c7c3aa3234b9f12eb1866edc
parent: 53a1faa0d758c86c5bc77808c4265129d627be1b
author: Ben Harris <bjh21@bjh21.me.uk>
date: Sat Jan 7 20:03:17 EST 2023
AFL-specific shared-memory fuzzing mode Rather than a save file from standard input and then exiting, this reads it from a shared memory buffer and then loops. This makes fuzzing _much_ faster: one core on my laptop can now load about 30,000 save files per second.
--- a/fuzzpuzz.c
+++ b/fuzzpuzz.c
@@ -16,6 +16,75 @@
#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>
+
+__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;
@@ -63,3 +132,5 @@
midend_free(me);
return 0;
}
+
+#endif