]> git.puffer.fish Git - mirror/frr.git/commitdiff
configure, zebra: Add some debug code to allow for fuzzing 1387/head
authorDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 2 Nov 2017 14:56:03 +0000 (10:56 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 9 Nov 2017 18:16:45 +0000 (13:16 -0500)
1) Write zserv api commands( one of each type ) to the side.  This will allow
us to use them as input for a fuzzer.

2) Add -c <file to pass to zapi read process> into zebra as a run-time
option of we've turned on fuzzing.

While in and of itself these are not terribly useful( you still need
an external fuzzer ), they provide an infrastructure to allow
tools like afl to test the zapi.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
configure.ac
doc/install.texi
zebra/main.c
zebra/zserv.c
zebra/zserv.h

index cae50611225f1c9afb37a0975242af54556e95f3..49bc652329d3ce5273d746489532f2df04e7db9c 100755 (executable)
@@ -381,6 +381,8 @@ AC_ARG_ENABLE(cumulus,
   AS_HELP_STRING([--enable-cumulus], [enable Cumulus Switch Special Extensions]))
 AC_ARG_ENABLE(datacenter,
   AS_HELP_STRING([--enable-datacenter], [enable Compilation for Data Center Extensions]))
+AC_ARG_ENABLE(fuzzing,
+  AS_HELP_STRING([--enable-fuzzing], [enable ability to fuzz various parts of FRR]))
 AC_ARG_ENABLE(rr-semantics,
   AS_HELP_STRING([--disable-rr-semantics], [disable the v6 Route Replace semantics]))
 AC_ARG_ENABLE([protobuf],
@@ -432,6 +434,10 @@ else
   DFLT_NAME="traditional"
 fi
 
+if test "${enable_fuzzing}" = "yes" ; then
+  AC_DEFINE(HANDLE_ZAPI_FUZZING,,Compile extensions to use with a fuzzer)
+fi
+
 if test "${enable_cumulus}" = "yes" ; then
   AC_DEFINE(HAVE_CUMULUS,,Compile Special Cumulus Code in)
 fi
index 1930af95e680b5c27998c81944ecf3d2a5571fce..19d9614420f8788377855898eeaf5445fe5028b7 100644 (file)
@@ -101,6 +101,10 @@ needs libexecinfo, while on glibc support for this is part of libc itself.
 Turn on some options for compiling FRR within a development environment in
 mind.  Specifically turn on -g3 -O0 for compiling options and add inclusion
 of grammar sandbox.
+@item --enable-fuzzing
+Turn on some compile options to allow you to run fuzzing tools
+against the system.  This tools is intended as a developer
+only tool and should not be used for normal operations
 @end table
 
 You may specify any combination of the above options to the configure
index cf677a775350e7469759fec75cb44942f57fd7fc..36c931c4ee9b6ded7afbf86be069d0aa2cd43227 100644 (file)
@@ -201,6 +201,9 @@ int main(int argc, char **argv)
        char *lblmgr_path = NULL;
        struct sockaddr_storage dummy;
        socklen_t dummylen;
+#if defined(HANDLE_ZAPI_FUZZING)
+       char *fuzzing = NULL;
+#endif
 
        frr_preinit(&zebra_di, argc, argv);
 
@@ -208,6 +211,9 @@ int main(int argc, char **argv)
                "bakz:e:l:r"
 #ifdef HAVE_NETLINK
                "s:"
+#endif
+#if defined(HANDLE_ZAPI_FUZZING)
+               "c:"
 #endif
                ,
                longopts,
@@ -221,6 +227,9 @@ int main(int argc, char **argv)
 #ifdef HAVE_NETLINK
                "  -s, --nl-bufsize   Set netlink receive buffer size\n"
 #endif /* HAVE_NETLINK */
+#if defined(HANDLE_ZAPI_FUZZING)
+               "  -c <file>          Bypass normal startup use this file for tetsting of zapi"
+#endif
                );
 
        while (1) {
@@ -271,6 +280,11 @@ int main(int argc, char **argv)
                        nl_rcvbufsize = atoi(optarg);
                        break;
 #endif /* HAVE_NETLINK */
+#if defined(HANDLE_ZAPI_FUZZING)
+               case 'c':
+                       fuzzing = optarg;
+                       break;
+#endif
                default:
                        frr_help_exit(1);
                        break;
@@ -308,6 +322,13 @@ int main(int argc, char **argv)
         * routing socket. */
        zebra_ns_init();
 
+#if defined(HANDLE_ZAPI_FUZZING)
+       if (fuzzing) {
+               zserv_read_file(fuzzing);
+               exit(0);
+       }
+#endif
+
        /* Process the configuration file. Among other configuration
        *  directives we can meet those installing static routes. Such
        *  requests will not be executed immediately, but queued in
index cbd532339d1b9a1c9e3ced17638ec94ba6660c26..75ed4abe76a93e563194d0c80f656d09874e7d68 100644 (file)
@@ -2377,6 +2377,26 @@ static inline void zserv_handle_commands(struct zserv *client,
        }
 }
 
+#if defined(HANDLE_ZAPI_FUZZING)
+static void zserv_write_incoming(struct stream *orig, uint16_t command)
+{
+       char fname[MAXPATHLEN];
+       struct stream *copy;
+       int fd = -1;
+
+       copy = stream_dup(orig);
+       stream_set_getp(copy, 0);
+
+       zserv_privs.change(ZPRIVS_RAISE);
+       snprintf(fname, MAXPATHLEN, "%s/%u", DAEMON_VTY_DIR, command);
+       fd = open(fname, O_CREAT | O_WRONLY | O_EXCL, 0644);
+       stream_flush(copy, fd);
+       close(fd);
+       zserv_privs.change(ZPRIVS_LOWER);
+       stream_free(copy);
+}
+#endif
+
 /* Handler of zebra service request. */
 static int zebra_client_read(struct thread *thread)
 {
@@ -2387,7 +2407,11 @@ static int zebra_client_read(struct thread *thread)
        uint8_t marker, version;
        vrf_id_t vrf_id;
        struct zebra_vrf *zvrf;
+#if defined(HANDLE_ZAPI_FUZZING)
+       int packets = 1;
+#else
        int packets = zebrad.packets_to_process;
+#endif
 
        /* Get thread data.  Reset reading thread because I'm running. */
        sock = THREAD_FD(thread);
@@ -2477,6 +2501,9 @@ static int zebra_client_read(struct thread *thread)
                        }
                }
 
+#if defined(HANDLE_ZAPI_FUZZING)
+               zserv_write_incoming(client->ibuf, command);
+#endif
                length -= ZEBRA_HEADER_SIZE;
 
                /* Debug packet information. */
@@ -3023,6 +3050,26 @@ static struct cmd_node forwarding_node = {FORWARDING_NODE,
                                          "", /* This node has no interface. */
                                          1};
 
+#if defined(HANDLE_ZAPI_FUZZING)
+void zserv_read_file(char *input)
+{
+       int fd;
+       struct zserv *client = NULL;
+       struct thread t;
+
+       zebra_client_create(-1);
+       client = zebrad.client_list->head->data;
+       t.arg = client;
+
+       fd = open(input, O_RDONLY|O_NONBLOCK);
+       t.u.fd = fd;
+
+       zebra_client_read(&t);
+
+       close(fd);
+}
+#endif
+
 /* Initialisation of zebra and installation of commands. */
 void zebra_init(void)
 {
index 279b56ec3c4ad93e16e7886cf96b6df2e24611a0..60e055088ae7a5105012030b16db92c3c5c42563 100644 (file)
@@ -193,4 +193,8 @@ extern int zebra_server_send_message(struct zserv *client);
 
 extern struct zserv *zebra_find_client(u_char proto);
 
+#if defined(HANDLE_ZAPI_FUZZING)
+extern void zserv_read_file(char *input);
+#endif
+
 #endif /* _ZEBRA_ZEBRA_H */