Skip to content

Commit 3491bb7

Browse files
committed
Merge tag 'for-net-2025-09-22' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth
Luiz Augusto von Dentz says: ==================== bluetooth pull request for net: - Fix build after header cleanup - hci_sync: Fix hci_resume_advertising_sync - hci_event: Fix UAF in hci_conn_tx_dequeue - hci_event: Fix UAF in hci_acl_create_conn_sync - MGMT: Fix possible UAFs * tag 'for-net-2025-09-22' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth: Bluetooth: MGMT: Fix possible UAFs Bluetooth: hci_event: Fix UAF in hci_acl_create_conn_sync Bluetooth: hci_event: Fix UAF in hci_conn_tx_dequeue Bluetooth: hci_sync: Fix hci_resume_advertising_sync Bluetooth: Fix build after header cleanup ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 207b45e + 302a1f6 commit 3491bb7

File tree

8 files changed

+296
-84
lines changed

8 files changed

+296
-84
lines changed

drivers/bluetooth/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,9 @@ config BT_HCIBCM4377
312312

313313
config BT_HCIBPA10X
314314
tristate "HCI BPA10x USB driver"
315+
depends on BT_HCIUART
315316
depends on USB
317+
select BT_HCIUART_H4
316318
help
317319
Bluetooth HCI BPA10x USB driver.
318320
This driver provides support for the Digianswer BPA 100/105 Bluetooth
@@ -437,8 +439,10 @@ config BT_MTKSDIO
437439

438440
config BT_MTKUART
439441
tristate "MediaTek HCI UART driver"
442+
depends on BT_HCIUART
440443
depends on SERIAL_DEV_BUS
441444
depends on USB || !BT_HCIBTUSB_MTK
445+
select BT_HCIUART_H4
442446
select BT_MTK
443447
help
444448
MediaTek Bluetooth HCI UART driver.
@@ -483,7 +487,9 @@ config BT_VIRTIO
483487

484488
config BT_NXPUART
485489
tristate "NXP protocol support"
490+
depends on BT_HCIUART
486491
depends on SERIAL_DEV_BUS
492+
select BT_HCIUART_H4
487493
select CRC32
488494
select CRC8
489495
help

drivers/bluetooth/hci_uart.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,6 @@ void hci_uart_set_flow_control(struct hci_uart *hu, bool enable);
121121
void hci_uart_set_speeds(struct hci_uart *hu, unsigned int init_speed,
122122
unsigned int oper_speed);
123123

124-
#ifdef CONFIG_BT_HCIUART_H4
125-
int h4_init(void);
126-
int h4_deinit(void);
127-
128124
struct h4_recv_pkt {
129125
u8 type; /* Packet type */
130126
u8 hlen; /* Header length */
@@ -162,6 +158,10 @@ struct h4_recv_pkt {
162158
.lsize = 2, \
163159
.maxlen = HCI_MAX_FRAME_SIZE \
164160

161+
#ifdef CONFIG_BT_HCIUART_H4
162+
int h4_init(void);
163+
int h4_deinit(void);
164+
165165
struct sk_buff *h4_recv_buf(struct hci_dev *hdev, struct sk_buff *skb,
166166
const unsigned char *buffer, int count,
167167
const struct h4_recv_pkt *pkts, int pkts_count);

include/net/bluetooth/hci_core.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,6 +1245,27 @@ static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev,
12451245
return NULL;
12461246
}
12471247

1248+
static inline struct hci_conn *hci_conn_hash_lookup_role(struct hci_dev *hdev,
1249+
__u8 type, __u8 role,
1250+
bdaddr_t *ba)
1251+
{
1252+
struct hci_conn_hash *h = &hdev->conn_hash;
1253+
struct hci_conn *c;
1254+
1255+
rcu_read_lock();
1256+
1257+
list_for_each_entry_rcu(c, &h->list, list) {
1258+
if (c->type == type && c->role == role && !bacmp(&c->dst, ba)) {
1259+
rcu_read_unlock();
1260+
return c;
1261+
}
1262+
}
1263+
1264+
rcu_read_unlock();
1265+
1266+
return NULL;
1267+
}
1268+
12481269
static inline struct hci_conn *hci_conn_hash_lookup_le(struct hci_dev *hdev,
12491270
bdaddr_t *ba,
12501271
__u8 ba_type)

net/bluetooth/hci_event.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3087,8 +3087,18 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
30873087

30883088
hci_dev_lock(hdev);
30893089

3090+
/* Check for existing connection:
3091+
*
3092+
* 1. If it doesn't exist then it must be receiver/slave role.
3093+
* 2. If it does exist confirm that it is connecting/BT_CONNECT in case
3094+
* of initiator/master role since there could be a collision where
3095+
* either side is attempting to connect or something like a fuzzing
3096+
* testing is trying to play tricks to destroy the hcon object before
3097+
* it even attempts to connect (e.g. hcon->state == BT_OPEN).
3098+
*/
30903099
conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
3091-
if (!conn) {
3100+
if (!conn ||
3101+
(conn->role == HCI_ROLE_MASTER && conn->state != BT_CONNECT)) {
30923102
/* In case of error status and there is no connection pending
30933103
* just unlock as there is nothing to cleanup.
30943104
*/
@@ -4391,6 +4401,8 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data,
43914401

43924402
bt_dev_dbg(hdev, "num %d", ev->num);
43934403

4404+
hci_dev_lock(hdev);
4405+
43944406
for (i = 0; i < ev->num; i++) {
43954407
struct hci_comp_pkts_info *info = &ev->handles[i];
43964408
struct hci_conn *conn;
@@ -4472,6 +4484,8 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data,
44724484
}
44734485

44744486
queue_work(hdev->workqueue, &hdev->tx_work);
4487+
4488+
hci_dev_unlock(hdev);
44754489
}
44764490

44774491
static void hci_mode_change_evt(struct hci_dev *hdev, void *data,
@@ -5634,8 +5648,18 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
56345648
*/
56355649
hci_dev_clear_flag(hdev, HCI_LE_ADV);
56365650

5637-
conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, bdaddr);
5638-
if (!conn) {
5651+
/* Check for existing connection:
5652+
*
5653+
* 1. If it doesn't exist then use the role to create a new object.
5654+
* 2. If it does exist confirm that it is connecting/BT_CONNECT in case
5655+
* of initiator/master role since there could be a collision where
5656+
* either side is attempting to connect or something like a fuzzing
5657+
* testing is trying to play tricks to destroy the hcon object before
5658+
* it even attempts to connect (e.g. hcon->state == BT_OPEN).
5659+
*/
5660+
conn = hci_conn_hash_lookup_role(hdev, LE_LINK, role, bdaddr);
5661+
if (!conn ||
5662+
(conn->role == HCI_ROLE_MASTER && conn->state != BT_CONNECT)) {
56395663
/* In case of error status and there is no connection pending
56405664
* just unlock as there is nothing to cleanup.
56415665
*/

net/bluetooth/hci_sync.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2594,6 +2594,13 @@ static int hci_resume_advertising_sync(struct hci_dev *hdev)
25942594
hci_remove_ext_adv_instance_sync(hdev, adv->instance,
25952595
NULL);
25962596
}
2597+
2598+
/* If current advertising instance is set to instance 0x00
2599+
* then we need to re-enable it.
2600+
*/
2601+
if (!hdev->cur_adv_instance)
2602+
err = hci_enable_ext_advertising_sync(hdev,
2603+
hdev->cur_adv_instance);
25972604
} else {
25982605
/* Schedule for most recent instance to be restarted and begin
25992606
* the software rotation loop

0 commit comments

Comments
 (0)