Skip to content

Commit c39b1bb

Browse files
committed
Merge tag 'for-net-2025-05-15' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth
Luiz Augusto von Dentz says: ==================== bluetooth pull request for net: - btusb: use skb_pull to avoid unsafe access in QCA dump handling - L2CAP: Fix not checking l2cap_chan security level * tag 'for-net-2025-05-15' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth: Bluetooth: btusb: use skb_pull to avoid unsafe access in QCA dump handling Bluetooth: L2CAP: Fix not checking l2cap_chan security level ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents ef93565 + 4bcb0c7 commit c39b1bb

File tree

2 files changed

+48
-65
lines changed

2 files changed

+48
-65
lines changed

drivers/bluetooth/btusb.c

Lines changed: 40 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -3014,9 +3014,8 @@ static void btusb_coredump_qca(struct hci_dev *hdev)
30143014
static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb)
30153015
{
30163016
int ret = 0;
3017+
unsigned int skip = 0;
30173018
u8 pkt_type;
3018-
u8 *sk_ptr;
3019-
unsigned int sk_len;
30203019
u16 seqno;
30213020
u32 dump_size;
30223021

@@ -3025,18 +3024,13 @@ static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb)
30253024
struct usb_device *udev = btdata->udev;
30263025

30273026
pkt_type = hci_skb_pkt_type(skb);
3028-
sk_ptr = skb->data;
3029-
sk_len = skb->len;
3027+
skip = sizeof(struct hci_event_hdr);
3028+
if (pkt_type == HCI_ACLDATA_PKT)
3029+
skip += sizeof(struct hci_acl_hdr);
30303030

3031-
if (pkt_type == HCI_ACLDATA_PKT) {
3032-
sk_ptr += HCI_ACL_HDR_SIZE;
3033-
sk_len -= HCI_ACL_HDR_SIZE;
3034-
}
3035-
3036-
sk_ptr += HCI_EVENT_HDR_SIZE;
3037-
sk_len -= HCI_EVENT_HDR_SIZE;
3031+
skb_pull(skb, skip);
3032+
dump_hdr = (struct qca_dump_hdr *)skb->data;
30383033

3039-
dump_hdr = (struct qca_dump_hdr *)sk_ptr;
30403034
seqno = le16_to_cpu(dump_hdr->seqno);
30413035
if (seqno == 0) {
30423036
set_bit(BTUSB_HW_SSR_ACTIVE, &btdata->flags);
@@ -3056,16 +3050,15 @@ static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb)
30563050

30573051
btdata->qca_dump.ram_dump_size = dump_size;
30583052
btdata->qca_dump.ram_dump_seqno = 0;
3059-
sk_ptr += offsetof(struct qca_dump_hdr, data0);
3060-
sk_len -= offsetof(struct qca_dump_hdr, data0);
3053+
3054+
skb_pull(skb, offsetof(struct qca_dump_hdr, data0));
30613055

30623056
usb_disable_autosuspend(udev);
30633057
bt_dev_info(hdev, "%s memdump size(%u)\n",
30643058
(pkt_type == HCI_ACLDATA_PKT) ? "ACL" : "event",
30653059
dump_size);
30663060
} else {
3067-
sk_ptr += offsetof(struct qca_dump_hdr, data);
3068-
sk_len -= offsetof(struct qca_dump_hdr, data);
3061+
skb_pull(skb, offsetof(struct qca_dump_hdr, data));
30693062
}
30703063

30713064
if (!btdata->qca_dump.ram_dump_size) {
@@ -3085,7 +3078,6 @@ static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb)
30853078
return ret;
30863079
}
30873080

3088-
skb_pull(skb, skb->len - sk_len);
30893081
hci_devcd_append(hdev, skb);
30903082
btdata->qca_dump.ram_dump_seqno++;
30913083
if (seqno == QCA_LAST_SEQUENCE_NUM) {
@@ -3113,68 +3105,58 @@ static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb)
31133105
/* Return: true if the ACL packet is a dump packet, false otherwise. */
31143106
static bool acl_pkt_is_dump_qca(struct hci_dev *hdev, struct sk_buff *skb)
31153107
{
3116-
u8 *sk_ptr;
3117-
unsigned int sk_len;
3118-
31193108
struct hci_event_hdr *event_hdr;
31203109
struct hci_acl_hdr *acl_hdr;
31213110
struct qca_dump_hdr *dump_hdr;
3111+
struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC);
3112+
bool is_dump = false;
31223113

3123-
sk_ptr = skb->data;
3124-
sk_len = skb->len;
3125-
3126-
acl_hdr = hci_acl_hdr(skb);
3127-
if (le16_to_cpu(acl_hdr->handle) != QCA_MEMDUMP_ACL_HANDLE)
3114+
if (!clone)
31283115
return false;
31293116

3130-
sk_ptr += HCI_ACL_HDR_SIZE;
3131-
sk_len -= HCI_ACL_HDR_SIZE;
3132-
event_hdr = (struct hci_event_hdr *)sk_ptr;
3133-
3134-
if ((event_hdr->evt != HCI_VENDOR_PKT) ||
3135-
(event_hdr->plen != (sk_len - HCI_EVENT_HDR_SIZE)))
3136-
return false;
3117+
acl_hdr = skb_pull_data(clone, sizeof(*acl_hdr));
3118+
if (!acl_hdr || (le16_to_cpu(acl_hdr->handle) != QCA_MEMDUMP_ACL_HANDLE))
3119+
goto out;
31373120

3138-
sk_ptr += HCI_EVENT_HDR_SIZE;
3139-
sk_len -= HCI_EVENT_HDR_SIZE;
3121+
event_hdr = skb_pull_data(clone, sizeof(*event_hdr));
3122+
if (!event_hdr || (event_hdr->evt != HCI_VENDOR_PKT))
3123+
goto out;
31403124

3141-
dump_hdr = (struct qca_dump_hdr *)sk_ptr;
3142-
if ((sk_len < offsetof(struct qca_dump_hdr, data)) ||
3143-
(dump_hdr->vse_class != QCA_MEMDUMP_VSE_CLASS) ||
3144-
(dump_hdr->msg_type != QCA_MEMDUMP_MSG_TYPE))
3145-
return false;
3125+
dump_hdr = skb_pull_data(clone, sizeof(*dump_hdr));
3126+
if (!dump_hdr || (dump_hdr->vse_class != QCA_MEMDUMP_VSE_CLASS) ||
3127+
(dump_hdr->msg_type != QCA_MEMDUMP_MSG_TYPE))
3128+
goto out;
31463129

3147-
return true;
3130+
is_dump = true;
3131+
out:
3132+
consume_skb(clone);
3133+
return is_dump;
31483134
}
31493135

31503136
/* Return: true if the event packet is a dump packet, false otherwise. */
31513137
static bool evt_pkt_is_dump_qca(struct hci_dev *hdev, struct sk_buff *skb)
31523138
{
3153-
u8 *sk_ptr;
3154-
unsigned int sk_len;
3155-
31563139
struct hci_event_hdr *event_hdr;
31573140
struct qca_dump_hdr *dump_hdr;
3141+
struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC);
3142+
bool is_dump = false;
31583143

3159-
sk_ptr = skb->data;
3160-
sk_len = skb->len;
3161-
3162-
event_hdr = hci_event_hdr(skb);
3163-
3164-
if ((event_hdr->evt != HCI_VENDOR_PKT)
3165-
|| (event_hdr->plen != (sk_len - HCI_EVENT_HDR_SIZE)))
3144+
if (!clone)
31663145
return false;
31673146

3168-
sk_ptr += HCI_EVENT_HDR_SIZE;
3169-
sk_len -= HCI_EVENT_HDR_SIZE;
3147+
event_hdr = skb_pull_data(clone, sizeof(*event_hdr));
3148+
if (!event_hdr || (event_hdr->evt != HCI_VENDOR_PKT))
3149+
goto out;
31703150

3171-
dump_hdr = (struct qca_dump_hdr *)sk_ptr;
3172-
if ((sk_len < offsetof(struct qca_dump_hdr, data)) ||
3173-
(dump_hdr->vse_class != QCA_MEMDUMP_VSE_CLASS) ||
3174-
(dump_hdr->msg_type != QCA_MEMDUMP_MSG_TYPE))
3175-
return false;
3151+
dump_hdr = skb_pull_data(clone, sizeof(*dump_hdr));
3152+
if (!dump_hdr || (dump_hdr->vse_class != QCA_MEMDUMP_VSE_CLASS) ||
3153+
(dump_hdr->msg_type != QCA_MEMDUMP_MSG_TYPE))
3154+
goto out;
31763155

3177-
return true;
3156+
is_dump = true;
3157+
out:
3158+
consume_skb(clone);
3159+
return is_dump;
31783160
}
31793161

31803162
static int btusb_recv_acl_qca(struct hci_dev *hdev, struct sk_buff *skb)

net/bluetooth/l2cap_core.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,7 +1411,8 @@ static void l2cap_request_info(struct l2cap_conn *conn)
14111411
sizeof(req), &req);
14121412
}
14131413

1414-
static bool l2cap_check_enc_key_size(struct hci_conn *hcon)
1414+
static bool l2cap_check_enc_key_size(struct hci_conn *hcon,
1415+
struct l2cap_chan *chan)
14151416
{
14161417
/* The minimum encryption key size needs to be enforced by the
14171418
* host stack before establishing any L2CAP connections. The
@@ -1425,7 +1426,7 @@ static bool l2cap_check_enc_key_size(struct hci_conn *hcon)
14251426
int min_key_size = hcon->hdev->min_enc_key_size;
14261427

14271428
/* On FIPS security level, key size must be 16 bytes */
1428-
if (hcon->sec_level == BT_SECURITY_FIPS)
1429+
if (chan->sec_level == BT_SECURITY_FIPS)
14291430
min_key_size = 16;
14301431

14311432
return (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags) ||
@@ -1453,7 +1454,7 @@ static void l2cap_do_start(struct l2cap_chan *chan)
14531454
!__l2cap_no_conn_pending(chan))
14541455
return;
14551456

1456-
if (l2cap_check_enc_key_size(conn->hcon))
1457+
if (l2cap_check_enc_key_size(conn->hcon, chan))
14571458
l2cap_start_connection(chan);
14581459
else
14591460
__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
@@ -1528,7 +1529,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
15281529
continue;
15291530
}
15301531

1531-
if (l2cap_check_enc_key_size(conn->hcon))
1532+
if (l2cap_check_enc_key_size(conn->hcon, chan))
15321533
l2cap_start_connection(chan);
15331534
else
15341535
l2cap_chan_close(chan, ECONNREFUSED);
@@ -3992,7 +3993,7 @@ static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
39923993
/* Check if the ACL is secure enough (if not SDP) */
39933994
if (psm != cpu_to_le16(L2CAP_PSM_SDP) &&
39943995
(!hci_conn_check_link_mode(conn->hcon) ||
3995-
!l2cap_check_enc_key_size(conn->hcon))) {
3996+
!l2cap_check_enc_key_size(conn->hcon, pchan))) {
39963997
conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
39973998
result = L2CAP_CR_SEC_BLOCK;
39983999
goto response;
@@ -7352,7 +7353,7 @@ static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
73527353
}
73537354

73547355
if (chan->state == BT_CONNECT) {
7355-
if (!status && l2cap_check_enc_key_size(hcon))
7356+
if (!status && l2cap_check_enc_key_size(hcon, chan))
73567357
l2cap_start_connection(chan);
73577358
else
73587359
__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
@@ -7362,7 +7363,7 @@ static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
73627363
struct l2cap_conn_rsp rsp;
73637364
__u16 res, stat;
73647365

7365-
if (!status && l2cap_check_enc_key_size(hcon)) {
7366+
if (!status && l2cap_check_enc_key_size(hcon, chan)) {
73667367
if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
73677368
res = L2CAP_CR_PEND;
73687369
stat = L2CAP_CS_AUTHOR_PEND;

0 commit comments

Comments
 (0)