From cdd8d8ba9f7026b0a68d34d27aa4a7901505caf4 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Sat, 4 Jan 2020 15:34:28 +0100 Subject: fuzz: add generic command argument fuzzer Signed-off-by: Jason A. Donenfeld --- src/fuzz/.gitignore | 2 ++ src/fuzz/Makefile | 9 ++++--- src/fuzz/cmd.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/fuzz/stringlist.c | 2 +- src/fuzz/uapi.c | 2 +- 5 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 src/fuzz/cmd.c diff --git a/src/fuzz/.gitignore b/src/fuzz/.gitignore index 988712e..3b69fda 100644 --- a/src/fuzz/.gitignore +++ b/src/fuzz/.gitignore @@ -1,2 +1,4 @@ config uapi +stringlist +cmd diff --git a/src/fuzz/Makefile b/src/fuzz/Makefile index 3fb2970..cb9db3b 100644 --- a/src/fuzz/Makefile +++ b/src/fuzz/Makefile @@ -2,10 +2,10 @@ # # Copyright (C) 2018-2020 Jason A. Donenfeld . All Rights Reserved. -all: config uapi stringlist +all: config uapi stringlist cmd CFLAGS ?= -O3 -march=native -g -CFLAGS += -fsanitize=fuzzer -fsanitize=address -std=gnu11 -idirafter ../uapi +CFLAGS += -fsanitize=fuzzer -fsanitize=address -std=gnu11 -idirafter ../uapi -D_GNU_SOURCE CC := clang config: config.c ../config.c ../encoding.c @@ -17,7 +17,10 @@ uapi: uapi.c ../ipc.c ../curve25519.c ../encoding.c stringlist: stringlist.c ../ipc.c ../curve25519.c ../encoding.c $(CC) $(CFLAGS) -o $@ $< +cmd: cmd.c $(wildcard ../*.c) + $(CC) $(CFLAGS) -D'RUNSTATEDIR="/var/empty"' -D'main(a,b)=wg_main(a,b)' -o $@ $^ -lmnl + clean: - rm -f config uapi stringlist + rm -f config uapi stringlist cmd .PHONY: all clean diff --git a/src/fuzz/cmd.c b/src/fuzz/cmd.c new file mode 100644 index 0000000..8d75eb7 --- /dev/null +++ b/src/fuzz/cmd.c @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018-2020 Jason A. Donenfeld . All Rights Reserved. + */ + +#include +#include +#include +#include + +const char *__asan_default_options() +{ + return "verbosity=1"; +} + +int wg_main(int argc, char *argv[]); + +static FILE *devnull; + +int LLVMFuzzerTestOneInput(const char *data, size_t data_len) +{ + char *argv[8192] = { 0 }, *args; + size_t argc = 0; + FILE *fake_stdin = NULL; + + if (!devnull) { + assert((devnull = fopen("/dev/null", "r+"))); + stdin = stdout = stderr = devnull; + } + + assert((args = malloc(data_len))); + memcpy(args, data, data_len); + if (data_len) + args[data_len - 1] = '\0'; + + for (const char *arg = args; argc < 8192 && arg - args < data_len; arg += strlen(arg) + 1) { + if (arg[0]) + assert((argv[argc++] = strdup(arg))); + } + if (!argc) + assert((argv[argc++] = strdup("no argv[0]!"))); + if (argc > 2 && (!strcmp(argv[1], "show") || !strcmp(argv[1], "showconf") || !strcmp(argv[1], "set") || !strcmp(argv[1], "setconf") || !strcmp(argv[1], "addconf") || !strcmp(argv[1], "syncconf"))) { + free(argv[2]); + assert((argv[2] = strdup("wg0"))); + } + if (argc >= 2 && !strcmp(argv[1], "pubkey")) { + char *arg; + size_t len; + + for (size_t i = 2; i < argc; ++i) + free(argv[i]); + argc = 2; + arg = args; + for (; !arg[0]; ++arg); + arg += strlen(arg) + 1; + for (; !arg[0]; ++arg); + arg += strlen(arg) + 1; + len = data_len - (arg - args); + if (len <= 1) + goto done; + assert((fake_stdin = fmemopen(arg, len - 1, "r"))); + stdin = fake_stdin; + } + wg_main(argc, argv); +done: + for (size_t i = 0; i < argc; ++i) + free(argv[i]); + free(args); + if (fake_stdin) + fclose(fake_stdin); + return 0; +} diff --git a/src/fuzz/stringlist.c b/src/fuzz/stringlist.c index 85f7330..9823aa0 100644 --- a/src/fuzz/stringlist.c +++ b/src/fuzz/stringlist.c @@ -4,9 +4,9 @@ */ #define RUNSTATEDIR "/var/empty" +#include "../curve25519.c" #undef __linux__ #include "../ipc.c" -#include "../curve25519.c" #include "../encoding.c" #include diff --git a/src/fuzz/uapi.c b/src/fuzz/uapi.c index a387125..46576bd 100644 --- a/src/fuzz/uapi.c +++ b/src/fuzz/uapi.c @@ -8,9 +8,9 @@ static FILE *hacked_userspace_interface_file(const char *iface); #define stat(a, b) ({ return hacked_userspace_interface_file(iface); 0; }) #define RUNSTATEDIR "/var/empty" +#include "../curve25519.c" #undef __linux__ #include "../ipc.c" -#include "../curve25519.c" #include "../encoding.c" #include -- cgit v1.2.3-59-g8ed1b