mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 23:53:28 +00:00
ospf6d: Prevent use after free
I am seeing a crash of ospf6d with this stack trace: OSPF6: Received signal 11 at 1636042827 (si_addr 0x0, PC 0x55efc2d09ec2); aborting... OSPF6: zlog_signal+0x18c 7fe20c8ca19a 7ffd08035590 /lib/libfrr.so.0 (mapped at 0x7fe20c819000) OSPF6: core_handler+0xe3 7fe20c90805e 7ffd080356b0 /lib/libfrr.so.0 (mapped at 0x7fe20c819000) OSPF6: funlockfile+0x50 7fe20c7f8140 7ffd08035800 /lib/x86_64-linux-gnu/libpthread.so.0 (mapped at 0x7fe20c7e4000) OSPF6: ---- signal ---- OSPF6: ospf6_neighbor_state_change+0xdc 55efc2d09ec2 7ffd08035d90 /usr/lib/frr/ospf6d (mapped at 0x55efc2c8e000) OSPF6: exchange_done+0x15c 55efc2d0ab4a 7ffd08035dc0 /usr/lib/frr/ospf6d (mapped at 0x55efc2c8e000) OSPF6: thread_call+0xc2 7fe20c91ee32 7ffd08035df0 /lib/libfrr.so.0 (mapped at 0x7fe20c819000) OSPF6: frr_run+0x217 7fe20c8bf7f3 7ffd08035eb0 /lib/libfrr.so.0 (mapped at 0x7fe20c819000) OSPF6: main+0xf3 55efc2cd7573 7ffd08035fc0 /usr/lib/frr/ospf6d (mapped at 0x55efc2c8e000) OSPF6: __libc_start_main+0xea 7fe20c645d0a 7ffd08036000 /lib/x86_64-linux-gnu/libc.so.6 (mapped at 0x7fe20c61f000) OSPF6: _start+0x2a 55efc2cd706a 7ffd080360d0 /usr/lib/frr/ospf6d (mapped at 0x55efc2c8e000) OSPF6: in thread exchange_done scheduled from ospf6d/ospf6_message.c:2264 ospf6_dbdesc_send_newone() The stack trace when decoded is: (gdb) l *(ospf6_neighbor_state_change+0xdc) 0x7bec2 is in ospf6_neighbor_state_change (ospf6d/ospf6_neighbor.c:200). warning: Source file is more recent than executable. 195 on->name, ospf6_neighbor_state_str[prev_state], 196 ospf6_neighbor_state_str[next_state], 197 ospf6_neighbor_event_string(event)); 198 } 199 200 /* Optionally notify about adjacency changes */ 201 if (CHECK_FLAG(on->ospf6_if->area->ospf6->config_flags, 202 OSPF6_LOG_ADJACENCY_CHANGES) 203 && (CHECK_FLAG(on->ospf6_if->area->ospf6->config_flags, 204 OSPF6_LOG_ADJACENCY_DETAIL) OSPFv3 is creating the event without a managing thread and as such if the event is not run before a deletion event comes in memory will be freed up and we'll start trying to access memory we should not. Modify ospfv3 to track the thread and appropriately stop it when the memory is deleted or it is no longer need to run that bit of code. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
This commit is contained in:
parent
77c657fb1f
commit
9318fc6a38
@ -772,7 +772,8 @@ static void ospf6_dbdesc_recv_master(struct ospf6_header *oh,
|
||||
/* More bit check */
|
||||
if (!CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MBIT)
|
||||
&& !CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT))
|
||||
thread_add_event(master, exchange_done, on, 0, NULL);
|
||||
thread_add_event(master, exchange_done, on, 0,
|
||||
&on->thread_exchange_done);
|
||||
else {
|
||||
thread_add_event(master, ospf6_dbdesc_send_newone, on, 0,
|
||||
&on->thread_send_dbdesc);
|
||||
@ -2261,7 +2262,8 @@ int ospf6_dbdesc_send_newone(struct thread *thread)
|
||||
if (!CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT) && /* Slave */
|
||||
!CHECK_FLAG(on->dbdesc_last.bits, OSPF6_DBDESC_MBIT)
|
||||
&& !CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT))
|
||||
thread_add_event(master, exchange_done, on, 0, NULL);
|
||||
thread_add_event(master, exchange_done, on, 0,
|
||||
&on->thread_exchange_done);
|
||||
|
||||
thread_execute(master, ospf6_dbdesc_send, on, 0);
|
||||
return 0;
|
||||
|
@ -168,6 +168,7 @@ void ospf6_neighbor_delete(struct ospf6_neighbor *on)
|
||||
THREAD_OFF(on->thread_send_lsreq);
|
||||
THREAD_OFF(on->thread_send_lsupdate);
|
||||
THREAD_OFF(on->thread_send_lsack);
|
||||
THREAD_OFF(on->thread_exchange_done);
|
||||
THREAD_OFF(on->gr_helper_info.t_grace_timer);
|
||||
|
||||
bfd_sess_free(&on->bfd_session);
|
||||
@ -603,6 +604,7 @@ int oneway_received(struct thread *thread)
|
||||
THREAD_OFF(on->thread_send_lsreq);
|
||||
THREAD_OFF(on->thread_send_lsupdate);
|
||||
THREAD_OFF(on->thread_send_lsack);
|
||||
THREAD_OFF(on->thread_exchange_done);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -136,6 +136,7 @@ struct ospf6_neighbor {
|
||||
struct thread *thread_send_lsreq;
|
||||
struct thread *thread_send_lsupdate;
|
||||
struct thread *thread_send_lsack;
|
||||
struct thread *thread_exchange_done;
|
||||
|
||||
/* BFD information */
|
||||
struct bfd_session_params *bfd_session;
|
||||
|
Loading…
Reference in New Issue
Block a user