]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: handle gr weirdness under libFuzzer
authorQuentin Young <qlyoung@cumulusnetworks.com>
Wed, 19 Feb 2020 21:52:00 +0000 (16:52 -0500)
committerQuentin Young <qlyoung@nvidia.com>
Mon, 15 Nov 2021 19:59:46 +0000 (14:59 -0500)
Two workarounds here. The #ifndef around assert(0) is to get around a
bug, in which a client that connects, announces GR capability,
disconnects, reconnects then sends anything other than a ZAPI hello will
hit the assert. GR resync is done in zread_hello(), so if a reconnecting
client doesn't send a hello then GR will notice that it's received a
disonnect for the same client twice in a row and assert. This is a bug,
GR should be able to handle that.

The rest of the code works around GR having a timer-based memory free.
Since we've disabled all thread.h code to increase determinism and avoid
mutex locks and other weirdness, clients repeatedly announcing GR
capability messages will result in a soft memleak.

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
zebra/zebra_gr.c

index 5373f27882956353dd4253b157212c8666772c0d..935e4d80ba10c4c2a0fe21bc56ca25c5f808ded0 100644 (file)
@@ -157,12 +157,19 @@ int32_t zebra_gr_client_disconnect(struct zserv *client)
        if (stale_client) {
                LOG_GR("%s: Stale client %s exist, we should not be here!",
                       __func__, zebra_route_string(client->proto));
+#ifndef FUZZING
                assert(0);
+#endif
        }
 
        client->restart_time = monotime(&tv);
 
        /* For all the GR instance start the stale removal timer. */
+#ifdef FUZZING
+       struct client_gr_info dupinfo = {};
+#endif
+
+       /* For all the GR instance start the starle removal timer. */
        TAILQ_FOREACH (info, &client->gr_info_queue, gr_info) {
                if (ZEBRA_CLIENT_GR_ENABLED(info->capabilities)
                    && (info->t_stale_removal == NULL)) {
@@ -177,10 +184,22 @@ int32_t zebra_gr_client_disconnect(struct zserv *client)
                        LOG_GR("%s: Client %s Stale timer update to %d",
                               __func__, zebra_route_string(client->proto),
                               info->stale_removal_time);
+
+                       dupinfo = *info;
+#ifdef FUZZING
+                       // yeah, that thread will never execute...clean it up now
+                       struct thread t = {};
+                       t.arg = info;
+                       info->t_stale_removal = &t;
+                       zebra_gr_route_stale_delete_timer_expiry(&t);
+                       info = &dupinfo;
+#endif
                }
        }
 
+#ifndef FUZZING
        listnode_add(zrouter.stale_client_list, client);
+#endif
 
        return 0;
 }