From 5056eb714fb5423b8c502c711ebbba51d15b35b9 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Thu, 10 Oct 2024 15:27:55 +0200 Subject: [PATCH] zebra: fix do not use ROUTE_DELETE when nhe not available The following heap-use-after-free message happens when teardown test happens on a topotest using protocol nexthop-groups. > ==739645==ERROR: AddressSanitizer: heap-use-after-free on address 0x60e00004df48 at pc 0x558966dbd6d1 bp 0x7ffdfc1e0ec0 sp 0x7ffdfc1e0eb0 > READ of size 8 at 0x60e00004df48 thread T0 > #0 0x558966dbd6d0 in dplane_ctx_route_init zebra/zebra_dplane.c:3447 > #1 0x558966dbd8f5 in dplane_route_update_internal zebra/zebra_dplane.c:4237 > #2 0x558966e5eb99 in rib_uninstall_kernel zebra/zebra_rib.c:778 > #3 0x558966e685f8 in rib_process_del_fib zebra/zebra_rib.c:1023 > #4 0x558966e685f8 in rib_process zebra/zebra_rib.c:1489 > #5 0x558966e6ab55 in process_subq_route zebra/zebra_rib.c:2792 > #6 0x558966e6ab55 in process_subq zebra/zebra_rib.c:3356 > #7 0x558966e6ab55 in meta_queue_process zebra/zebra_rib.c:3395 > #8 0x7f7fd771207f in work_queue_run lib/workqueue.c:282 > #9 0x7f7fd76f3d3b in event_call lib/event.c:2011 > #10 0x7f7fd761b897 in frr_run lib/libfrr.c:1212 > #11 0x558966d270b6 in main zebra/main.c:533 > #12 0x7f7fd7029d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 > #13 0x7f7fd7029e3f in __libc_start_main_impl ../csu/libc-start.c:392 > #14 0x558966d29ed4 in _start (/usr/lib/frr/zebra+0x1b4ed4) > > 0x60e00004df48 is located 40 bytes inside of 160-byte region [0x60e00004df20,0x60e00004dfc0) > freed by thread T0 here: > #0 0x7f7fd7ab4537 in __interceptor_free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:127 > #1 0x558966e6b38b in process_subq_nhg zebra/zebra_rib.c:2730 > #2 0x558966e6b38b in process_subq zebra/zebra_rib.c:3342 > #3 0x558966e6b38b in meta_queue_process zebra/zebra_rib.c:3395 > #4 0x7f7fd771207f in work_queue_run lib/workqueue.c:282 > #5 0x7f7fd76f3d3b in event_call lib/event.c:2011 > #6 0x7f7fd761b897 in frr_run lib/libfrr.c:1212 > #7 0x558966d270b6 in main zebra/main.c:533 > #8 0x7f7fd7029d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 A ROUTE_DELETE message is sent with an NHE identifier, in addition to NHG_DELETE. The latter message triggers the deletion of the NHE, but no check is done for the former message. Fix this by checking if the NHE ID exists before sending it to the dataplane. Signed-off-by: Philippe Guibert --- zebra/zebra_rib.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 8ebc193fba99..f88c51a0f519 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -723,6 +723,7 @@ void rib_uninstall_kernel(struct route_node *rn, struct route_entry *re) struct nexthop *nexthop; struct rib_table_info *info = srcdest_rnode_table_info(rn); struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(re->vrf_id); + struct nhg_hash_entry *nhe; if (info->safi != SAFI_UNICAST) { UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED); @@ -737,6 +738,14 @@ void rib_uninstall_kernel(struct route_node *rn, struct route_entry *re) */ hook_call(rib_update, rn, "uninstalling from kernel"); + if (re->nhe_id) { + nhe = zebra_nhg_lookup_id(re->nhe_id); + if (!nhe) + /* nothing to process, as there is no NHG to delete + */ + return; + } + switch (dplane_route_delete(rn, re)) { case ZEBRA_DPLANE_REQUEST_QUEUED: if (zvrf)