]> git.puffer.fish Git - matthieu/frr.git/commitdiff
pimd: add libFuzzer support
authorQuentin Young <qlyoung@cumulusnetworks.com>
Thu, 20 Feb 2020 18:37:22 +0000 (13:37 -0500)
committerQuentin Young <qlyoung@nvidia.com>
Mon, 15 Nov 2021 20:01:02 +0000 (15:01 -0500)
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
configure.ac
pimd/pim_main.c
pimd/subdir.am

index f996e2a60bf0a20b6e8273c630f09d4d37c3b74c..cd840847d0a28a70d2bcaca372ed1523d785eea3 100644 (file)
@@ -407,6 +407,7 @@ if test "$enable_libfuzzer" = "yes"; then
     ZEBRA_SAN_FLAGS="-fsanitize=fuzzer"
     OSPFD_SAN_FLAGS="-fsanitize=fuzzer"
     VRRPD_SAN_FLAGS="-fsanitize=fuzzer"
+    PIMD_SAN_FLAGS="-fsanitize=fuzzer"
     AC_DEFINE([FUZZING_LIBFUZZER], [1], [Compiling and linking with libFuzzer])
   ])
 fi
@@ -415,6 +416,7 @@ AC_SUBST([BGPD_SAN_FLAGS])
 AC_SUBST([ZEBRA_SAN_FLAGS])
 AC_SUBST([OSPFD_SAN_FLAGS])
 AC_SUBST([VRRPD_SAN_FLAGS])
+AC_SUBST([PIMD_SAN_FLAGS])
 
 dnl frr-format.so
 if test "$with_frr_format" != "no" -a "$with_frr_format" != "yes" -a -n "$with_frr_format"; then
index c9ae27b53900280393ba346415a8bbd87c3a2563..9a3463b03027bc7d6b8fdcb2e2e5962cbe460b25 100644 (file)
@@ -102,93 +102,133 @@ FRR_DAEMON_INFO(pimd, PIM, .vty_port = PIMD_VTY_PORT,
                .n_yang_modules = array_size(pimd_yang_modules),
 );
 
+#ifdef FUZZING
 
-int main(int argc, char **argv, char **envp)
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
+
+static struct interface *FuzzingIfp;
+static struct in_addr FuzzingSrc = { .s_addr = 0x0900001b };
+
+static bool FuzzingInit(void)
 {
-       frr_preinit(&pimd_di, argc, argv);
+       vrf_configure_backend(VRF_BACKEND_VRF_LITE);
 
-#ifdef FUZZING
+       const char *name[] = {"pimd"};
 
-       /* INIT */
-       {
-               pim_router_init();
-
-               /*
-                * Initializations
-                */
-               pim_error_init();
-               pim_vrf_init();
-               access_list_init();
-               prefix_list_init();
-               prefix_list_add_hook(pim_prefix_list_update);
-               prefix_list_delete_hook(pim_prefix_list_update);
-
-               pim_route_map_init();
-               pim_init();
-
-
-               /*
-                * Initialize zclient "update" and "lookup" sockets
-                */
-               if_zapi_callbacks(pim_ifp_create, pim_ifp_up,
-                                 pim_ifp_down, pim_ifp_destroy);
-               pim_zebra_init();
-               pim_bfd_init();
-               pim_mlag_init();
-       }
+       frr_preinit(&pimd_di, 1, (char **)name);
+       pim_router_init();
+
+       /*
+        * Initializations
+        */
+       pim_error_init();
+       pim_vrf_init();
+       access_list_init();
+       prefix_list_init();
+       prefix_list_add_hook(pim_prefix_list_update);
+       prefix_list_delete_hook(pim_prefix_list_update);
+
+       pim_route_map_init();
+       pim_init();
+
+       /*
+        * Initialize zclient "update" and "lookup" sockets
+        */
+       if_zapi_callbacks(pim_ifp_create, pim_ifp_up,
+                         pim_ifp_down, pim_ifp_destroy);
+       pim_zebra_init();
+       pim_bfd_init();
+       pim_mlag_init();
+
+       /* Create some fake interface */
 
-#define KERNEL_IFACE 0
-#ifdef KERNEL_IFACE
        /* Source address stuff */
        struct prefix p;
        str2prefix("27.0.0.9/24", &p);
-       struct in_addr src = { .s_addr = 0x0900001b };
 
        /* Create system interface */
-       struct interface *ifp = if_create_name("fuzziface", VRF_DEFAULT);
-       if_set_index(ifp, 69);
+       FuzzingIfp = if_create_name("fuzziface", VRF_DEFAULT);
+       if_set_index(FuzzingIfp, 69);
+
+       connected_add_by_prefix(FuzzingIfp, &p, NULL);
 
-       struct connected *c = connected_add_by_prefix(ifp, &p, NULL);
+       return true;
+}
 
+static struct pim_instance *FuzzingCreatePimInstance(void)
+{
        /* Create pim stuff */
-       struct pim_interface *pim_ifp = pim_if_new(ifp, true, true, false, false);
-       pim_igmp_sock_add(pim_ifp->igmp_socket_list, src, ifp, false);
+       fprintf(stderr, ">>>>>>>>> %p\n", FuzzingIfp);
+       struct pim_interface *pim_ifp = pim_if_new(FuzzingIfp, true, true, false, false);
+       pim_igmp_sock_add(pim_ifp->igmp_socket_list, FuzzingSrc, FuzzingIfp, false);
 
        struct pim_instance *pim = vrf_lookup_by_id(VRF_DEFAULT)->info;
        pim_if_create_pimreg(pim);
        pim_hello_options ho = 0;
-       pim_neighbor_add(ifp, src, ho, 210, 1, 1, 30, 20, NULL, 0);
+       pim_neighbor_add(FuzzingIfp, FuzzingSrc, ho, 210, 1, 1, 30, 20, NULL, 0);
 
-#ifdef __AFL_HAVE_MANUAL_CONTROL
-       __AFL_INIT();
-#endif /* __AFL_HAVE_MANUAL_CONTROL */
+       return pim;
+}
 
-       uint8_t *input;
-       int len = frrfuzz_read_input(&input);
+static bool FuzzingInitialized;
 
-       int result = pim_mroute_msg(pim, (const char *) input, len, 69);
+static struct pim_instance *FuzzingPim;
 
-#else /* KERNEL_IFACE */
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+       if (!FuzzingInitialized) {
+               FuzzingInit();
+               FuzzingInitialized = true;
+               FuzzingPim = FuzzingCreatePimInstance();
+       }
 
-       struct interface *ifp = if_create_name("fuzziface", VRF_DEFAULT);
-       pim_if_new(ifp, true, true, false, false);
-       struct in_addr src = { .s_addr = 0x0900001b };
-       pim_hello_options ho = 0;
-       pim_neighbor_add(ifp, src, ho, 210, 1, 1, 30, 20, NULL, 0);
+       struct pim_instance *pim;
+#ifdef FUZZING_LIBFUZZER
+       pim = FuzzingPim;
+#else
+       pim = FuzzingPim;
+#endif
+
+       int result;
+
+       uint8_t *input = malloc(size);
+       memcpy(input, data, size);
+
+#ifdef KERNEL_IFACE
+       result = pim_mroute_msg(pim, (const char *) input, size, 69);
+#else
+       result = pim_pim_packet(FuzzingIfp, input, size);
+#endif /* KERNEL_IFACE */
+
+       free(input);
+
+       return result;
+}
+#endif /* FUZZING */
 
+#ifndef FUZZING_LIBFUZZER
+
+int main(int argc, char **argv, char **envp)
+{
+       frr_preinit(&pimd_di, argc, argv);
+
+#ifdef FUZZING
+       FuzzingInit();
+       FuzzingInitialized = true;
+       FuzzingPim = FuzzingCreatePimInstance();
 
 #ifdef __AFL_HAVE_MANUAL_CONTROL
        __AFL_INIT();
 #endif /* __AFL_HAVE_MANUAL_CONTROL */
 
-       uint8_t *input;
-       int len = frrfuzz_read_input(&input);
+       uint8_t *input = NULL;
+       int r = frrfuzz_read_input(&input);
 
-       int result = pim_pim_packet(ifp, input, len);
+       int ret = LLVMFuzzerTestOneInput(input, r);
 
-#endif /* KERNEL_IFACE */
+       free(input);
 
-       return result;
+       return ret;
 #endif /* FUZZING */
 
        frr_opt_add("", longopts, "");
@@ -274,3 +314,4 @@ int main(int argc, char **argv, char **envp)
        /* never reached */
        return 0;
 }
+#endif /* FUZZING_LIBFUZZER */
index f8bc0ff081669d39238e7360a60331d956e94fee..487cdd45049219ac3609a1434a1c5a8dcbd7f077 100644 (file)
@@ -135,6 +135,7 @@ clippy_scan += \
        # end
 
 pimd_pimd_LDADD = lib/libfrr.la $(LIBCAP)
+pimd_pimd_LDFLAGS = $(AM_LDFLAGS) $(PIMD_SAN_FLAGS)
 
 pimd_test_igmpv3_join_LDADD = lib/libfrr.la
 pimd_test_igmpv3_join_SOURCES = pimd/test_igmpv3_join.c