summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorPaolo Abeni <pabeni@redhat.com>2026-03-26 13:46:55 +0100
committerPaolo Abeni <pabeni@redhat.com>2026-03-26 13:46:55 +0100
commitaa637b2cf303e1d133a5c4ad3ee397ad99ad3f14 (patch)
treee0fe78ecc588d585023c56d518b276b5efd1f1ea /net
parent84a8335d8300576f1b377ae24abca1d9f197807f (diff)
parent129fa608b6ad08b8ab7178eeb2ec272c993aaccc (diff)
Merge tag 'for-net-2026-03-25' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth
Luiz Augusto von Dentz says: ==================== bluetooth pull request for net: - L2CAP: Fix deadlock in l2cap_conn_del() - L2CAP: Fix ERTM re-init and zero pdu_len infinite loop - L2CAP: Fix send LE flow credits in ACL link - btintel: serialize btintel_hw_error() with hci_req_sync_lock - btusb: clamp SCO altsetting table indices * tag 'for-net-2026-03-25' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth: Bluetooth: btusb: clamp SCO altsetting table indices Bluetooth: L2CAP: Fix ERTM re-init and zero pdu_len infinite loop Bluetooth: L2CAP: Fix deadlock in l2cap_conn_del() Bluetooth: btintel: serialize btintel_hw_error() with hci_req_sync_lock Bluetooth: L2CAP: Fix send LE flow credits in ACL link ==================== Link: https://patch.msgid.link/20260325194358.618892-1-luiz.dentz@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/l2cap_core.c31
1 files changed, 19 insertions, 12 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 3de3e3c8e966..95c65fece39b 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1771,6 +1771,9 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
+ disable_delayed_work_sync(&conn->info_timer);
+ disable_delayed_work_sync(&conn->id_addr_timer);
+
mutex_lock(&conn->lock);
kfree_skb(conn->rx_skb);
@@ -1786,8 +1789,6 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
ida_destroy(&conn->tx_ida);
- cancel_delayed_work_sync(&conn->id_addr_timer);
-
l2cap_unregister_all_users(conn);
/* Force the connection to be immediately dropped */
@@ -1806,9 +1807,6 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
l2cap_chan_put(chan);
}
- if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
- cancel_delayed_work_sync(&conn->info_timer);
-
hci_chan_del(conn->hchan);
conn->hchan = NULL;
@@ -2400,6 +2398,9 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan,
/* Remote device may have requested smaller PDUs */
pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
+ if (!pdu_len)
+ return -EINVAL;
+
if (len <= pdu_len) {
sar = L2CAP_SAR_UNSEGMENTED;
sdu_len = 0;
@@ -4335,14 +4336,16 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
set_default_fcs(chan);
- if (chan->mode == L2CAP_MODE_ERTM ||
- chan->mode == L2CAP_MODE_STREAMING)
- err = l2cap_ertm_init(chan);
+ if (chan->state != BT_CONNECTED) {
+ if (chan->mode == L2CAP_MODE_ERTM ||
+ chan->mode == L2CAP_MODE_STREAMING)
+ err = l2cap_ertm_init(chan);
- if (err < 0)
- l2cap_send_disconn_req(chan, -err);
- else
- l2cap_chan_ready(chan);
+ if (err < 0)
+ l2cap_send_disconn_req(chan, -err);
+ else
+ l2cap_chan_ready(chan);
+ }
goto unlock;
}
@@ -6630,6 +6633,10 @@ static void l2cap_chan_le_send_credits(struct l2cap_chan *chan)
struct l2cap_le_credits pkt;
u16 return_credits = l2cap_le_rx_credits(chan);
+ if (chan->mode != L2CAP_MODE_LE_FLOWCTL &&
+ chan->mode != L2CAP_MODE_EXT_FLOWCTL)
+ return;
+
if (chan->rx_credits >= return_credits)
return;