aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/fuzz/cmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fuzz/cmd.c')
-rw-r--r--src/fuzz/cmd.c72
1 files changed, 72 insertions, 0 deletions
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 <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;
+}