summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorPauli Virtanen <pav@iki.fi>2026-08-29 17:19:56 +0300
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2026-10-14 13:23:46 -0400
commit385c0829e09e7a6380ae67998ac6ef6f4dfd5303 (patch)
tree56447dc0b55ad87c2582ac40970d26c9b03ec458 /include
parenta2bb734c368766a2499ed00590ea838cac13c76e (diff)
Bluetooth: L2CAP: take chan->lock for l2cap_chan_add/ready/del
chan->lock must be held for __l2cap_chan_add as eg. calls to l2cap_chan_close assume chan->conn writes are guarded by it. It must be held for l2cap_chan_del() due to l2cap_sock.c:l2cap_chan_conn, l2cap_monitor_timeout, etc. Similarly it should be held for l2cap_ops::ready (assumed in 6lowpan.c). Also teardown usually has chan->lock held, it should always have it held to have the same locking context. The lock is not correctly held by l2cap_core in several places. Add the missing locks for l2cap_chan_del/add/ready(), except in l2cap_ecred_rsp_defer() which needs separate fix as it needs lock nesting. Fixes: 6fef032af009 ("Bluetooth: L2CAP: Fix use-after-free in l2cap_sock_new_connection_cb()") Signed-off-by: Pauli Virtanen <pav@iki.fi> Reported-by: Eulgyu Kim <eulgyukim@snu.ac.kr> Reported-by: Jaeyoung Chung <jjy600901@snu.ac.kr> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Diffstat (limited to 'include')
-rw-r--r--include/net/bluetooth/l2cap.h3
1 files changed, 2 insertions, 1 deletions
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 69d193fee351..43a67562b238 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -973,7 +973,8 @@ int l2cap_chan_check_security(struct l2cap_chan *chan, bool initiator);
void l2cap_chan_set_defaults(struct l2cap_chan *chan, struct l2cap_chan *pchan);
int l2cap_ertm_init(struct l2cap_chan *chan);
void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan);
-void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan);
+void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
+ __must_hold(&chan->lock);
typedef void (*l2cap_chan_func_t)(struct l2cap_chan *chan, void *data);
void l2cap_chan_list(struct l2cap_conn *conn, l2cap_chan_func_t func,
void *data);