Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Bluetooth: hci_event: fix potential UAF in SSP passkey handlers

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: 92a25256f142 ("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>

authored by

Shuvam Pandey and committed by
Luiz Augusto von Dentz
85fa3512 a0cff16d

+14 -4
+14 -4
net/bluetooth/hci_event.c
··· 5495 5495 5496 5496 bt_dev_dbg(hdev, ""); 5497 5497 5498 + hci_dev_lock(hdev); 5499 + 5498 5500 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 5499 5501 if (!conn) 5500 - return; 5502 + goto unlock; 5501 5503 5502 5504 conn->passkey_notify = __le32_to_cpu(ev->passkey); 5503 5505 conn->passkey_entered = 0; ··· 5508 5506 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type, 5509 5507 conn->dst_type, conn->passkey_notify, 5510 5508 conn->passkey_entered); 5509 + 5510 + unlock: 5511 + hci_dev_unlock(hdev); 5511 5512 } 5512 5513 5513 5514 static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data, ··· 5521 5516 5522 5517 bt_dev_dbg(hdev, ""); 5523 5518 5519 + hci_dev_lock(hdev); 5520 + 5524 5521 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 5525 5522 if (!conn) 5526 - return; 5523 + goto unlock; 5527 5524 5528 5525 switch (ev->type) { 5529 5526 case HCI_KEYPRESS_STARTED: 5530 5527 conn->passkey_entered = 0; 5531 - return; 5528 + goto unlock; 5532 5529 5533 5530 case HCI_KEYPRESS_ENTERED: 5534 5531 conn->passkey_entered++; ··· 5545 5538 break; 5546 5539 5547 5540 case HCI_KEYPRESS_COMPLETED: 5548 - return; 5541 + goto unlock; 5549 5542 } 5550 5543 5551 5544 if (hci_dev_test_flag(hdev, HCI_MGMT)) 5552 5545 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type, 5553 5546 conn->dst_type, conn->passkey_notify, 5554 5547 conn->passkey_entered); 5548 + 5549 + unlock: 5550 + hci_dev_unlock(hdev); 5555 5551 } 5556 5552 5557 5553 static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,