Skip to content

Commit 27064f7

Browse files
committed
bgpd: Fix double-free crash in peer_delete() during doppelganger peer transfer
In peer_xfer_conn(), the hostname, domainname, and soft_version pointers were transferred between peers using simple pointer assignment, which caused both peers to reference the same memory. If the transfer didn't complete cleanly or there was a race condition during peer state transitions, when both peers were eventually deleted, the same memory was freed twice, causing a crash. Fix this by using XSTRDUP() to create independent copies of the strings instead of transferring pointer ownership. This ensures each peer owns its own memory and can be safely deleted independently. Crash was seen intermittently when removing interface-based BGP neighbors from peer-groups after the session reached Established state. example: no neighbor swp3 interface peer-group fabric Backtrace: #0  0x00007fc88b41aeec in ?? () from /lib/x86_64-linux-gnu/libc.so.6 #1  0x00007fc88b3cbfb2 in raise () from /lib/x86_64-linux-gnu/libc.so.6 #2  0x00007fc88b70045c in core_handler (signo=11, siginfo=0x7fffbdee6c30, context=<optimized out>) at ../lib/sigevent.c:261 #3  <signal handler called> #4  0x00007fc88b429d49 in malloc_usable_size () from /lib/x86_64-linux-gnu/libc.so.6 #5  0x00007fc88b6c99f9 in mt_count_free (ptr=0x55ff594d9320, mt=0x55ff25046460 <MTYPE_BGP_PEER_HOST>) at ../lib/memory.c:77 #6  qfree (mt=0x55ff25046460 <MTYPE_BGP_PEER_HOST>, ptr=0x55ff594d9320) at ../lib/memory.c:129 #7  0x000055ff24eac802 in peer_delete (peer=peer@entry=0x55ff5941d770) at ../bgpd/bgpd.c:2864 #8  0x000055ff24e65982 in no_neighbor_interface_config (...) at ../bgpd/bgp_vty.c:5862 #9  0x00007fc88b695ab0 in cmd_execute_command_real (...) at ../lib/command.c:1018 #10 0x00007fc88b695bae in cmd_execute_command (...) at ../lib/command.c:1076 #11 0x00007fc88b695e40 in cmd_execute (vty=..., cmd=no neighbor swp3 interface peer-group test_gr_shut, ...) at ../lib/command.c:1243 Ticket: #20628 Signed-off-by: Rajesh Varatharaj <[email protected]>
1 parent ff06e5a commit 27064f7

File tree

1 file changed

+6
-12
lines changed

1 file changed

+6
-12
lines changed

bgpd/bgp_fsm.c

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -240,28 +240,22 @@ static struct peer *peer_xfer_conn(struct peer *from_peer)
240240
XFREE(MTYPE_BGP_PEER_HOST, peer->hostname);
241241
peer->hostname = NULL;
242242
}
243-
if (from_peer->hostname != NULL) {
244-
peer->hostname = from_peer->hostname;
245-
from_peer->hostname = NULL;
246-
}
243+
if (from_peer->hostname != NULL)
244+
peer->hostname = XSTRDUP(MTYPE_BGP_PEER_HOST, from_peer->hostname);
247245

248246
if (peer->domainname) {
249247
XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);
250248
peer->domainname = NULL;
251249
}
252-
if (from_peer->domainname != NULL) {
253-
peer->domainname = from_peer->domainname;
254-
from_peer->domainname = NULL;
255-
}
250+
if (from_peer->domainname != NULL)
251+
peer->domainname = XSTRDUP(MTYPE_BGP_PEER_HOST, from_peer->domainname);
256252

257253
if (peer->soft_version) {
258254
XFREE(MTYPE_BGP_SOFT_VERSION, peer->soft_version);
259255
peer->soft_version = NULL;
260256
}
261-
if (from_peer->soft_version) {
262-
peer->soft_version = from_peer->soft_version;
263-
from_peer->soft_version = NULL;
264-
}
257+
if (from_peer->soft_version)
258+
peer->soft_version = XSTRDUP(MTYPE_BGP_SOFT_VERSION, from_peer->soft_version);
265259

266260
FOREACH_AFI_SAFI (afi, safi) {
267261
peer->af_sflags[afi][safi] = from_peer->af_sflags[afi][safi];

0 commit comments

Comments
 (0)