]> git.ipfire.org Git - thirdparty/wireguard-tools.git/commitdiff
fuzz: add generic command argument fuzzer
authorJason A. Donenfeld <Jason@zx2c4.com>
Sat, 4 Jan 2020 14:34:28 +0000 (15:34 +0100)
committerJason A. Donenfeld <Jason@zx2c4.com>
Sat, 4 Jan 2020 15:47:28 +0000 (10:47 -0500)
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
src/fuzz/.gitignore
src/fuzz/Makefile
src/fuzz/cmd.c [new file with mode: 0644]
src/fuzz/stringlist.c
src/fuzz/uapi.c

index 988712e33ce5f223842256b9f0ad9409e8142c76..3b69fdaa727c817ea3f60c6178de7d38a4678ce6 100644 (file)
@@ -1,2 +1,4 @@
 config
 uapi
+stringlist
+cmd
index 3fb2970019019ec183053fd2a1cccab9ba304695..cb9db3bfcbc635e5f077ff89d0c9d32f87ae7126 100644 (file)
@@ -2,10 +2,10 @@
 #
 # Copyright (C) 2018-2020 Jason A. Donenfeld <Jason@zx2c4.com>. 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 (file)
index 0000000..8d75eb7
--- /dev/null
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+
+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;
+}
index 85f73300562f298b954514894282b7b0f2e0b3d9..9823aa00200c21cbbc698d81910034823d3ca888 100644 (file)
@@ -4,9 +4,9 @@
  */
 
 #define RUNSTATEDIR "/var/empty"
+#include "../curve25519.c"
 #undef __linux__
 #include "../ipc.c"
-#include "../curve25519.c"
 #include "../encoding.c"
 
 #include <stdint.h>
index a387125e4bc0219e0253e102ce1349046e8de7ac..46576bddfffa6b34599bc6d3c0d687ac9c4381eb 100644 (file)
@@ -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 <stdint.h>