From 92f98484d7f2f9086c36f476a1cb8824ef826a06 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Wed, 18 Dec 2024 16:04:06 +0100 Subject: [PATCH] bgpd: fix memory leak when updating peer up loc rib events The following memory leak can be observed when turning off and on the BGP vrf interface. > ==706056==ERROR: LeakSanitizer: detected memory leaks > > Direct leak of 78 byte(s) in 1 object(s) allocated from: > #0 0x7fbf5f6b4887 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145 > #1 0x7fbf5f0771f8 in qmalloc lib/memory.c:101 > #2 0x7fbf5bdde610 in bmp_bgp_peer_vrf bgpd/bgp_bmp.c:2042 > #3 0x7fbf5bdde8aa in bmp_bgp_update_vrf_status bgpd/bgp_bmp.c:2079 > #4 0x7fbf5bdeaa1c in bmp_vrf_itf_state_changed bgpd/bgp_bmp.c:3204 > #5 0x562740f0d83f in hook_call_bgp_vrf_status_changed bgpd/bgp_zebra.c:64 > #6 0x562740f0ee28 in bgp_ifp_up bgpd/bgp_zebra.c:234 > #7 0x7fbf5f01c193 in hook_call_if_up lib/if.c:57 > #8 0x7fbf5f01d09a in if_up_via_zapi lib/if.c:203 > #9 0x7fbf5f1d6f54 in zclient_interface_up lib/zclient.c:2671 > #10 0x7fbf5f1e3e5a in zclient_read lib/zclient.c:4624 > #11 0x7fbf5f18078d in event_call lib/event.c:1996 > #12 0x7fbf5f048933 in frr_run lib/libfrr.c:1232 > #13 0x562740c0cae1 in main bgpd/bgp_main.c:557 > #14 0x7fbf5ea29d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 > > Direct leak of 78 byte(s) in 1 object(s) allocated from: > #0 0x7fbf5f6b4887 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145 > #1 0x7fbf5f0771f8 in qmalloc lib/memory.c:101 > #2 0x7fbf5bdde610 in bmp_bgp_peer_vrf bgpd/bgp_bmp.c:2042 > #3 0x7fbf5bdde8aa in bmp_bgp_update_vrf_status bgpd/bgp_bmp.c:2079 > #4 0x7fbf5bdd4839 in bmp_send_peerup_vrf bgpd/bgp_bmp.c:627 > #5 0x7fbf5bddb0d3 in bmp_wrfill bgpd/bgp_bmp.c:1590 > #6 0x7fbf5f10841f in pullwr_run lib/pullwr.c:197 > #7 0x7fbf5f18078d in event_call lib/event.c:1996 > #8 0x7fbf5f048933 in frr_run lib/libfrr.c:1232 > #9 0x562740c0cae1 in main bgpd/bgp_main.c:557 > #10 0x7fbf5ea29d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 Fix this by freeing the previous open_tx and open_rx contexts before setting up the new one. Also at deletion of peer, free the open_rx context. Signed-off-by: Philippe Guibert --- bgpd/bgp_bmp.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c index 0d3f196f96a8..f71e13c522f0 100644 --- a/bgpd/bgp_bmp.c +++ b/bgpd/bgp_bmp.c @@ -2034,10 +2034,14 @@ static void bmp_bgp_peer_vrf(struct bmp_bgp_peer *bbpeer, struct bgp *bgp) size_t open_len = stream_get_endp(s); bbpeer->open_rx_len = open_len; + if (bbpeer->open_rx) + XFREE(MTYPE_BMP_OPEN, bbpeer->open_rx); bbpeer->open_rx = XMALLOC(MTYPE_BMP_OPEN, open_len); memcpy(bbpeer->open_rx, s->data, open_len); bbpeer->open_tx_len = open_len; + if (bbpeer->open_tx) + XFREE(MTYPE_BMP_OPEN, bbpeer->open_tx); bbpeer->open_tx = XMALLOC(MTYPE_BMP_OPEN, open_len); memcpy(bbpeer->open_tx, s->data, open_len); @@ -2079,6 +2083,7 @@ bool bmp_bgp_update_vrf_status(struct bmp_bgp *bmpbgp, enum bmp_vrf_state force) } else { bbpeer = bmp_bgp_peer_find(peer->qobj_node.nid); if (bbpeer) { + XFREE(MTYPE_BMP_OPEN, bbpeer->open_tx); XFREE(MTYPE_BMP_OPEN, bbpeer->open_rx); bmp_peerh_del(&bmp_peerh, bbpeer); XFREE(MTYPE_BMP_PEER, bbpeer);