diff --git a/sys/netgraph7/bluetooth/socket/ng_btsocket_l2cap_raw.c b/sys/netgraph7/bluetooth/socket/ng_btsocket_l2cap_raw.c --- a/sys/netgraph7/bluetooth/socket/ng_btsocket_l2cap_raw.c +++ b/sys/netgraph7/bluetooth/socket/ng_btsocket_l2cap_raw.c @@ -700,9 +700,13 @@ break; } - lockmgr(&ng_btsocket_l2cap_raw_rt_lock, LK_RELEASE); - + /* + * Keep rt_lock held across pcb->rt = rt. ng_btsocket_l2cap_rtentry + * has no refcount, so releasing rt_lock before storing the pointer + * lets ng_btsocket_l2cap_raw_rtclean() free the entry (use-after-free). + */ if (rt == NULL) { + lockmgr(&ng_btsocket_l2cap_raw_rt_lock, LK_RELEASE); error = ENETDOWN; goto out; } @@ -714,6 +718,9 @@ pcb->rt = rt; lockmgr(&pcb->pcb_lock, LK_RELEASE); + if (rt != NULL) + lockmgr(&ng_btsocket_l2cap_raw_rt_lock, LK_RELEASE); + out: lwkt_replymsg(&msg->bind.base.lmsg, error); } /* ng_btsocket_l2cap_raw_bind */