Skip to content

Commit b255531

Browse files
pvVudentz
authored andcommitted
Bluetooth: hci_event: fix potential UAF in hci_le_remote_conn_param_req_evt
hci_conn lookup and field access must be covered by hdev lock in hci_le_remote_conn_param_req_evt, otherwise it's possible it is freed concurrently. Extend the hci_dev_lock critical section to cover all conn usage. Fixes: 95118dd ("Bluetooth: hci_event: Use of a function table to handle LE subevents") Signed-off-by: Pauli Virtanen <pav@iki.fi> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
1 parent a2639a7 commit b255531

1 file changed

Lines changed: 20 additions & 13 deletions

File tree

net/bluetooth/hci_event.c

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6784,25 +6784,31 @@ static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev, void *data,
67846784
latency = le16_to_cpu(ev->latency);
67856785
timeout = le16_to_cpu(ev->timeout);
67866786

6787+
hci_dev_lock(hdev);
6788+
67876789
hcon = hci_conn_hash_lookup_handle(hdev, handle);
6788-
if (!hcon || hcon->state != BT_CONNECTED)
6789-
return send_conn_param_neg_reply(hdev, handle,
6790-
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+
}
67916795

6792-
if (max > hcon->le_conn_max_interval)
6793-
return send_conn_param_neg_reply(hdev, handle,
6794-
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+
}
67956801

6796-
if (hci_check_conn_params(min, max, latency, timeout))
6797-
return send_conn_param_neg_reply(hdev, handle,
6798-
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+
}
67996807

68006808
if (hcon->role == HCI_ROLE_MASTER) {
68016809
struct hci_conn_params *params;
68026810
u8 store_hint;
68036811

6804-
hci_dev_lock(hdev);
6805-
68066812
params = hci_conn_params_lookup(hdev, &hcon->dst,
68076813
hcon->dst_type);
68086814
if (params) {
@@ -6815,8 +6821,6 @@ static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev, void *data,
68156821
store_hint = 0x00;
68166822
}
68176823

6818-
hci_dev_unlock(hdev);
6819-
68206824
mgmt_new_conn_param(hdev, &hcon->dst, hcon->dst_type,
68216825
store_hint, min, max, latency, timeout);
68226826
}
@@ -6830,6 +6834,9 @@ static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev, void *data,
68306834
cp.max_ce_len = 0;
68316835

68326836
hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_REPLY, sizeof(cp), &cp);
6837+
6838+
unlock:
6839+
hci_dev_unlock(hdev);
68336840
}
68346841

68356842
static void hci_le_direct_adv_report_evt(struct hci_dev *hdev, void *data,

0 commit comments

Comments
 (0)