Skip to content

Commit 6d6be70

Browse files
committed
Merge tag 'for-net-2026-04-01' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth
Luiz Augusto von Dentz says: ==================== bluetooth pull request for net: - hci_sync: Fix UAF in le_read_features_complete - hci_sync: call destroy in hci_cmd_sync_run if immediate - hci_sync: hci_cmd_sync_queue_once() return -EEXIST if exists - hci_sync: fix leaks when hci_cmd_sync_queue_once fails - hci_sync: fix stack buffer overflow in hci_le_big_create_sync - hci_conn: fix potential UAF in set_cig_params_sync - hci_event: fix potential UAF in hci_le_remote_conn_param_req_evt - hci_event: move wake reason storage into validated event handlers - SMP: force responder MITM requirements before building the pairing response - SMP: derive legacy responder STK authentication from MITM state - MGMT: validate LTK enc_size on load - MGMT: validate mesh send advertising payload length - SCO: fix race conditions in sco_sock_connect() - hci_h4: Fix race during initialization * tag 'for-net-2026-04-01' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth: Bluetooth: hci_sync: fix stack buffer overflow in hci_le_big_create_sync Bluetooth: SMP: derive legacy responder STK authentication from MITM state Bluetooth: SMP: force responder MITM requirements before building the pairing response Bluetooth: MGMT: validate mesh send advertising payload length Bluetooth: hci_event: fix potential UAF in hci_le_remote_conn_param_req_evt Bluetooth: hci_conn: fix potential UAF in set_cig_params_sync Bluetooth: MGMT: validate LTK enc_size on load Bluetooth: hci_h4: Fix race during initialization Bluetooth: hci_sync: Fix UAF in le_read_features_complete Bluetooth: hci_sync: fix leaks when hci_cmd_sync_queue_once fails Bluetooth: hci_sync: hci_cmd_sync_queue_once() return -EEXIST if exists Bluetooth: hci_event: move wake reason storage into validated event handlers Bluetooth: SCO: fix race conditions in sco_sock_connect() Bluetooth: hci_sync: call destroy in hci_cmd_sync_run if immediate ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents a54eccc + bc39a09 commit 6d6be70

7 files changed

Lines changed: 165 additions & 115 deletions

File tree

drivers/bluetooth/hci_h4.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,6 @@ static int h4_recv(struct hci_uart *hu, const void *data, int count)
109109
{
110110
struct h4_struct *h4 = hu->priv;
111111

112-
if (!test_bit(HCI_UART_REGISTERED, &hu->flags))
113-
return -EUNATCH;
114-
115112
h4->rx_skb = h4_recv_buf(hu, h4->rx_skb, data, count,
116113
h4_recv_pkts, ARRAY_SIZE(h4_recv_pkts));
117114
if (IS_ERR(h4->rx_skb)) {

net/bluetooth/hci_conn.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1843,9 +1843,13 @@ static int set_cig_params_sync(struct hci_dev *hdev, void *data)
18431843
u8 aux_num_cis = 0;
18441844
u8 cis_id;
18451845

1846+
hci_dev_lock(hdev);
1847+
18461848
conn = hci_conn_hash_lookup_cig(hdev, cig_id);
1847-
if (!conn)
1849+
if (!conn) {
1850+
hci_dev_unlock(hdev);
18481851
return 0;
1852+
}
18491853

18501854
qos = &conn->iso_qos;
18511855
pdu->cig_id = cig_id;
@@ -1884,6 +1888,8 @@ static int set_cig_params_sync(struct hci_dev *hdev, void *data)
18841888
}
18851889
pdu->num_cis = aux_num_cis;
18861890

1891+
hci_dev_unlock(hdev);
1892+
18871893
if (!pdu->num_cis)
18881894
return 0;
18891895

net/bluetooth/hci_event.c

Lines changed: 55 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ static void *hci_le_ev_skb_pull(struct hci_dev *hdev, struct sk_buff *skb,
8080
return data;
8181
}
8282

83+
static void hci_store_wake_reason(struct hci_dev *hdev,
84+
const bdaddr_t *bdaddr, u8 addr_type)
85+
__must_hold(&hdev->lock);
86+
8387
static u8 hci_cc_inquiry_cancel(struct hci_dev *hdev, void *data,
8488
struct sk_buff *skb)
8589
{
@@ -3111,6 +3115,7 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
31113115
bt_dev_dbg(hdev, "status 0x%2.2x", status);
31123116

31133117
hci_dev_lock(hdev);
3118+
hci_store_wake_reason(hdev, &ev->bdaddr, BDADDR_BREDR);
31143119

31153120
/* Check for existing connection:
31163121
*
@@ -3274,6 +3279,10 @@ static void hci_conn_request_evt(struct hci_dev *hdev, void *data,
32743279

32753280
bt_dev_dbg(hdev, "bdaddr %pMR type 0x%x", &ev->bdaddr, ev->link_type);
32763281

3282+
hci_dev_lock(hdev);
3283+
hci_store_wake_reason(hdev, &ev->bdaddr, BDADDR_BREDR);
3284+
hci_dev_unlock(hdev);
3285+
32773286
/* Reject incoming connection from device with same BD ADDR against
32783287
* CVE-2020-26555
32793288
*/
@@ -5021,6 +5030,7 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data,
50215030
bt_dev_dbg(hdev, "status 0x%2.2x", status);
50225031

50235032
hci_dev_lock(hdev);
5033+
hci_store_wake_reason(hdev, &ev->bdaddr, BDADDR_BREDR);
50245034

50255035
conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
50265036
if (!conn) {
@@ -5713,6 +5723,7 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
57135723
int err;
57145724

57155725
hci_dev_lock(hdev);
5726+
hci_store_wake_reason(hdev, bdaddr, bdaddr_type);
57165727

57175728
/* All controllers implicitly stop advertising in the event of a
57185729
* connection, so ensure that the state bit is cleared.
@@ -6005,6 +6016,7 @@ static void hci_le_past_received_evt(struct hci_dev *hdev, void *data,
60056016
bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
60066017

60076018
hci_dev_lock(hdev);
6019+
hci_store_wake_reason(hdev, &ev->bdaddr, ev->bdaddr_type);
60086020

60096021
hci_dev_clear_flag(hdev, HCI_PA_SYNC);
60106022

@@ -6403,6 +6415,8 @@ static void hci_le_adv_report_evt(struct hci_dev *hdev, void *data,
64036415
info->length + 1))
64046416
break;
64056417

6418+
hci_store_wake_reason(hdev, &info->bdaddr, info->bdaddr_type);
6419+
64066420
if (info->length <= max_adv_len(hdev)) {
64076421
rssi = info->data[info->length];
64086422
process_adv_report(hdev, info->type, &info->bdaddr,
@@ -6491,6 +6505,8 @@ static void hci_le_ext_adv_report_evt(struct hci_dev *hdev, void *data,
64916505
info->length))
64926506
break;
64936507

6508+
hci_store_wake_reason(hdev, &info->bdaddr, info->bdaddr_type);
6509+
64946510
evt_type = __le16_to_cpu(info->type) & LE_EXT_ADV_EVT_TYPE_MASK;
64956511
legacy_evt_type = ext_evt_type_to_legacy(hdev, evt_type);
64966512

@@ -6536,6 +6552,7 @@ static void hci_le_pa_sync_established_evt(struct hci_dev *hdev, void *data,
65366552
bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
65376553

65386554
hci_dev_lock(hdev);
6555+
hci_store_wake_reason(hdev, &ev->bdaddr, ev->bdaddr_type);
65396556

65406557
hci_dev_clear_flag(hdev, HCI_PA_SYNC);
65416558

@@ -6767,25 +6784,31 @@ static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev, void *data,
67676784
latency = le16_to_cpu(ev->latency);
67686785
timeout = le16_to_cpu(ev->timeout);
67696786

6787+
hci_dev_lock(hdev);
6788+
67706789
hcon = hci_conn_hash_lookup_handle(hdev, handle);
6771-
if (!hcon || hcon->state != BT_CONNECTED)
6772-
return send_conn_param_neg_reply(hdev, handle,
6773-
HCI_ERROR_UNKNOWN_CONN_ID);
6790+
if (!hcon || hcon->state != BT_CONNECTED) {
6791+
send_conn_param_neg_reply(hdev, handle,
6792+
HCI_ERROR_UNKNOWN_CONN_ID);
6793+
goto unlock;
6794+
}
67746795

6775-
if (max > hcon->le_conn_max_interval)
6776-
return send_conn_param_neg_reply(hdev, handle,
6777-
HCI_ERROR_INVALID_LL_PARAMS);
6796+
if (max > hcon->le_conn_max_interval) {
6797+
send_conn_param_neg_reply(hdev, handle,
6798+
HCI_ERROR_INVALID_LL_PARAMS);
6799+
goto unlock;
6800+
}
67786801

6779-
if (hci_check_conn_params(min, max, latency, timeout))
6780-
return send_conn_param_neg_reply(hdev, handle,
6781-
HCI_ERROR_INVALID_LL_PARAMS);
6802+
if (hci_check_conn_params(min, max, latency, timeout)) {
6803+
send_conn_param_neg_reply(hdev, handle,
6804+
HCI_ERROR_INVALID_LL_PARAMS);
6805+
goto unlock;
6806+
}
67826807

67836808
if (hcon->role == HCI_ROLE_MASTER) {
67846809
struct hci_conn_params *params;
67856810
u8 store_hint;
67866811

6787-
hci_dev_lock(hdev);
6788-
67896812
params = hci_conn_params_lookup(hdev, &hcon->dst,
67906813
hcon->dst_type);
67916814
if (params) {
@@ -6798,8 +6821,6 @@ static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev, void *data,
67986821
store_hint = 0x00;
67996822
}
68006823

6801-
hci_dev_unlock(hdev);
6802-
68036824
mgmt_new_conn_param(hdev, &hcon->dst, hcon->dst_type,
68046825
store_hint, min, max, latency, timeout);
68056826
}
@@ -6813,6 +6834,9 @@ static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev, void *data,
68136834
cp.max_ce_len = 0;
68146835

68156836
hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_REPLY, sizeof(cp), &cp);
6837+
6838+
unlock:
6839+
hci_dev_unlock(hdev);
68166840
}
68176841

68186842
static void hci_le_direct_adv_report_evt(struct hci_dev *hdev, void *data,
@@ -6834,6 +6858,8 @@ static void hci_le_direct_adv_report_evt(struct hci_dev *hdev, void *data,
68346858
for (i = 0; i < ev->num; i++) {
68356859
struct hci_ev_le_direct_adv_info *info = &ev->info[i];
68366860

6861+
hci_store_wake_reason(hdev, &info->bdaddr, info->bdaddr_type);
6862+
68376863
process_adv_report(hdev, info->type, &info->bdaddr,
68386864
info->bdaddr_type, &info->direct_addr,
68396865
info->direct_addr_type, HCI_ADV_PHY_1M, 0,
@@ -7517,73 +7543,29 @@ static bool hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
75177543
return true;
75187544
}
75197545

7520-
static void hci_store_wake_reason(struct hci_dev *hdev, u8 event,
7521-
struct sk_buff *skb)
7546+
static void hci_store_wake_reason(struct hci_dev *hdev,
7547+
const bdaddr_t *bdaddr, u8 addr_type)
7548+
__must_hold(&hdev->lock)
75227549
{
7523-
struct hci_ev_le_advertising_info *adv;
7524-
struct hci_ev_le_direct_adv_info *direct_adv;
7525-
struct hci_ev_le_ext_adv_info *ext_adv;
7526-
const struct hci_ev_conn_complete *conn_complete = (void *)skb->data;
7527-
const struct hci_ev_conn_request *conn_request = (void *)skb->data;
7528-
7529-
hci_dev_lock(hdev);
7550+
lockdep_assert_held(&hdev->lock);
75307551

75317552
/* If we are currently suspended and this is the first BT event seen,
75327553
* save the wake reason associated with the event.
75337554
*/
75347555
if (!hdev->suspended || hdev->wake_reason)
7535-
goto unlock;
7556+
return;
7557+
7558+
if (!bdaddr) {
7559+
hdev->wake_reason = MGMT_WAKE_REASON_UNEXPECTED;
7560+
return;
7561+
}
75367562

75377563
/* Default to remote wake. Values for wake_reason are documented in the
75387564
* Bluez mgmt api docs.
75397565
*/
75407566
hdev->wake_reason = MGMT_WAKE_REASON_REMOTE_WAKE;
7541-
7542-
/* Once configured for remote wakeup, we should only wake up for
7543-
* reconnections. It's useful to see which device is waking us up so
7544-
* keep track of the bdaddr of the connection event that woke us up.
7545-
*/
7546-
if (event == HCI_EV_CONN_REQUEST) {
7547-
bacpy(&hdev->wake_addr, &conn_request->bdaddr);
7548-
hdev->wake_addr_type = BDADDR_BREDR;
7549-
} else if (event == HCI_EV_CONN_COMPLETE) {
7550-
bacpy(&hdev->wake_addr, &conn_complete->bdaddr);
7551-
hdev->wake_addr_type = BDADDR_BREDR;
7552-
} else if (event == HCI_EV_LE_META) {
7553-
struct hci_ev_le_meta *le_ev = (void *)skb->data;
7554-
u8 subevent = le_ev->subevent;
7555-
u8 *ptr = &skb->data[sizeof(*le_ev)];
7556-
u8 num_reports = *ptr;
7557-
7558-
if ((subevent == HCI_EV_LE_ADVERTISING_REPORT ||
7559-
subevent == HCI_EV_LE_DIRECT_ADV_REPORT ||
7560-
subevent == HCI_EV_LE_EXT_ADV_REPORT) &&
7561-
num_reports) {
7562-
adv = (void *)(ptr + 1);
7563-
direct_adv = (void *)(ptr + 1);
7564-
ext_adv = (void *)(ptr + 1);
7565-
7566-
switch (subevent) {
7567-
case HCI_EV_LE_ADVERTISING_REPORT:
7568-
bacpy(&hdev->wake_addr, &adv->bdaddr);
7569-
hdev->wake_addr_type = adv->bdaddr_type;
7570-
break;
7571-
case HCI_EV_LE_DIRECT_ADV_REPORT:
7572-
bacpy(&hdev->wake_addr, &direct_adv->bdaddr);
7573-
hdev->wake_addr_type = direct_adv->bdaddr_type;
7574-
break;
7575-
case HCI_EV_LE_EXT_ADV_REPORT:
7576-
bacpy(&hdev->wake_addr, &ext_adv->bdaddr);
7577-
hdev->wake_addr_type = ext_adv->bdaddr_type;
7578-
break;
7579-
}
7580-
}
7581-
} else {
7582-
hdev->wake_reason = MGMT_WAKE_REASON_UNEXPECTED;
7583-
}
7584-
7585-
unlock:
7586-
hci_dev_unlock(hdev);
7567+
bacpy(&hdev->wake_addr, bdaddr);
7568+
hdev->wake_addr_type = addr_type;
75877569
}
75887570

75897571
#define HCI_EV_VL(_op, _func, _min_len, _max_len) \
@@ -7830,14 +7812,15 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
78307812

78317813
skb_pull(skb, HCI_EVENT_HDR_SIZE);
78327814

7833-
/* Store wake reason if we're suspended */
7834-
hci_store_wake_reason(hdev, event, skb);
7835-
78367815
bt_dev_dbg(hdev, "event 0x%2.2x", event);
78377816

78387817
hci_event_func(hdev, event, skb, &opcode, &status, &req_complete,
78397818
&req_complete_skb);
78407819

7820+
hci_dev_lock(hdev);
7821+
hci_store_wake_reason(hdev, NULL, 0);
7822+
hci_dev_unlock(hdev);
7823+
78417824
if (req_complete) {
78427825
req_complete(hdev, status, opcode);
78437826
} else if (req_complete_skb) {

0 commit comments

Comments
 (0)