Skip to content

Commit aa637b2

Browse files
author
Paolo Abeni
committed
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/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
2 parents 84a8335 + 129fa60 commit aa637b2

3 files changed

Lines changed: 31 additions & 16 deletions

File tree

drivers/bluetooth/btintel.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,30 +251,35 @@ void btintel_hw_error(struct hci_dev *hdev, u8 code)
251251

252252
bt_dev_err(hdev, "Hardware error 0x%2.2x", code);
253253

254+
hci_req_sync_lock(hdev);
255+
254256
skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
255257
if (IS_ERR(skb)) {
256258
bt_dev_err(hdev, "Reset after hardware error failed (%ld)",
257259
PTR_ERR(skb));
258-
return;
260+
goto unlock;
259261
}
260262
kfree_skb(skb);
261263

262264
skb = __hci_cmd_sync(hdev, 0xfc22, 1, &type, HCI_INIT_TIMEOUT);
263265
if (IS_ERR(skb)) {
264266
bt_dev_err(hdev, "Retrieving Intel exception info failed (%ld)",
265267
PTR_ERR(skb));
266-
return;
268+
goto unlock;
267269
}
268270

269271
if (skb->len != 13) {
270272
bt_dev_err(hdev, "Exception info size mismatch");
271273
kfree_skb(skb);
272-
return;
274+
goto unlock;
273275
}
274276

275277
bt_dev_err(hdev, "Exception info %s", (char *)(skb->data + 1));
276278

277279
kfree_skb(skb);
280+
281+
unlock:
282+
hci_req_sync_unlock(hdev);
278283
}
279284
EXPORT_SYMBOL_GPL(btintel_hw_error);
280285

drivers/bluetooth/btusb.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2376,8 +2376,11 @@ static void btusb_work(struct work_struct *work)
23762376
if (data->air_mode == HCI_NOTIFY_ENABLE_SCO_CVSD) {
23772377
if (hdev->voice_setting & 0x0020) {
23782378
static const int alts[3] = { 2, 4, 5 };
2379+
unsigned int sco_idx;
23792380

2380-
new_alts = alts[data->sco_num - 1];
2381+
sco_idx = min_t(unsigned int, data->sco_num - 1,
2382+
ARRAY_SIZE(alts) - 1);
2383+
new_alts = alts[sco_idx];
23812384
} else {
23822385
new_alts = data->sco_num;
23832386
}

net/bluetooth/l2cap_core.c

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1771,6 +1771,9 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
17711771

17721772
BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
17731773

1774+
disable_delayed_work_sync(&conn->info_timer);
1775+
disable_delayed_work_sync(&conn->id_addr_timer);
1776+
17741777
mutex_lock(&conn->lock);
17751778

17761779
kfree_skb(conn->rx_skb);
@@ -1786,8 +1789,6 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
17861789

17871790
ida_destroy(&conn->tx_ida);
17881791

1789-
cancel_delayed_work_sync(&conn->id_addr_timer);
1790-
17911792
l2cap_unregister_all_users(conn);
17921793

17931794
/* Force the connection to be immediately dropped */
@@ -1806,9 +1807,6 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
18061807
l2cap_chan_put(chan);
18071808
}
18081809

1809-
if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
1810-
cancel_delayed_work_sync(&conn->info_timer);
1811-
18121810
hci_chan_del(conn->hchan);
18131811
conn->hchan = NULL;
18141812

@@ -2400,6 +2398,9 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan,
24002398
/* Remote device may have requested smaller PDUs */
24012399
pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
24022400

2401+
if (!pdu_len)
2402+
return -EINVAL;
2403+
24032404
if (len <= pdu_len) {
24042405
sar = L2CAP_SAR_UNSEGMENTED;
24052406
sdu_len = 0;
@@ -4335,14 +4336,16 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
43354336
if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
43364337
set_default_fcs(chan);
43374338

4338-
if (chan->mode == L2CAP_MODE_ERTM ||
4339-
chan->mode == L2CAP_MODE_STREAMING)
4340-
err = l2cap_ertm_init(chan);
4339+
if (chan->state != BT_CONNECTED) {
4340+
if (chan->mode == L2CAP_MODE_ERTM ||
4341+
chan->mode == L2CAP_MODE_STREAMING)
4342+
err = l2cap_ertm_init(chan);
43414343

4342-
if (err < 0)
4343-
l2cap_send_disconn_req(chan, -err);
4344-
else
4345-
l2cap_chan_ready(chan);
4344+
if (err < 0)
4345+
l2cap_send_disconn_req(chan, -err);
4346+
else
4347+
l2cap_chan_ready(chan);
4348+
}
43464349

43474350
goto unlock;
43484351
}
@@ -6630,6 +6633,10 @@ static void l2cap_chan_le_send_credits(struct l2cap_chan *chan)
66306633
struct l2cap_le_credits pkt;
66316634
u16 return_credits = l2cap_le_rx_credits(chan);
66326635

6636+
if (chan->mode != L2CAP_MODE_LE_FLOWCTL &&
6637+
chan->mode != L2CAP_MODE_EXT_FLOWCTL)
6638+
return;
6639+
66336640
if (chan->rx_credits >= return_credits)
66346641
return;
66356642

0 commit comments

Comments
 (0)