From b508a2a2d846ccc4c8f691e4e3dfca6f97dfe85a Mon Sep 17 00:00:00 2001 From: Pauli Virtanen Date: Sat, 29 Aug 2026 17:20:06 +0300 Subject: Bluetooth: L2CAP: hold chan in l2cap_ecred_conn_rsp() l2cap_chan_del() calls l2cap_chan_put() to drop the conn->chan_l reference. If this was the last reference, UAF follows. l2cap_ecred_conn_rsp() iterates chan_l list and calls l2cap_chan_del() on some members, without holding chan reference. Fix by holding refcount while using chan after l2cap_chan_del(). Since orig is looked up by dcid provided by remote, it's also possible orig == chan, so reference needs to be held also after orig use. Fixes: 41c2713b204e ("Bluetooth: L2CAP: Fix possible crash on l2cap_ecred_conn_rsp") Assisted-by: deepseek-v4-flash Signed-off-by: Pauli Virtanen Signed-off-by: Luiz Augusto von Dentz --- net/bluetooth/l2cap_core.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'net') diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 68fc14344026..93dade523416 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -5468,12 +5468,14 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn, chan->state == BT_CONNECTED) continue; + l2cap_chan_hold(chan); l2cap_chan_lock(chan); /* Check that there is a dcid for each pending channel */ if (cmd_len < sizeof(dcid)) { l2cap_chan_del(chan, ECONNREFUSED); l2cap_chan_unlock(chan); + l2cap_chan_put(chan); continue; } @@ -5512,6 +5514,8 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn, __set_chan_timer(orig, 0); l2cap_chan_unlock(orig); } + + l2cap_chan_put(chan); continue; } @@ -5557,6 +5561,7 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn, } l2cap_chan_unlock(chan); + l2cap_chan_put(chan); } return err; -- cgit v1.2.3