diff options
| author | Pauli Virtanen <pav@iki.fi> | 2026-08-29 17:19:56 +0300 |
|---|---|---|
| committer | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2026-10-14 13:23:46 -0400 |
| commit | 385c0829e09e7a6380ae67998ac6ef6f4dfd5303 (patch) | |
| tree | 56447dc0b55ad87c2582ac40970d26c9b03ec458 /include | |
| parent | a2bb734c368766a2499ed00590ea838cac13c76e (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.h | 3 |
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); |
