From 38cc374f2acc3783c07db54012201a76b5d8fec3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= Date: Thu, 14 May 2020 21:09:48 +0200 Subject: test/fuzz: add libfuzzer target for text data structure This reuses the existing fuzzing driver initially written for afl-fuzz. As a consequence, quite a bit of stdio code is involved which is probably not optimal. --- fuzz/.gitignore | 1 + fuzz/Makefile | 14 +++++++++++--- fuzz/dictionaries/text-libfuzzer.dict | 1 + fuzz/inputs/text-libfuzzer/text-libfuzzer.in | 1 + fuzz/text-fuzzer.c | 26 +++++++++++++++++++++++--- 5 files changed, 37 insertions(+), 6 deletions(-) create mode 120000 fuzz/dictionaries/text-libfuzzer.dict create mode 120000 fuzz/inputs/text-libfuzzer/text-libfuzzer.in (limited to 'fuzz') diff --git a/fuzz/.gitignore b/fuzz/.gitignore index 21d1a0c..17b5c17 100644 --- a/fuzz/.gitignore +++ b/fuzz/.gitignore @@ -1,3 +1,4 @@ /results /text-fuzzer +/text-libfuzzer /buffer-fuzzer diff --git a/fuzz/Makefile b/fuzz/Makefile index 26bb10c..6f5dc90 100644 --- a/fuzz/Makefile +++ b/fuzz/Makefile @@ -1,6 +1,6 @@ -include ../../config.mk -ALL = text-fuzzer buffer-fuzzer +ALL = text-fuzzer text-libfuzzer buffer-fuzzer CC = afl-gcc CFLAGS += -I. -I../.. -DBUFFER_SIZE=4 -DBLOCK_SIZE=4 @@ -8,7 +8,11 @@ test: $(ALL) text-fuzzer: text-fuzzer.c fuzzer.h ../../text.c ../../text-util.c ../../text-motions.c ../../text-objects.c ../../text-regex.c @echo Compiling $@ binary - ${CC} ${CFLAGS} ${CFLAGS_STD} ${CFLAGS_LIBC} ${CFLAGS_EXTRA} ${filter %.c, $^} ${LDFLAGS} -o $@ + @${CC} ${CFLAGS} ${CFLAGS_STD} ${CFLAGS_LIBC} ${CFLAGS_EXTRA} ${filter %.c, $^} ${LDFLAGS} -o $@ + +text-libfuzzer: text-fuzzer.c fuzzer.h ../../text.c ../../text-util.c ../../text-motions.c ../../text-objects.c ../../text-regex.c + @echo Compiling $@ binary + @${CC} ${CFLAGS} ${CFLAGS_STD} ${CFLAGS_LIBC} ${CFLAGS_EXTRA} -DLIBFUZZER ${filter %.c, $^} -fsanitize=fuzzer,address,undefined ${LDFLAGS} -o $@ buffer-fuzzer: buffer-fuzzer.c fuzzer.h ../../buffer.c @echo Compiling $@ binary @@ -22,6 +26,10 @@ afl-fuzz-text: text-fuzzer @afl-fuzz -i - -x "dictionaries/$<.dict" -o "results/$<" -- "./$<" || \ afl-fuzz -i "inputs/$<" -x "dictionaries/$<.dict" -o "results/$<" -- "./$<" +libfuzzer-text: text-libfuzzer + @mkdir -p "results/$<" + @./$< -close_fd_mask=1 -only_ascii=1 -print_final_stats=1 "-dict=dictionaries/$<.dict" "inputs/$<" "results/$<" + afl-fuzz-buffer: buffer-fuzzer @mkdir -p "results/$<" @afl-fuzz -i - -x "dictionaries/$<.dict" -o "results/$<" -- "./$<" || \ @@ -34,4 +42,4 @@ clean: distclean: clean @rm -rf results/ -.PHONY: clean distclean debug afl-fuzz-text afl-fuzz-buffer +.PHONY: clean distclean debug afl-fuzz-text libfuzzer-text afl-fuzz-buffer diff --git a/fuzz/dictionaries/text-libfuzzer.dict b/fuzz/dictionaries/text-libfuzzer.dict new file mode 120000 index 0000000..f5e49a7 --- /dev/null +++ b/fuzz/dictionaries/text-libfuzzer.dict @@ -0,0 +1 @@ +text-fuzzer.dict \ No newline at end of file diff --git a/fuzz/inputs/text-libfuzzer/text-libfuzzer.in b/fuzz/inputs/text-libfuzzer/text-libfuzzer.in new file mode 120000 index 0000000..e351471 --- /dev/null +++ b/fuzz/inputs/text-libfuzzer/text-libfuzzer.in @@ -0,0 +1 @@ +../text-fuzzer/text-fuzzer.in \ No newline at end of file diff --git a/fuzz/text-fuzzer.c b/fuzz/text-fuzzer.c index ddb132b..c09d7be 100644 --- a/fuzz/text-fuzzer.c +++ b/fuzz/text-fuzzer.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -112,8 +113,7 @@ static Cmd commands[] = { ['u'] = cmd_undo, }; -int main(int argc, char *argv[]) { - char line[BUFSIZ], *name = (argc == 1) ? NULL : argv[1]; +static int repl(const char *name, FILE *input) { Text *txt = text_load(name); if (!name) name = "-"; @@ -124,9 +124,10 @@ int main(int argc, char *argv[]) { printf("Loaded %zu bytes from `%s'\n", text_size(txt), name); + char line[BUFSIZ]; for (;;) { printf("> "); - if (!fgets(line, sizeof(line), stdin)) + if (!fgets(line, sizeof(line), input)) break; if (!isatty(0)) printf("%s", line); @@ -147,3 +148,22 @@ int main(int argc, char *argv[]) { return 0; } + +#ifdef LIBFUZZER + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t len) { + FILE *input = fmemopen((void*)data, len, "r"); + if (!input) + return 1; + int r = repl(NULL, input); + fclose(input); + return r; +} + +#else + +int main(int argc, char *argv[]) { + return repl(argc == 1 ? NULL : argv[1], stdin); +} + +#endif /* LIBFUZZER */ -- cgit v1.2.3