Skip to content

Commit

Permalink
zebra: fix do not use ROUTE_DELETE when nhe not available
Browse files Browse the repository at this point in the history
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
>     FRRouting#1 0x558966dbd8f5 in dplane_route_update_internal zebra/zebra_dplane.c:4237
>     FRRouting#2 0x558966e5eb99 in rib_uninstall_kernel zebra/zebra_rib.c:778
>     FRRouting#3 0x558966e685f8 in rib_process_del_fib zebra/zebra_rib.c:1023
>     FRRouting#4 0x558966e685f8 in rib_process zebra/zebra_rib.c:1489
>     FRRouting#5 0x558966e6ab55 in process_subq_route zebra/zebra_rib.c:2792
>     FRRouting#6 0x558966e6ab55 in process_subq zebra/zebra_rib.c:3356
>     FRRouting#7 0x558966e6ab55 in meta_queue_process zebra/zebra_rib.c:3395
>     FRRouting#8 0x7f7fd771207f in work_queue_run lib/workqueue.c:282
>     FRRouting#9 0x7f7fd76f3d3b in event_call lib/event.c:2011
>     FRRouting#10 0x7f7fd761b897 in frr_run lib/libfrr.c:1212
>     FRRouting#11 0x558966d270b6 in main zebra/main.c:533
>     FRRouting#12 0x7f7fd7029d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
>     FRRouting#13 0x7f7fd7029e3f in __libc_start_main_impl ../csu/libc-start.c:392
>     FRRouting#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
>     FRRouting#1 0x558966e6b38b in process_subq_nhg zebra/zebra_rib.c:2730
>     FRRouting#2 0x558966e6b38b in process_subq zebra/zebra_rib.c:3342
>     FRRouting#3 0x558966e6b38b in meta_queue_process zebra/zebra_rib.c:3395
>     FRRouting#4 0x7f7fd771207f in work_queue_run lib/workqueue.c:282
>     FRRouting#5 0x7f7fd76f3d3b in event_call lib/event.c:2011
>     FRRouting#6 0x7f7fd761b897 in frr_run lib/libfrr.c:1212
>     FRRouting#7 0x558966d270b6 in main zebra/main.c:533
>     FRRouting#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 <philippe.guibert@6wind.com>
  • Loading branch information
pguibert6WIND committed Oct 10, 2024
1 parent d30fa81 commit 5056eb7
Showing 1 changed file with 9 additions and 0 deletions.
9 changes: 9 additions & 0 deletions zebra/zebra_rib.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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)
Expand Down

0 comments on commit 5056eb7

Please sign in to comment.