Skip to content

Commit 8d03451

Browse files
committed
bgpd: fix double-free of EVPN attrs with soft-reconf
With soft reconfiguration, the BGP attributes are interned, but the EVPN attributes contained by the standard attributes are also interned. However, during BGP route processing, we performed a copy of the attributes in a new_attr struct, performing a shallow-copy. This made two structs point to the same interned EVPN attributes, freeing the attributes at the end of the input processing. Fix the double-free by increasing the refcount when shallow-copying the attributes. The direct symptom can be seen with a topotest, where bgpd segfaults on exit when cleaning up peer data: FRRouting#12 0x00007fc57d6a8ff5 in malloc_printerr (str=str@entry=0x7fc57d7d18a0 "malloc_consolidate(): unaligned fastbin chunk detected") at ./malloc/malloc.c:5772 FRRouting#13 0x00007fc57d6a9d4c in malloc_consolidate (av=0x7fc57d803ac0 <main_arena>) at ./malloc/malloc.c:4846 FRRouting#14 0x00007fc57d6aada5 in _int_free_maybe_consolidate (av=0x7fc57d803ac0 <main_arena>, size=<optimized out>) at ./malloc/malloc.c:4779 FRRouting#15 0x00007fc57d6ab43a in _int_free (av=0x7fc57d803ac0 <main_arena>, p=<optimized out>, have_lock=<optimized out>) at ./malloc/malloc.c:4646 FRRouting#16 0x00007fc57d6addae in __GI___libc_free (mem=0x55704295e8a0) at ./malloc/malloc.c:3398 FRRouting#17 0x00007fc57dada55e in qfree (mt=mt@entry=0x7fc57dc34e60 <MTYPE_STREAM>, ptr=<optimized out>) at lib/memory.c:131 FRRouting#18 0x00007fc57db1b8f8 in stream_free (s=<optimized out>) at lib/stream.c:109 FRRouting#19 0x000055704186539e in sync_delete (subgrp=0x557042957f00) at bgpd/bgp_updgrp.c:108 FRRouting#20 update_subgroup_delete (subgrp=0x557042957f00) at bgpd/bgp_updgrp.c:1167 FRRouting#21 0x0000557041866c75 in update_subgroup_check_delete (subgrp=<optimized out>) at bgpd/bgp_updgrp.c:1202 FRRouting#22 0x00005570417fbf51 in update_group_remove_peer_afs (peer=<optimized out>) at ./bgpd/bgp_updgrp.h:523 FRRouting#23 bgp_stop (connection=<optimized out>) at bgpd/bgp_fsm.c:1478 FRRouting#24 0x0000557041800357 in bgp_event_update (connection=0x557042956b50, event=TCP_connection_closed) at bgpd/bgp_fsm.c:2655 FRRouting#25 0x00007fc57db28fae in event_call (thread=thread@entry=0x7ffe0c687760) at lib/event.c:2019 FRRouting#26 0x00007fc57daccb28 in frr_run (master=0x5570421106e0) at lib/libfrr.c:1247 FRRouting#27 0x00005570417b1fd3 in main (argc=<optimized out>, argv=0x7ffe0c687a28) at bgpd/bgp_main.c:557 Fixes: 4ace11d ("bgpd: Move evpn_overlay to a pointer")
1 parent 13136e9 commit 8d03451

File tree

1 file changed

+11
-0
lines changed

1 file changed

+11
-0
lines changed

bgpd/bgp_route.c

+11
Original file line numberDiff line numberDiff line change
@@ -5159,6 +5159,17 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
51595159
}
51605160

51615161
new_attr = *attr;
5162+
if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)) {
5163+
/* For soft-reconfiguration, the attributes are interned. If
5164+
* the EVPN attributes are set, they are ref-counted. We
5165+
* perform a shallow-copy of the attribtues above, thus need to
5166+
* increase the EVPN refcount to avoid a double-free later on.
5167+
*/
5168+
struct bgp_route_evpn *bre = bgp_attr_get_evpn_overlay(attr);
5169+
if (bre && bre->refcnt)
5170+
bre->refcnt++;
5171+
}
5172+
51625173
/*
51635174
* If bgp_update is called with soft_reconfig set then
51645175
* attr is interned. In this case, do not overwrite the

0 commit comments

Comments
 (0)