Skip to content

Commit 57ce3b2

Browse files
committed
Merge tag 'for-net-2026-03-19' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth
Luiz Augusto von Dentz says: ==================== bluetooth pull request for net: - hci_ll: Fix firmware leak on error path - hci_sync: annotate data-races around hdev->req_status - L2CAP: Fix null-ptr-deref on l2cap_sock_ready_cb - L2CAP: Validate PDU length before reading SDU length in l2cap_ecred_data_rcv() - L2CAP: Fix regressions caused by reusing ident - L2CAP: Fix stack-out-of-bounds read in l2cap_ecred_conn_req - MGMT: Fix dangling pointer on mgmt_add_adv_patterns_monitor_complete - SCO: Fix use-after-free in sco_recv_frame() due to missing sock_hold * tag 'for-net-2026-03-19' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth: Bluetooth: L2CAP: Fix regressions caused by reusing ident Bluetooth: L2CAP: Fix null-ptr-deref on l2cap_sock_ready_cb Bluetooth: hci_ll: Fix firmware leak on error path Bluetooth: hci_sync: annotate data-races around hdev->req_status Bluetooth: MGMT: Fix dangling pointer on mgmt_add_adv_patterns_monitor_complete Bluetooth: SCO: Fix use-after-free in sco_recv_frame() due to missing sock_hold Bluetooth: L2CAP: Validate PDU length before reading SDU length in l2cap_ecred_data_rcv() Bluetooth: L2CAP: Fix stack-out-of-bounds read in l2cap_ecred_conn_req ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents cbcb3cf + 761fb8e commit 57ce3b2

9 files changed

Lines changed: 60 additions & 22 deletions

File tree

drivers/bluetooth/hci_ll.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,8 @@ static int download_firmware(struct ll_device *lldev)
541541
if (err || !fw->data || !fw->size) {
542542
bt_dev_err(lldev->hu.hdev, "request_firmware failed(errno %d) for %s",
543543
err, bts_scr_name);
544+
if (!err)
545+
release_firmware(fw);
544546
return -EINVAL;
545547
}
546548
ptr = (void *)fw->data;

include/net/bluetooth/l2cap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,7 @@ struct l2cap_conn {
658658
struct sk_buff *rx_skb;
659659
__u32 rx_len;
660660
struct ida tx_ida;
661+
__u8 tx_ident;
661662

662663
struct sk_buff_head pending_rx;
663664
struct work_struct pending_rx_work;

net/bluetooth/hci_conn.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3095,7 +3095,7 @@ int hci_abort_conn(struct hci_conn *conn, u8 reason)
30953095
* hci_connect_le serializes the connection attempts so only one
30963096
* connection can be in BT_CONNECT at time.
30973097
*/
3098-
if (conn->state == BT_CONNECT && hdev->req_status == HCI_REQ_PEND) {
3098+
if (conn->state == BT_CONNECT && READ_ONCE(hdev->req_status) == HCI_REQ_PEND) {
30993099
switch (hci_skb_event(hdev->sent_cmd)) {
31003100
case HCI_EV_CONN_COMPLETE:
31013101
case HCI_EV_LE_CONN_COMPLETE:

net/bluetooth/hci_core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4126,7 +4126,7 @@ static int hci_send_cmd_sync(struct hci_dev *hdev, struct sk_buff *skb)
41264126
kfree_skb(skb);
41274127
}
41284128

4129-
if (hdev->req_status == HCI_REQ_PEND &&
4129+
if (READ_ONCE(hdev->req_status) == HCI_REQ_PEND &&
41304130
!hci_dev_test_and_set_flag(hdev, HCI_CMD_PENDING)) {
41314131
kfree_skb(hdev->req_skb);
41324132
hdev->req_skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);

net/bluetooth/hci_sync.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ static void hci_cmd_sync_complete(struct hci_dev *hdev, u8 result, u16 opcode,
2525
{
2626
bt_dev_dbg(hdev, "result 0x%2.2x", result);
2727

28-
if (hdev->req_status != HCI_REQ_PEND)
28+
if (READ_ONCE(hdev->req_status) != HCI_REQ_PEND)
2929
return;
3030

3131
hdev->req_result = result;
32-
hdev->req_status = HCI_REQ_DONE;
32+
WRITE_ONCE(hdev->req_status, HCI_REQ_DONE);
3333

3434
/* Free the request command so it is not used as response */
3535
kfree_skb(hdev->req_skb);
@@ -167,20 +167,20 @@ struct sk_buff *__hci_cmd_sync_sk(struct hci_dev *hdev, u16 opcode, u32 plen,
167167

168168
hci_cmd_sync_add(&req, opcode, plen, param, event, sk);
169169

170-
hdev->req_status = HCI_REQ_PEND;
170+
WRITE_ONCE(hdev->req_status, HCI_REQ_PEND);
171171

172172
err = hci_req_sync_run(&req);
173173
if (err < 0)
174174
return ERR_PTR(err);
175175

176176
err = wait_event_interruptible_timeout(hdev->req_wait_q,
177-
hdev->req_status != HCI_REQ_PEND,
177+
READ_ONCE(hdev->req_status) != HCI_REQ_PEND,
178178
timeout);
179179

180180
if (err == -ERESTARTSYS)
181181
return ERR_PTR(-EINTR);
182182

183-
switch (hdev->req_status) {
183+
switch (READ_ONCE(hdev->req_status)) {
184184
case HCI_REQ_DONE:
185185
err = -bt_to_errno(hdev->req_result);
186186
break;
@@ -194,7 +194,7 @@ struct sk_buff *__hci_cmd_sync_sk(struct hci_dev *hdev, u16 opcode, u32 plen,
194194
break;
195195
}
196196

197-
hdev->req_status = 0;
197+
WRITE_ONCE(hdev->req_status, 0);
198198
hdev->req_result = 0;
199199
skb = hdev->req_rsp;
200200
hdev->req_rsp = NULL;
@@ -665,9 +665,9 @@ void hci_cmd_sync_cancel(struct hci_dev *hdev, int err)
665665
{
666666
bt_dev_dbg(hdev, "err 0x%2.2x", err);
667667

668-
if (hdev->req_status == HCI_REQ_PEND) {
668+
if (READ_ONCE(hdev->req_status) == HCI_REQ_PEND) {
669669
hdev->req_result = err;
670-
hdev->req_status = HCI_REQ_CANCELED;
670+
WRITE_ONCE(hdev->req_status, HCI_REQ_CANCELED);
671671

672672
queue_work(hdev->workqueue, &hdev->cmd_sync_cancel_work);
673673
}
@@ -683,12 +683,12 @@ void hci_cmd_sync_cancel_sync(struct hci_dev *hdev, int err)
683683
{
684684
bt_dev_dbg(hdev, "err 0x%2.2x", err);
685685

686-
if (hdev->req_status == HCI_REQ_PEND) {
686+
if (READ_ONCE(hdev->req_status) == HCI_REQ_PEND) {
687687
/* req_result is __u32 so error must be positive to be properly
688688
* propagated.
689689
*/
690690
hdev->req_result = err < 0 ? -err : err;
691-
hdev->req_status = HCI_REQ_CANCELED;
691+
WRITE_ONCE(hdev->req_status, HCI_REQ_CANCELED);
692692

693693
wake_up_interruptible(&hdev->req_wait_q);
694694
}

net/bluetooth/l2cap_core.c

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -926,16 +926,39 @@ int l2cap_chan_check_security(struct l2cap_chan *chan, bool initiator)
926926

927927
static int l2cap_get_ident(struct l2cap_conn *conn)
928928
{
929+
u8 max;
930+
int ident;
931+
929932
/* LE link does not support tools like l2ping so use the full range */
930933
if (conn->hcon->type == LE_LINK)
931-
return ida_alloc_range(&conn->tx_ida, 1, 255, GFP_ATOMIC);
932-
934+
max = 255;
933935
/* Get next available identificator.
934936
* 1 - 128 are used by kernel.
935937
* 129 - 199 are reserved.
936938
* 200 - 254 are used by utilities like l2ping, etc.
937939
*/
938-
return ida_alloc_range(&conn->tx_ida, 1, 128, GFP_ATOMIC);
940+
else
941+
max = 128;
942+
943+
/* Allocate ident using min as last used + 1 (cyclic) */
944+
ident = ida_alloc_range(&conn->tx_ida, READ_ONCE(conn->tx_ident) + 1,
945+
max, GFP_ATOMIC);
946+
/* Force min 1 to start over */
947+
if (ident <= 0) {
948+
ident = ida_alloc_range(&conn->tx_ida, 1, max, GFP_ATOMIC);
949+
if (ident <= 0) {
950+
/* If all idents are in use, log an error, this is
951+
* extremely unlikely to happen and would indicate a bug
952+
* in the code that idents are not being freed properly.
953+
*/
954+
BT_ERR("Unable to allocate ident: %d", ident);
955+
return 0;
956+
}
957+
}
958+
959+
WRITE_ONCE(conn->tx_ident, ident);
960+
961+
return ident;
939962
}
940963

941964
static void l2cap_send_acl(struct l2cap_conn *conn, struct sk_buff *skb,
@@ -5081,14 +5104,14 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
50815104
cmd_len -= sizeof(*req);
50825105
num_scid = cmd_len / sizeof(u16);
50835106

5084-
/* Always respond with the same number of scids as in the request */
5085-
rsp_len = cmd_len;
5086-
50875107
if (num_scid > L2CAP_ECRED_MAX_CID) {
50885108
result = L2CAP_CR_LE_INVALID_PARAMS;
50895109
goto response;
50905110
}
50915111

5112+
/* Always respond with the same number of scids as in the request */
5113+
rsp_len = cmd_len;
5114+
50925115
mtu = __le16_to_cpu(req->mtu);
50935116
mps = __le16_to_cpu(req->mps);
50945117

@@ -6690,6 +6713,11 @@ static int l2cap_ecred_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
66906713
if (!chan->sdu) {
66916714
u16 sdu_len;
66926715

6716+
if (!pskb_may_pull(skb, L2CAP_SDULEN_SIZE)) {
6717+
err = -EINVAL;
6718+
goto failed;
6719+
}
6720+
66936721
sdu_len = get_unaligned_le16(skb->data);
66946722
skb_pull(skb, L2CAP_SDULEN_SIZE);
66956723

net/bluetooth/l2cap_sock.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1698,6 +1698,9 @@ static void l2cap_sock_ready_cb(struct l2cap_chan *chan)
16981698
struct sock *sk = chan->data;
16991699
struct sock *parent;
17001700

1701+
if (!sk)
1702+
return;
1703+
17011704
lock_sock(sk);
17021705

17031706
parent = bt_sk(sk)->parent;

net/bluetooth/mgmt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5355,7 +5355,7 @@ static void mgmt_add_adv_patterns_monitor_complete(struct hci_dev *hdev,
53555355
* hci_adv_monitors_clear is about to be called which will take care of
53565356
* freeing the adv_monitor instances.
53575357
*/
5358-
if (status == -ECANCELED && !mgmt_pending_valid(hdev, cmd))
5358+
if (status == -ECANCELED || !mgmt_pending_valid(hdev, cmd))
53595359
return;
53605360

53615361
monitor = cmd->user_data;

net/bluetooth/sco.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ static void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb)
401401
struct sock *sk;
402402

403403
sco_conn_lock(conn);
404-
sk = conn->sk;
404+
sk = sco_sock_hold(conn);
405405
sco_conn_unlock(conn);
406406

407407
if (!sk)
@@ -410,11 +410,15 @@ static void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb)
410410
BT_DBG("sk %p len %u", sk, skb->len);
411411

412412
if (sk->sk_state != BT_CONNECTED)
413-
goto drop;
413+
goto drop_put;
414414

415-
if (!sock_queue_rcv_skb(sk, skb))
415+
if (!sock_queue_rcv_skb(sk, skb)) {
416+
sock_put(sk);
416417
return;
418+
}
417419

420+
drop_put:
421+
sock_put(sk);
418422
drop:
419423
kfree_skb(skb);
420424
}

0 commit comments

Comments
 (0)