From 8e7044ba3b806d286ed964746f4e88004035be09 Mon Sep 17 00:00:00 2001 From: Keelan10 Date: Wed, 29 Nov 2023 15:49:58 +0400 Subject: [PATCH] bgpd: Free Memory for SRv6 Functions and Locator Chunks Implement proper memory cleanup for SRv6 functions and locator chunks to prevent potential memory leaks. The list callback deletion functions have been set. The ASan leak log for reference: ``` *********************************************************************************** Address Sanitizer Error detected in bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.asan.bgpd.4180 ================================================================= ==4180==ERROR: LeakSanitizer: detected memory leaks Direct leak of 544 byte(s) in 2 object(s) allocated from: #0 0x7f8d176a0d28 in __interceptor_calloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xded28) #1 0x7f8d1709f238 in qcalloc lib/memory.c:105 #2 0x55d5dba6ee75 in sid_register bgpd/bgp_mplsvpn.c:591 #3 0x55d5dba6ee75 in alloc_new_sid bgpd/bgp_mplsvpn.c:712 #4 0x55d5dba6f3ce in ensure_vrf_tovpn_sid_per_af bgpd/bgp_mplsvpn.c:758 #5 0x55d5dba6fb94 in ensure_vrf_tovpn_sid bgpd/bgp_mplsvpn.c:849 #6 0x55d5dba7f975 in vpn_leak_postchange bgpd/bgp_mplsvpn.h:299 #7 0x55d5dba7f975 in vpn_leak_postchange_all bgpd/bgp_mplsvpn.c:3704 #8 0x55d5dbbb6c66 in bgp_zebra_process_srv6_locator_chunk bgpd/bgp_zebra.c:3164 #9 0x7f8d1716f08a in zclient_read lib/zclient.c:4459 #10 0x7f8d1713f034 in event_call lib/event.c:1974 #11 0x7f8d1708242b in frr_run lib/libfrr.c:1214 #12 0x55d5db99d19d in main bgpd/bgp_main.c:510 #13 0x7f8d160c5c86 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21c86) Direct leak of 296 byte(s) in 1 object(s) allocated from: #0 0x7f8d176a0d28 in __interceptor_calloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xded28) #1 0x7f8d1709f238 in qcalloc lib/memory.c:105 #2 0x7f8d170b1d5f in srv6_locator_chunk_alloc lib/srv6.c:135 #3 0x55d5dbbb6a19 in bgp_zebra_process_srv6_locator_chunk bgpd/bgp_zebra.c:3144 #4 0x7f8d1716f08a in zclient_read lib/zclient.c:4459 #5 0x7f8d1713f034 in event_call lib/event.c:1974 #6 0x7f8d1708242b in frr_run lib/libfrr.c:1214 #7 0x55d5db99d19d in main bgpd/bgp_main.c:510 #8 0x7f8d160c5c86 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21c86) *********************************************************************************** ``` Signed-off-by: Keelan Cannoo --- bgpd/bgp_mplsvpn.c | 7 ++++++- bgpd/bgp_vty.c | 2 +- bgpd/bgp_zebra.c | 2 +- bgpd/bgpd.c | 2 ++ bgpd/bgpd.h | 3 +++ lib/srv6.c | 2 +- lib/srv6.h | 1 + 7 files changed, 15 insertions(+), 4 deletions(-) diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 1e25e1b6a7..cf57d95eb0 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -596,6 +596,11 @@ static void sid_register(struct bgp *bgp, const struct in6_addr *sid, listnode_add(bgp->srv6_functions, func); } +void srv6_function_free(struct bgp_srv6_function *func) +{ + XFREE(MTYPE_BGP_SRV6_FUNCTION, func); +} + void sid_unregister(struct bgp *bgp, const struct in6_addr *sid) { struct listnode *node, *nnode; @@ -604,7 +609,7 @@ void sid_unregister(struct bgp *bgp, const struct in6_addr *sid) for (ALL_LIST_ELEMENTS(bgp->srv6_functions, node, nnode, func)) if (sid_same(&func->sid, sid)) { listnode_delete(bgp->srv6_functions, func); - XFREE(MTYPE_BGP_SRV6_FUNCTION, func); + srv6_function_free(func); } } diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index e45a5fccb4..4f9e4b4ce9 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -319,7 +319,7 @@ static int bgp_srv6_locator_unset(struct bgp *bgp) /* refresh functions */ for (ALL_LIST_ELEMENTS(bgp->srv6_functions, node, nnode, func)) { listnode_delete(bgp->srv6_functions, func); - XFREE(MTYPE_BGP_SRV6_FUNCTION, func); + srv6_function_free(func); } /* refresh tovpn_sid */ diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 98e21bae09..dfb8d01f2d 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -3213,7 +3213,7 @@ static int bgp_zebra_process_srv6_locator_delete(ZAPI_CALLBACK_ARGS) if (prefix_match((struct prefix *)&loc.prefix, (struct prefix *)&tmp_prefi)) { listnode_delete(bgp->srv6_functions, func); - XFREE(MTYPE_BGP_SRV6_FUNCTION, func); + srv6_function_free(func); } } diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index e7318e994b..3c1f223228 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1427,7 +1427,9 @@ static void bgp_srv6_init(struct bgp *bgp) bgp->srv6_enabled = false; memset(bgp->srv6_locator_name, 0, sizeof(bgp->srv6_locator_name)); bgp->srv6_locator_chunks = list_new(); + bgp->srv6_locator_chunks->del = srv6_locator_chunk_list_free; bgp->srv6_functions = list_new(); + bgp->srv6_functions->del = (void (*)(void *))srv6_function_free; } static void bgp_srv6_cleanup(struct bgp *bgp) diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 30877cad06..9e9d1c1e1e 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -2739,6 +2739,9 @@ extern bool bgp_path_attribute_discard(struct peer *peer, char *buf, size_t size); extern bool bgp_path_attribute_treat_as_withdraw(struct peer *peer, char *buf, size_t size); + +extern void srv6_function_free(struct bgp_srv6_function *func); + #ifdef _FRR_ATTRIBUTE_PRINTFRR /* clang-format off */ #pragma FRR printfrr_ext "%pBP" (struct peer *) diff --git a/lib/srv6.c b/lib/srv6.c index 09835f3ea8..dceb6ab48b 100644 --- a/lib/srv6.c +++ b/lib/srv6.c @@ -108,7 +108,7 @@ const char *seg6local_context2str(char *str, size_t size, } } -static void srv6_locator_chunk_list_free(void *data) +void srv6_locator_chunk_list_free(void *data) { struct srv6_locator_chunk *chunk = data; diff --git a/lib/srv6.h b/lib/srv6.h index fb34f861c8..433c5c14fd 100644 --- a/lib/srv6.h +++ b/lib/srv6.h @@ -252,6 +252,7 @@ int snprintf_seg6_segs(char *str, extern struct srv6_locator *srv6_locator_alloc(const char *name); extern struct srv6_locator_chunk *srv6_locator_chunk_alloc(void); extern void srv6_locator_free(struct srv6_locator *locator); +extern void srv6_locator_chunk_list_free(void *data); extern void srv6_locator_chunk_free(struct srv6_locator_chunk **chunk); json_object *srv6_locator_chunk_json(const struct srv6_locator_chunk *chunk); json_object *srv6_locator_json(const struct srv6_locator *loc);