Skip to content

Commit 204028a

Browse files
shuv-ampgregkh
authored andcommitted
Bluetooth: hci_event: fix potential UAF in SSP passkey handlers
commit 85fa351 upstream. hci_conn lookup and field access must be covered by hdev lock in hci_user_passkey_notify_evt() and hci_keypress_notify_evt(), otherwise the connection can be freed concurrently. Extend the hci_dev_lock critical section to cover all conn usage in both handlers. Keep the existing keypress notification behavior unchanged by routing the early exits through a common unlock path. Fixes: 92a2525 ("Bluetooth: mgmt: Implement support for passkey notification") Cc: stable@vger.kernel.org Signed-off-by: Shuvam Pandey <shuvampandey1@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 6cbf217 commit 204028a

1 file changed

Lines changed: 14 additions & 4 deletions

File tree

net/bluetooth/hci_event.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5409,9 +5409,11 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
54095409

54105410
bt_dev_dbg(hdev, "");
54115411

5412+
hci_dev_lock(hdev);
5413+
54125414
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
54135415
if (!conn)
5414-
return;
5416+
goto unlock;
54155417

54165418
conn->passkey_notify = __le32_to_cpu(ev->passkey);
54175419
conn->passkey_entered = 0;
@@ -5420,6 +5422,9 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
54205422
mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
54215423
conn->dst_type, conn->passkey_notify,
54225424
conn->passkey_entered);
5425+
5426+
unlock:
5427+
hci_dev_unlock(hdev);
54235428
}
54245429

54255430
static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
@@ -5430,14 +5435,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
54305435

54315436
bt_dev_dbg(hdev, "");
54325437

5438+
hci_dev_lock(hdev);
5439+
54335440
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
54345441
if (!conn)
5435-
return;
5442+
goto unlock;
54365443

54375444
switch (ev->type) {
54385445
case HCI_KEYPRESS_STARTED:
54395446
conn->passkey_entered = 0;
5440-
return;
5447+
goto unlock;
54415448

54425449
case HCI_KEYPRESS_ENTERED:
54435450
conn->passkey_entered++;
@@ -5452,13 +5459,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
54525459
break;
54535460

54545461
case HCI_KEYPRESS_COMPLETED:
5455-
return;
5462+
goto unlock;
54565463
}
54575464

54585465
if (hci_dev_test_flag(hdev, HCI_MGMT))
54595466
mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
54605467
conn->dst_type, conn->passkey_notify,
54615468
conn->passkey_entered);
5469+
5470+
unlock:
5471+
hci_dev_unlock(hdev);
54625472
}
54635473

54645474
static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,

0 commit comments

Comments
 (0)