]> git.puffer.fish Git - mirror/frr.git/commitdiff
nhrpd: cleans up shortcut cache entries on termination 16175/head
authorDave LeRoy <dleroy@labn.net>
Wed, 5 Jun 2024 17:22:57 +0000 (10:22 -0700)
committerMergify <37929162+mergify[bot]@users.noreply.github.com>
Wed, 5 Jun 2024 21:40:05 +0000 (21:40 +0000)
nhrp_shortcut_terminate() previously was just freeing the associated AFI shortcut
RIBs and not addressing existing shortcut cache entries. This cause a use after
free issue in vrf_terminate() later in the terminate sequence

NHRP: Received signal 7 at 1717516286 (si_addr 0x1955d, PC 0x7098786912c0); aborting...
NHRP: zlog_signal+0xf5                   709878ad1255     7fff3d992eb0 /usr/lib/frr/libfrr.so.0 (mapped at 0x709878a00000)
NHRP: core_handler+0xb5                  709878b0db85     7fff3d992ff0 /usr/lib/frr/libfrr.so.0 (mapped at 0x709878a00000)
NHRP: __sigaction+0x50                   709878642520     7fff3d993140 /lib/x86_64-linux-gnu/libc.so.6 (mapped at 0x709878600000)
NHRP:     ---- signal ----
NHRP: __lll_lock_wait_private+0x90       7098786912c0     7fff3d9936d8 /lib/x86_64-linux-gnu/libc.so.6 (mapped at 0x709878600000)
NHRP: pthread_mutex_lock+0x112           709878698002     7fff3d9936e0 /lib/x86_64-linux-gnu/libc.so.6 (mapped at 0x709878600000)
NHRP: _event_add_read_write+0x63         709878b1f423     7fff3d993700 /usr/lib/frr/libfrr.so.0 (mapped at 0x709878a00000)
NHRP: zclient_send_message+0xd4          709878b37614     7fff3d993770 /usr/lib/frr/libfrr.so.0 (mapped at 0x709878a00000)
NHRP: nhrp_route_announce+0x1ad          5ab34d63d39d     7fff3d993790 /usr/lib/frr/nhrpd (mapped at 0x5ab34d621000)
NHRP: nhrp_shortcut_cache_notify+0xd8     5ab34d63e758     7fff3d99d4e0 /usr/lib/frr/nhrpd (mapped at 0x5ab34d621000)
NHRP: nhrp_cache_free+0x165              5ab34d632f25     7fff3d99d510 /usr/lib/frr/nhrpd (mapped at 0x5ab34d621000)
NHRP: hash_iterate+0x4d                  709878ab949d     7fff3d99d540 /usr/lib/frr/libfrr.so.0 (mapped at 0x709878a00000)
NHRP: nhrp_cache_interface_del+0x37      5ab34d633eb7     7fff3d99d580 /usr/lib/frr/nhrpd (mapped at 0x5ab34d621000)
NHRP: nhrp_if_delete_hook+0x26           5ab34d6350d6     7fff3d99d5a0 /usr/lib/frr/nhrpd (mapped at 0x5ab34d621000)
NHRP: if_delete_retain+0x3d              709878abcd1d     7fff3d99d5c0 /usr/lib/frr/libfrr.so.0 (mapped at 0x709878a00000)
NHRP: if_delete+0x4c                     709878abd87c     7fff3d99d600 /usr/lib/frr/libfrr.so.0 (mapped at 0x709878a00000)
NHRP: if_terminate+0x53                  709878abda83     7fff3d99d630 /usr/lib/frr/libfrr.so.0 (mapped at 0x709878a00000)
NHRP: vrf_terminate_single+0x24          709878b23c74     7fff3d99d670 /usr/lib/frr/libfrr.so.0 (mapped at 0x709878a00000)
NHRP: nhrp_request_stop+0x34             5ab34d636844     7fff3d99d690 /usr/lib/frr/nhrpd (mapped at 0x5ab34d621000)
NHRP: frr_sigevent_process+0x53          709878b0df53     7fff3d99d6a0 /usr/lib/frr/libfrr.so.0 (mapped at 0x709878a00000)
NHRP: event_fetch+0x6c5                  709878b20405     7fff3d99d6c0 /usr/lib/frr/libfrr.so.0 (mapped at 0x709878a00000)
NHRP: frr_run+0xd3                       709878ac8163     7fff3d99d840 /usr/lib/frr/libfrr.so.0 (mapped at 0x709878a00000)
NHRP: main+0x195                         5ab34d631915     7fff3d99d960 /usr/lib/frr/nhrpd (mapped at 0x5ab34d621000)
NHRP: __libc_init_first+0x90             709878629d90     7fff3d99d980 /lib/x86_64-linux-gnu/libc.so.6 (mapped at 0x709878600000)
NHRP: __libc_start_main+0x80             709878629e40     7fff3d99da20 /lib/x86_64-linux-gnu/libc.so.6 (mapped at 0x709878600000)
NHRP: _start+0x25                        5ab34d631b65     7fff3d99da70 /usr/lib/frr/nhrpd (mapped at 0x5ab34d621000)

Signed-off-by: Dave LeRoy <dleroy@labn.net>
(cherry picked from commit 2b7e357cf902190aad544b4f7d46e9f229454346)

nhrpd/nhrp_main.c
nhrpd/nhrp_shortcut.c

index 5d492249d32c41942fcd2b9756d2f5270eeac684..adb8be36d303cfd0967c7a316c00d5752b36b82f 100644 (file)
@@ -83,13 +83,13 @@ static void nhrp_request_stop(void)
        debugf(NHRP_DEBUG_COMMON, "Exiting...");
        frr_early_fini();
 
-       vrf_terminate();
+       nhrp_shortcut_terminate();
        nhrp_nhs_terminate();
        nhrp_zebra_terminate();
        vici_terminate();
        evmgr_terminate();
+       vrf_terminate();
        nhrp_vc_terminate();
-       nhrp_shortcut_terminate();
 
        debugf(NHRP_DEBUG_COMMON, "Done.");
 
index 04dad2aea627701ad330294c412d82ee16e07722..e83ce7f58f472527feecae9f9f4d18bf3c0e2ed6 100644 (file)
@@ -19,7 +19,8 @@ DEFINE_MTYPE_STATIC(NHRPD, NHRP_SHORTCUT, "NHRP shortcut");
 static struct route_table *shortcut_rib[AFI_MAX];
 
 static void nhrp_shortcut_do_purge(struct event *t);
-static void nhrp_shortcut_delete(struct nhrp_shortcut *s);
+static void nhrp_shortcut_delete(struct nhrp_shortcut *s,
+                                void *arg __attribute__((__unused__)));
 static void nhrp_shortcut_send_resolution_req(struct nhrp_shortcut *s);
 
 static void nhrp_shortcut_check_use(struct nhrp_shortcut *s)
@@ -72,7 +73,7 @@ static void nhrp_shortcut_cache_notify(struct notifier_block *n,
                        s->route_installed = 0;
                }
                if (cmd == NOTIFY_CACHE_DELETE)
-                       nhrp_shortcut_delete(s);
+                       nhrp_shortcut_delete(s, NULL);
                break;
        }
 }
@@ -132,7 +133,8 @@ static void nhrp_shortcut_update_binding(struct nhrp_shortcut *s,
        }
 }
 
-static void nhrp_shortcut_delete(struct nhrp_shortcut *s)
+static void nhrp_shortcut_delete(struct nhrp_shortcut *s,
+                                void *arg __attribute__((__unused__)))
 {
        struct route_node *rn;
        afi_t afi = family2afi(PREFIX_FAMILY(s->p));
@@ -158,7 +160,7 @@ static void nhrp_shortcut_do_purge(struct event *t)
 {
        struct nhrp_shortcut *s = EVENT_ARG(t);
        s->t_timer = NULL;
-       nhrp_shortcut_delete(s);
+       nhrp_shortcut_delete(s, NULL);
 }
 
 static struct nhrp_shortcut *nhrp_shortcut_get(struct prefix *p)
@@ -469,6 +471,8 @@ void nhrp_shortcut_init(void)
 
 void nhrp_shortcut_terminate(void)
 {
+       nhrp_shortcut_foreach(AFI_IP, nhrp_shortcut_delete, NULL);
+       nhrp_shortcut_foreach(AFI_IP6, nhrp_shortcut_delete, NULL);
        route_table_finish(shortcut_rib[AFI_IP]);
        route_table_finish(shortcut_rib[AFI_IP6]);
 }