]> git.puffer.fish Git - matthieu/frr.git/commitdiff
vrrpd: add afl & libfuzzer support
authorQuentin Young <qlyoung@cumulusnetworks.com>
Wed, 22 Jan 2020 19:58:14 +0000 (14:58 -0500)
committerQuentin Young <qlyoung@nvidia.com>
Mon, 15 Nov 2021 19:59:45 +0000 (14:59 -0500)
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
configure.ac
vrrpd/subdir.am
vrrpd/vrrp.c
vrrpd/vrrp.h
vrrpd/vrrp_main.c
vrrpd/vrrp_packet.c
vrrpd/vrrp_zebra.c

index ea0c30a0c0aab7659d4faa3d88a533bee526988a..f996e2a60bf0a20b6e8273c630f09d4d37c3b74c 100644 (file)
@@ -406,6 +406,7 @@ if test "$enable_libfuzzer" = "yes"; then
     BGPD_SAN_FLAGS="-fsanitize=fuzzer"
     ZEBRA_SAN_FLAGS="-fsanitize=fuzzer"
     OSPFD_SAN_FLAGS="-fsanitize=fuzzer"
+    VRRPD_SAN_FLAGS="-fsanitize=fuzzer"
     AC_DEFINE([FUZZING_LIBFUZZER], [1], [Compiling and linking with libFuzzer])
   ])
 fi
@@ -413,6 +414,7 @@ AC_SUBST([SAN_FLAGS])
 AC_SUBST([BGPD_SAN_FLAGS])
 AC_SUBST([ZEBRA_SAN_FLAGS])
 AC_SUBST([OSPFD_SAN_FLAGS])
+AC_SUBST([VRRPD_SAN_FLAGS])
 
 dnl frr-format.so
 if test "$with_frr_format" != "no" -a "$with_frr_format" != "yes" -a -n "$with_frr_format"; then
index 02e0497eef13869602e48b98003ad0de2535b261..80d8a61f6ef9dec3f088dc724f70027c0f41076e 100644 (file)
@@ -36,6 +36,7 @@ clippy_scan += \
        # end
 
 vrrpd_vrrpd_LDADD = lib/libfrr.la @LIBCAP@
+vrrpd_vrrpd_LDFLAGS = $(AM_CFLAGS) $(VRRPD_SAN_FLAGS)
 nodist_vrrpd_vrrpd_SOURCES = \
        yang/frr-vrrpd.yang.c \
        # end
index 775611b3e3e225927281b5c22910cda36216dfe4..e7a123078850687ff8b107a4480ac47f66d3eafb 100644 (file)
@@ -983,7 +983,10 @@ static int vrrp_recv_advertisement(struct vrrp_router *r, struct ipaddr *src,
 /*
  * Read and process next IPvX datagram.
  */
-static int vrrp_read(struct thread *thread)
+#ifndef FUZZING
+static
+#endif
+int vrrp_read(struct thread *thread)
 {
        struct vrrp_router *r = thread->arg;
 
@@ -1008,6 +1011,7 @@ static int vrrp_read(struct thread *thread)
        m.msg_control = control;
        m.msg_controllen = sizeof(control);
 
+#ifndef FUZZING
        nbytes = recvmsg(r->sock_rx, &m, MSG_DONTWAIT);
 
        if ((nbytes < 0 && ERRNO_IO_RETRY(errno))) {
@@ -1018,6 +1022,10 @@ static int vrrp_read(struct thread *thread)
                resched = false;
                goto done;
        }
+#else
+       nbytes = r->fuzzing_input_size;
+       m.msg_name = &r->fuzzing_sa;
+#endif
 
        if (DEBUG_MODE_CHECK(&vrrp_dbg_pkt, DEBUG_MODE_ALL)) {
                DEBUGD(&vrrp_dbg_pkt,
@@ -1043,8 +1051,10 @@ static int vrrp_read(struct thread *thread)
 done:
        memset(r->ibuf, 0x00, sizeof(r->ibuf));
 
+#ifndef FUZZING
        if (resched)
                thread_add_read(master, vrrp_read, r, r->sock_rx, &r->t_read);
+#endif
 
        return 0;
 }
index c181c2159bf10aaa032d9095d230b6d1294981f7..63257612628b7255fbfd00e69ba6b6b429b841d5 100644 (file)
@@ -111,6 +111,10 @@ struct vrrp_router {
        struct ipaddr src;
 
        /* Socket read buffer */
+#ifdef FUZZING
+       size_t fuzzing_input_size;
+       struct sockaddr_in fuzzing_sa;
+#endif
        uint8_t ibuf[IP_MAXPACKET];
 
        /*
@@ -464,6 +468,10 @@ int vrrp_del_ipv4(struct vrrp_vrouter *vr, struct in_addr v4);
  */
 int vrrp_del_ipv6(struct vrrp_vrouter *vr, struct in6_addr v6);
 
+#ifdef FUZZING
+int vrrp_read(struct thread *thread);
+#endif
+
 /* State machine ----------------------------------------------------------- */
 
 #define VRRP_STATE_INITIALIZE 0
index 59769788e7e5ec6fcb5f313deec9e37bd7efce3d..b51b0d1c8489aa589c9c9587d08ffc589159bd8d 100644 (file)
@@ -130,8 +130,102 @@ FRR_DAEMON_INFO(vrrpd, VRRP, .vty_port = VRRP_VTY_PORT,
                .n_yang_modules = array_size(vrrp_yang_modules),
 );
 
+#ifdef FUZZING
+
+int LLVMFuzzerTestOneInput(uint8_t *data, size_t size);
+
+static bool FuzzingInit(void)
+{
+       const char *name[] = { "vrrpd" };
+
+       frr_preinit(&vrrpd_di, 1, (char **) name);
+
+       master = frr_init();
+
+       access_list_init();
+       vrrp_debug_init();
+       vrrp_zebra_init();
+       vrrp_vty_init();
+       vrrp_init();
+
+
+       return true;
+}
+
+static struct vrrp_vrouter *FuzzingCreateVr(void)
+{
+       struct interface *ifp;
+       struct prefix p;
+
+       ifp = if_create_ifindex(69, 0);
+       ifp->mtu = 68;
+       str2prefix("11.0.2.1/24", &p);
+       connected_add_by_prefix(ifp, &p, NULL);
+
+       struct vrrp_vrouter *vr = vrrp_vrouter_create(ifp, 10, 3);
+       vr->v4->fsm.state = VRRP_STATE_MASTER;
+       vr->v6->fsm.state = VRRP_STATE_MASTER;
+
+       vrrp_debug_set(NULL, 0, CONFIG_NODE, 1, 1, 1, 1, 1, 1, 1, 1);
+
+       return vr;
+}
+
+bool FuzzingInitialized;
+struct vrrp_vrouter *FuzzingVr;
+
+int LLVMFuzzerTestOneInput(uint8_t *data, size_t size)
+{
+       if (!FuzzingInitialized) {
+               FuzzingInit();
+               FuzzingInitialized = true;
+               FuzzingVr = FuzzingCreateVr();
+       }
+
+       struct thread t;
+       struct vrrp_vrouter *vr;
+
+#ifdef FUZZING_LIBFUZZER
+       vr = FuzzingVr;
+#else
+       vr = FuzzingVr;
+#endif
+       
+       /* set input size */
+       vr->v4->fuzzing_input_size = size;
+       /* some info to fake msghdr with */
+       memcpy(vr->v4->ibuf, data, MIN(size, sizeof(vr->v4->ibuf)));
+       vr->v4->fuzzing_sa.sin_family = AF_INET;
+       inet_pton(AF_INET, "11.0.2.3", &vr->v4->fuzzing_sa.sin_addr);
+
+       t.arg = vr->v4;
+
+       vrrp_read(&t);
+
+       return 0;
+}
+
+#endif
+
+#ifndef FUZZING_LIBFUZZER
 int main(int argc, char **argv, char **envp)
 {
+#ifdef FUZZING
+       FuzzingInit();
+       FuzzingInitialized = true;
+
+#ifdef __AFL_HAVE_MANUAL_CONTROL
+       __AFL_INIT();
+#endif /* AFL_HAVE_MANUAL_CONTROL */
+
+       uint8_t *input;
+       int r = frrfuzz_read_input(&input);
+
+       if (r < 0)
+               return 0;
+
+       return LLVMFuzzerTestOneInput(input, r);
+#endif
        frr_preinit(&vrrpd_di, argc, argv);
        frr_opt_add("", longopts, "");
 
@@ -169,3 +263,4 @@ int main(int argc, char **argv, char **envp)
        /* Not reached. */
        return 0;
 }
+#endif
index 991c030196e975e46469dfd691dbd7ae2fba7e3f..8456a1dc955adfa71b290a2b16b38b6ed6032f16 100644 (file)
@@ -291,9 +291,11 @@ ssize_t vrrp_pkt_parse_datagram(int family, int version, struct msghdr *m,
        /* Checksum check */
        uint16_t chksum = vrrp_pkt_checksum(*pkt, pktsize, src);
 
+#ifndef FUZZING
        VRRP_PKT_VCHECK((*pkt)->hdr.chksum == chksum,
                        "Bad VRRP checksum %hx; should be %hx",
                        (*pkt)->hdr.chksum, chksum);
+#endif
 
        /* Type check */
        VRRP_PKT_VCHECK(((*pkt)->hdr.vertype & 0x0F) == 1, "Bad type %u",
index d7d37f1f339bb373a1608d2c25c3156967d38efa..b585287c81891ffa42a81454e00faf1416d3cf35 100644 (file)
@@ -181,6 +181,9 @@ void vrrp_zebra_radv_set(struct vrrp_router *r, bool enable)
 
 void vrrp_zclient_send_interface_protodown(struct interface *ifp, bool down)
 {
+       if (!ifp)
+               return 0;
+
        DEBUGD(&vrrp_dbg_zebra,
               VRRP_LOGPFX "Requesting Zebra to set %s protodown %s", ifp->name,
               down ? "on" : "off");