From 10e16a8c347c1af35b6e10bee38a640bea9634fe Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Fri, 3 Jan 2020 00:32:37 -0500 Subject: [PATCH] zebra: add fuzzing shim Signed-off-by: Quentin Young --- zebra/main.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++ zebra/zapi_msg.c | 1 - zebra/zserv.c | 4 ++- zebra/zserv.h | 4 +++ 4 files changed, 80 insertions(+), 2 deletions(-) diff --git a/zebra/main.c b/zebra/main.c index 038022ceb2..f7a017056f 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -35,6 +35,8 @@ #include "libfrr.h" #include "routemap.h" #include "routing_nb.h" +#include "fuzz.h" +#include "frr_pthread.h" #include "zebra/zebra_router.h" #include "zebra/zebra_errors.h" @@ -59,6 +61,7 @@ #include "zebra/zebra_srte.h" #include "zebra/zebra_srv6.h" #include "zebra/zebra_srv6_vty.h" +#include "zebra/zapi_msg.h" #define ZEBRA_PTM_SUPPORT @@ -287,16 +290,65 @@ int main(int argc, char **argv) bool asic_offload = false; bool notify_on_ack = true; +#if defined(HANDLE_NETLINK_FUZZING) + char *netlink_fuzzing = NULL; +#endif /* HANDLE_NETLINK_FUZZING */ + graceful_restart = 0; vrf_configure_backend(VRF_BACKEND_VRF_LITE); frr_preinit(&zebra_di, argc, argv); +#ifdef FUZZING + zrouter.master = frr_init_fast(); + + /* Zebra related initialize. */ + zebra_router_init(); + zserv_init(); + rib_init(); + zebra_if_init(); + zebra_debug_init(); + router_id_cmd_init(); + zebra_ns_init((const char *)vrf_default_name_configured); + zebra_vty_init(); + access_list_init(); + prefix_list_init(); + zebra_mpls_init(); + zebra_mpls_vty_init(); + zebra_pw_vty_init(); + zebra_pbr_init(); + zrouter.startup_time = monotime(NULL); + label_manager_init(); + zebra_rnh_init(); + zebra_evpn_init(); + zebra_error_init(); + frr_pthread_init(); + + struct zserv *zc = zserv_client_create(69); + +#ifdef __AFL_HAVE_MANUAL_CONTROL + __AFL_INIT(); +#endif /* __AFL_HAVE_MANUAL_CONTROL */ + + uint8_t *input; + int r = frrfuzz_read_input(&input); + + struct stream *s = stream_new(r + 1); + stream_put(s, input, r); + + zserv_handle_commands(zc, s); + + exit(0); +#endif /* FUZZING */ + frr_opt_add( "baz:e:o:rK:" #ifdef HAVE_NETLINK "s:n" #endif +#if defined(HANDLE_NETLINK_FUZZING) + "w:" +#endif /* HANDLE_NETLINK_FUZZING */ , longopts, " -b, --batch Runs in batch mode\n" @@ -312,6 +364,9 @@ int main(int argc, char **argv) " -s, --nl-bufsize Set netlink receive buffer size\n" " --v6-rr-semantics Use v6 RR semantics\n" #endif /* HAVE_NETLINK */ +#if defined(HANDLE_NETLINK_FUZZING) + " -w Bypass normal startup and use this file for testing of netlink input\n" +#endif /* HANDLE_NETLINK_FUZZING */ ); while (1) { @@ -380,6 +435,16 @@ int main(int argc, char **argv) asic_offload = true; break; #endif /* HAVE_NETLINK */ +#if defined(HANDLE_NETLINK_FUZZING) + case 'w': + netlink_fuzzing = optarg; + /* This ensures we are aren't writing any of the + * startup netlink messages that happen when we + * just want to read. + */ + netlink_read = true; + break; +#endif /* HANDLE_NETLINK_FUZZING */ default: frr_help_exit(1); } @@ -467,6 +532,14 @@ int main(int argc, char **argv) /* Error init */ zebra_error_init(); +#if defined(HANDLE_NETLINK_FUZZING) + if (netlink_fuzzing) { + netlink_read_init(netlink_fuzzing); + exit(0); + } +#endif /* HANDLE_NETLINK_FUZZING */ + + frr_run(zrouter.master); /* Not reached... */ diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 85721d7d70..d1cd92eb07 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -3781,7 +3781,6 @@ void zserv_handle_commands(struct zserv *client, struct stream_fifo *fifo) zserv_log_message(NULL, msg, &hdr); hdr.length -= ZEBRA_HEADER_SIZE; - /* Before checking for a handler function, check for * special messages that are handled in another module; * we'll treat these as opaque. diff --git a/zebra/zserv.c b/zebra/zserv.c index abb9c5ca5d..3cc0f5b2b8 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -732,7 +732,7 @@ static int zserv_handle_client_fail(struct thread *thread) * sock * client's socket file descriptor */ -static struct zserv *zserv_client_create(int sock) +struct zserv *zserv_client_create(int sock) { struct zserv *client; size_t stream_size = @@ -785,7 +785,9 @@ static struct zserv *zserv_client_create(int sock) hook_call(zserv_client_connect, client); /* start pthread */ +#ifndef FUZZING frr_pthread_run(client->pthread, NULL); +#endif return client; } diff --git a/zebra/zserv.h b/zebra/zserv.h index 203670ac1d..d19f330dbb 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -391,6 +391,10 @@ extern void zread_client_capabilities(struct zserv *client, struct zmsghdr *hdr, struct stream *msg, struct zebra_vrf *zvrf); +#ifdef FUZZING +struct zserv *zserv_client_create(int sock); +#endif + #ifdef __cplusplus } #endif -- 2.39.5