[PATCH 1/5] Bluetooth: L2CAP: ignore close requests for deleted channels

From: Cen Zhang

Date: Mon Sep 21 2026 - 11:48:30 EST


l2cap_chan_del() keeps chan->conn alive until channel destruction and
marks removal with FLAG_DEL, but does not necessarily change the state.
A caller retaining a temporary reference can therefore enter
l2cap_chan_close_unlocked() after deletion and follow a stale connected
state, rearming the channel timer and sending another disconnection
request for a channel no longer on the connection list.

Check FLAG_DEL after taking the channel and connection locks so that
concurrent deletion is serialized with the decision to close. Return
without further timer or signaling work when the channel is deleted.

Fixes: b66774b48dd9 ("Bluetooth: L2CAP: Fix UAF in channel timeout by holding conn ref")
Assisted-by: LLM
Signed-off-by: Cen Zhang <zzzccc427@xxxxxxxxx>
---
net/bluetooth/l2cap_core.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 49a998804908..65e957fdc7ae 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -939,8 +939,10 @@ void l2cap_chan_close_unlocked(struct l2cap_chan *chan, int reason)

have_conn = l2cap_chan_lock_conn(chan);

- /* Context analysis: consider chan->conn->lock held also if conn NULL */
- context_unsafe(__l2cap_chan_close(chan, reason));
+ if (!test_bit(FLAG_DEL, &chan->flags)) {
+ /* Consider chan->conn->lock held also if conn NULL */
+ context_unsafe(__l2cap_chan_close(chan, reason));
+ }

l2cap_chan_unlock_conn(chan, have_conn);
}

base-commit: 019debf20bfd648b40ba10377ee0168db5eb241e
--
2.43.0