Use-after-free in OSPF with BFD on
Hi, I found a use-after-free in OSPF with BFD on, which crashes BIRD 3.4.0 on FreeBSD. In ospf_neighbor_new(), we allocate the ospf_neighbor structure from a child pool, and ospf_neigh_down() frees it with rp_free(). The problem is, if that neighbor relies on BFD, ospf_neigh_update_bfd() later adds the BFD reference to the same pool, and the request's notify points at n->bfd_notify, which is embedded in the neighbor. Since the pool frees resources in allocation order, when the neighbor goes to NEIGHBOR_DOWN, the neighbor is freed first, and then bfd_request_ref_free() cancels a callback inside freed memory. The same happens when OSPF shuts down with neighbors up. To reproduce: MALLOC_CONF=junk:true, two routers with OSPF ptp and bfd on, kill one, and the other dies in seconds. I first tried to allocate the ospf_neighbor from the protocol pool itself and free it at the end of neighbor down, and that fixed it: https://github.com/spmzt/bird/commit/0de65adf9676750d58f5e83ef5be4db7ed811cb... But it looks wrong to treat OSPF specially. The main problem is the order, we free the hooks of a pool and its memory in the same loop. So I tried to free all the hooks first before freeing the pool data: https://github.com/spmzt/bird/commit/09e859086fa82ae1f4142ef8d027c733dbb899b... I think the second one is the correct fix, but I’ll leave it to you to decide. I also found another bug: a configure that turns bfd on for an OSPF interface with a neighbor up aborts with "Trying to lock in a bad order" (ospf_iface_reconfigure -> bfd_request_session -> do_lock). -- Pouria
participants (1)
-
Pouria Mousavizadeh Tehrani