diff options
| author | Rajesh Varatharaj <rvaratharaj@nvidia.com> | 2025-03-06 16:57:18 -0800 | 
|---|---|---|
| committer | Rajesh Varatharaj <rvaratharaj@nvidia.com> | 2025-03-11 13:41:40 -0700 | 
| commit | 3060afc84d2c8a6fa79d588000331e94c36921ae (patch) | |
| tree | 57fa52064231e9ac12f171af709ad3268e4363d4 /zebra | |
| parent | b1711c010fbb016b982b1d7471ae62a44c00e93c (diff) | |
zebra: Fix neigh delete causing heap-use-after-free error
Issue:
Not freeing the neighbor n  within the same function can lead to
memory leak.
zebra_neigh_del_all() -> zebra_neigh_del() re lookup and free
Fix: not accessing n after its freed.
Directly free the neighbor entry (n) when its interface index matches
ifp->ifindex.
This fixes:
ERROR: AddressSanitizer: heap-use-after-free on address 0x6070001052e8 at pc 0x7f6bf7d09ddb bp 0x7ffd3366a000 sp 0x7ffd33669ff0
READ of size 8 at 0x6070001052e8 thread T0
    #0 0x7f6bf7d09dda in _rb_next lib/openbsd-tree.c:455
    #1 0x55f95a307261 in zebra_neigh_rb_head_RB_NEXT zebra/zebra_neigh.h:34
    #2 0x55f95a3082e9 in zebra_neigh_del_all zebra/zebra_neigh.c:162
    #3 0x55f95a121ee7 in zebra_interface_down_update zebra/redistribute.c:571
    #4 0x55f95a0f819d in if_down zebra/interface.c:1017
    #5 0x55f95a0fe168 in zebra_if_dplane_ifp_handling zebra/interface.c:2102
    #6 0x55f95a0ff10c in zebra_if_dplane_result zebra/interface.c:2241
    #7 0x55f95a27ce9c in rib_process_dplane_results zebra/zebra_rib.c:5015
    #8 0x7f6bf7da3ad9 in event_call lib/event.c:1984
    #9 0x7f6bf7c62141 in frr_run lib/libfrr.c:1246
    #10 0x55f95a11ca7f in main zebra/main.c:543
    #11 0x7f6bf7029d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #12 0x7f6bf7029e3f in __libc_start_main_impl ../csu/libc-start.c:392
    #13 0x55f95a0dd0b4 in _start (/usr/lib/frr/zebra+0x1a80b4)
Ticket: #18047
Signed-off-by: Rajesh Varatharaj <rvaratharaj@nvidia.com>
Diffstat (limited to 'zebra')
| -rw-r--r-- | zebra/zebra_neigh.c | 10 | 
1 files changed, 7 insertions, 3 deletions
diff --git a/zebra/zebra_neigh.c b/zebra/zebra_neigh.c index a222e7f6e8..8a91f2719b 100644 --- a/zebra/zebra_neigh.c +++ b/zebra/zebra_neigh.c @@ -153,14 +153,18 @@ void zebra_neigh_del(struct interface *ifp, struct ipaddr *ip)  /* kernel neigh delete all for a given interface */  void zebra_neigh_del_all(struct interface *ifp)  { -	struct zebra_neigh_ent *n, *nn; +	struct zebra_neigh_ent *n, *next;  	if (IS_ZEBRA_DEBUG_NEIGH)  		zlog_debug("zebra neigh delete all for interface %s/%d",  			   ifp->name, ifp->ifindex); -	RB_FOREACH_SAFE (n, zebra_neigh_rb_head, &zneigh_info->neigh_rb_tree, nn) -		zebra_neigh_del(ifp, &n->ip); +	RB_FOREACH_SAFE (n, zebra_neigh_rb_head, &zneigh_info->neigh_rb_tree, next) { +		if (n->ifindex == ifp->ifindex) { +			/* Free the neighbor directly instead of looking it up again */ +			zebra_neigh_free(n); +		} +	}  }  /* kernel neigh add */  | 
