Bluetooth: 6lowpan: avoid concurrent peer_del() in bt_6lowpan_disconnect

bt_6lowpan_disconnect() looks up and accesses peer->chan, without
holding locks guaranteeing peer_del() cannot free the peer concurrently.

Take devices_lock to ensure peer can be dereferenced safely.

Fixes: 15f32cabf4 ("Bluetooth: 6lowpan: add missing l2cap_chan_lock()")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
Pauli Virtanen 2026-08-29 17:20:01 +03:00 committed by Luiz Augusto von Dentz
parent 5ccdbf71f1
commit df5175dfcf

View File

@ -912,16 +912,27 @@ static int bt_6lowpan_connect(bdaddr_t *addr, u8 dst_type)
static int bt_6lowpan_disconnect(struct l2cap_conn *conn, u8 dst_type)
{
struct lowpan_peer *peer;
struct l2cap_chan *chan;
BT_DBG("conn %p dst type %u", conn, dst_type);
spin_lock(&devices_lock);
peer = lookup_peer(conn);
if (!peer)
if (!peer) {
spin_unlock(&devices_lock);
return -ENOENT;
}
BT_DBG("peer %p chan %p", peer, peer->chan);
chan = peer->chan;
l2cap_chan_hold(chan);
l2cap_chan_close_unlocked(peer->chan, ENOENT);
spin_unlock(&devices_lock);
BT_DBG("peer %p chan %p", peer, chan);
l2cap_chan_close_unlocked(chan, ENOENT);
l2cap_chan_put(chan);
return 0;
}