VYPR
Unrated severityNVD Advisory· Published May 27, 2026· Updated May 27, 2026

CVE-2026-46056

CVE-2026-46056

Description

In the Linux kernel, the following vulnerability has been resolved:

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.

Affected products

2

Patches

10
8c6443bb9257

Bluetooth: hci_event: fix potential UAF in SSP passkey handlers

2 files changed · +28 10
  • net/bluetooth/hci_event.c+14 5 modified
    diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
    index 3ebc5e6d45d98a..6500f7a327f608 100644
    --- a/net/bluetooth/hci_event.c
    +++ b/net/bluetooth/hci_event.c
    @@ -5498,9 +5498,11 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	conn->passkey_notify = __le32_to_cpu(ev->passkey);
     	conn->passkey_entered = 0;
    @@ -5509,6 +5511,9 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
    @@ -5519,14 +5524,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	switch (ev->type) {
     	case HCI_KEYPRESS_STARTED:
     		conn->passkey_entered = 0;
    -		return;
    +		goto unlock;
     
     	case HCI_KEYPRESS_ENTERED:
     		conn->passkey_entered++;
    @@ -5541,13 +5548,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     		break;
     
     	case HCI_KEYPRESS_COMPLETED:
    -		return;
    +		goto unlock;
     	}
     
     	if (hci_dev_test_flag(hdev, HCI_MGMT))
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
    -- 
    cgit 1.3-korg
    
    
    
  • net/bluetooth/hci_event.c+14 5 modified
    diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
    index 3ebc5e6d45d98a..6500f7a327f608 100644
    --- a/net/bluetooth/hci_event.c
    +++ b/net/bluetooth/hci_event.c
    @@ -5498,9 +5498,11 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	conn->passkey_notify = __le32_to_cpu(ev->passkey);
     	conn->passkey_entered = 0;
    @@ -5509,6 +5511,9 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
    @@ -5519,14 +5524,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	switch (ev->type) {
     	case HCI_KEYPRESS_STARTED:
     		conn->passkey_entered = 0;
    -		return;
    +		goto unlock;
     
     	case HCI_KEYPRESS_ENTERED:
     		conn->passkey_entered++;
    @@ -5541,13 +5548,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     		break;
     
     	case HCI_KEYPRESS_COMPLETED:
    -		return;
    +		goto unlock;
     	}
     
     	if (hci_dev_test_flag(hdev, HCI_MGMT))
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
    -- 
    cgit 1.3-korg
    
    
    
204028af77a2

Bluetooth: hci_event: fix potential UAF in SSP passkey handlers

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitShuvam PandeyFixed in 6.6.140via kernel-cna
2 files changed · +28 10
  • net/bluetooth/hci_event.c+14 5 modified
    diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
    index 8b184839b013ab..dcf23d9f1ef6cf 100644
    --- a/net/bluetooth/hci_event.c
    +++ b/net/bluetooth/hci_event.c
    @@ -5409,9 +5409,11 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	conn->passkey_notify = __le32_to_cpu(ev->passkey);
     	conn->passkey_entered = 0;
    @@ -5420,6 +5422,9 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     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,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	switch (ev->type) {
     	case HCI_KEYPRESS_STARTED:
     		conn->passkey_entered = 0;
    -		return;
    +		goto unlock;
     
     	case HCI_KEYPRESS_ENTERED:
     		conn->passkey_entered++;
    @@ -5452,13 +5459,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     		break;
     
     	case HCI_KEYPRESS_COMPLETED:
    -		return;
    +		goto unlock;
     	}
     
     	if (hci_dev_test_flag(hdev, HCI_MGMT))
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
    -- 
    cgit 1.3-korg
    
    
    
  • net/bluetooth/hci_event.c+14 5 modified
    diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
    index 8b184839b013ab..dcf23d9f1ef6cf 100644
    --- a/net/bluetooth/hci_event.c
    +++ b/net/bluetooth/hci_event.c
    @@ -5409,9 +5409,11 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	conn->passkey_notify = __le32_to_cpu(ev->passkey);
     	conn->passkey_entered = 0;
    @@ -5420,6 +5422,9 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     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,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	switch (ev->type) {
     	case HCI_KEYPRESS_STARTED:
     		conn->passkey_entered = 0;
    -		return;
    +		goto unlock;
     
     	case HCI_KEYPRESS_ENTERED:
     		conn->passkey_entered++;
    @@ -5452,13 +5459,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     		break;
     
     	case HCI_KEYPRESS_COMPLETED:
    -		return;
    +		goto unlock;
     	}
     
     	if (hci_dev_test_flag(hdev, HCI_MGMT))
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
    -- 
    cgit 1.3-korg
    
    
    
01a6431766c3

Bluetooth: hci_event: fix potential UAF in SSP passkey handlers

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitShuvam PandeyFixed in 6.12.86via kernel-cna
2 files changed · +28 10
  • net/bluetooth/hci_event.c+14 5 modified
    diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
    index 0dd021c881cc44..7246a26723d0fd 100644
    --- a/net/bluetooth/hci_event.c
    +++ b/net/bluetooth/hci_event.c
    @@ -5412,9 +5412,11 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	conn->passkey_notify = __le32_to_cpu(ev->passkey);
     	conn->passkey_entered = 0;
    @@ -5423,6 +5425,9 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
    @@ -5433,14 +5438,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	switch (ev->type) {
     	case HCI_KEYPRESS_STARTED:
     		conn->passkey_entered = 0;
    -		return;
    +		goto unlock;
     
     	case HCI_KEYPRESS_ENTERED:
     		conn->passkey_entered++;
    @@ -5455,13 +5462,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     		break;
     
     	case HCI_KEYPRESS_COMPLETED:
    -		return;
    +		goto unlock;
     	}
     
     	if (hci_dev_test_flag(hdev, HCI_MGMT))
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
    -- 
    cgit 1.3-korg
    
    
    
  • net/bluetooth/hci_event.c+14 5 modified
    diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
    index 0dd021c881cc44..7246a26723d0fd 100644
    --- a/net/bluetooth/hci_event.c
    +++ b/net/bluetooth/hci_event.c
    @@ -5412,9 +5412,11 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	conn->passkey_notify = __le32_to_cpu(ev->passkey);
     	conn->passkey_entered = 0;
    @@ -5423,6 +5425,9 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
    @@ -5433,14 +5438,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	switch (ev->type) {
     	case HCI_KEYPRESS_STARTED:
     		conn->passkey_entered = 0;
    -		return;
    +		goto unlock;
     
     	case HCI_KEYPRESS_ENTERED:
     		conn->passkey_entered++;
    @@ -5455,13 +5462,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     		break;
     
     	case HCI_KEYPRESS_COMPLETED:
    -		return;
    +		goto unlock;
     	}
     
     	if (hci_dev_test_flag(hdev, HCI_MGMT))
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
    -- 
    cgit 1.3-korg
    
    
    
e08d75753db1

Bluetooth: hci_event: fix potential UAF in SSP passkey handlers

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitShuvam PandeyFixed in 6.18.27via kernel-cna
2 files changed · +28 10
  • net/bluetooth/hci_event.c+14 5 modified
    diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
    index 7794f4f9815964..c66443f4cf5a7a 100644
    --- a/net/bluetooth/hci_event.c
    +++ b/net/bluetooth/hci_event.c
    @@ -5422,9 +5422,11 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	conn->passkey_notify = __le32_to_cpu(ev->passkey);
     	conn->passkey_entered = 0;
    @@ -5433,6 +5435,9 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
    @@ -5443,14 +5448,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	switch (ev->type) {
     	case HCI_KEYPRESS_STARTED:
     		conn->passkey_entered = 0;
    -		return;
    +		goto unlock;
     
     	case HCI_KEYPRESS_ENTERED:
     		conn->passkey_entered++;
    @@ -5465,13 +5472,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     		break;
     
     	case HCI_KEYPRESS_COMPLETED:
    -		return;
    +		goto unlock;
     	}
     
     	if (hci_dev_test_flag(hdev, HCI_MGMT))
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
    -- 
    cgit 1.3-korg
    
    
    
  • net/bluetooth/hci_event.c+14 5 modified
    diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
    index 7794f4f9815964..c66443f4cf5a7a 100644
    --- a/net/bluetooth/hci_event.c
    +++ b/net/bluetooth/hci_event.c
    @@ -5422,9 +5422,11 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	conn->passkey_notify = __le32_to_cpu(ev->passkey);
     	conn->passkey_entered = 0;
    @@ -5433,6 +5435,9 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
    @@ -5443,14 +5448,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	switch (ev->type) {
     	case HCI_KEYPRESS_STARTED:
     		conn->passkey_entered = 0;
    -		return;
    +		goto unlock;
     
     	case HCI_KEYPRESS_ENTERED:
     		conn->passkey_entered++;
    @@ -5465,13 +5472,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     		break;
     
     	case HCI_KEYPRESS_COMPLETED:
    -		return;
    +		goto unlock;
     	}
     
     	if (hci_dev_test_flag(hdev, HCI_MGMT))
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
    -- 
    cgit 1.3-korg
    
    
    
85fa35120487

Bluetooth: hci_event: fix potential UAF in SSP passkey handlers

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitShuvam PandeyFixed in 7.1-rc1via kernel-cna
2 files changed · +28 10
  • net/bluetooth/hci_event.c+14 5 modified
    diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
    index 83248085dd4f21..b2ee6b6a0f5650 100644
    --- a/net/bluetooth/hci_event.c
    +++ b/net/bluetooth/hci_event.c
    @@ -5495,9 +5495,11 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	conn->passkey_notify = __le32_to_cpu(ev->passkey);
     	conn->passkey_entered = 0;
    @@ -5506,6 +5508,9 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
    @@ -5516,14 +5521,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	switch (ev->type) {
     	case HCI_KEYPRESS_STARTED:
     		conn->passkey_entered = 0;
    -		return;
    +		goto unlock;
     
     	case HCI_KEYPRESS_ENTERED:
     		conn->passkey_entered++;
    @@ -5538,13 +5545,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     		break;
     
     	case HCI_KEYPRESS_COMPLETED:
    -		return;
    +		goto unlock;
     	}
     
     	if (hci_dev_test_flag(hdev, HCI_MGMT))
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
    -- 
    cgit 1.3-korg
    
    
    
  • net/bluetooth/hci_event.c+14 5 modified
    diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
    index 83248085dd4f21..b2ee6b6a0f5650 100644
    --- a/net/bluetooth/hci_event.c
    +++ b/net/bluetooth/hci_event.c
    @@ -5495,9 +5495,11 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	conn->passkey_notify = __le32_to_cpu(ev->passkey);
     	conn->passkey_entered = 0;
    @@ -5506,6 +5508,9 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
    @@ -5516,14 +5521,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	switch (ev->type) {
     	case HCI_KEYPRESS_STARTED:
     		conn->passkey_entered = 0;
    -		return;
    +		goto unlock;
     
     	case HCI_KEYPRESS_ENTERED:
     		conn->passkey_entered++;
    @@ -5538,13 +5545,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     		break;
     
     	case HCI_KEYPRESS_COMPLETED:
    -		return;
    +		goto unlock;
     	}
     
     	if (hci_dev_test_flag(hdev, HCI_MGMT))
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
    -- 
    cgit 1.3-korg
    
    
    
01a6431766c3

Bluetooth: hci_event: fix potential UAF in SSP passkey handlers

2 files changed · +28 10
  • net/bluetooth/hci_event.c+14 5 modified
    diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
    index 0dd021c881cc44..7246a26723d0fd 100644
    --- a/net/bluetooth/hci_event.c
    +++ b/net/bluetooth/hci_event.c
    @@ -5412,9 +5412,11 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	conn->passkey_notify = __le32_to_cpu(ev->passkey);
     	conn->passkey_entered = 0;
    @@ -5423,6 +5425,9 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
    @@ -5433,14 +5438,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	switch (ev->type) {
     	case HCI_KEYPRESS_STARTED:
     		conn->passkey_entered = 0;
    -		return;
    +		goto unlock;
     
     	case HCI_KEYPRESS_ENTERED:
     		conn->passkey_entered++;
    @@ -5455,13 +5462,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     		break;
     
     	case HCI_KEYPRESS_COMPLETED:
    -		return;
    +		goto unlock;
     	}
     
     	if (hci_dev_test_flag(hdev, HCI_MGMT))
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
    -- 
    cgit 1.3-korg
    
    
    
  • net/bluetooth/hci_event.c+14 5 modified
    diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
    index 0dd021c881cc44..7246a26723d0fd 100644
    --- a/net/bluetooth/hci_event.c
    +++ b/net/bluetooth/hci_event.c
    @@ -5412,9 +5412,11 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	conn->passkey_notify = __le32_to_cpu(ev->passkey);
     	conn->passkey_entered = 0;
    @@ -5423,6 +5425,9 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
    @@ -5433,14 +5438,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	switch (ev->type) {
     	case HCI_KEYPRESS_STARTED:
     		conn->passkey_entered = 0;
    -		return;
    +		goto unlock;
     
     	case HCI_KEYPRESS_ENTERED:
     		conn->passkey_entered++;
    @@ -5455,13 +5462,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     		break;
     
     	case HCI_KEYPRESS_COMPLETED:
    -		return;
    +		goto unlock;
     	}
     
     	if (hci_dev_test_flag(hdev, HCI_MGMT))
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
    -- 
    cgit 1.3-korg
    
    
    
e08d75753db1

Bluetooth: hci_event: fix potential UAF in SSP passkey handlers

2 files changed · +28 10
  • net/bluetooth/hci_event.c+14 5 modified
    diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
    index 7794f4f9815964..c66443f4cf5a7a 100644
    --- a/net/bluetooth/hci_event.c
    +++ b/net/bluetooth/hci_event.c
    @@ -5422,9 +5422,11 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	conn->passkey_notify = __le32_to_cpu(ev->passkey);
     	conn->passkey_entered = 0;
    @@ -5433,6 +5435,9 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
    @@ -5443,14 +5448,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	switch (ev->type) {
     	case HCI_KEYPRESS_STARTED:
     		conn->passkey_entered = 0;
    -		return;
    +		goto unlock;
     
     	case HCI_KEYPRESS_ENTERED:
     		conn->passkey_entered++;
    @@ -5465,13 +5472,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     		break;
     
     	case HCI_KEYPRESS_COMPLETED:
    -		return;
    +		goto unlock;
     	}
     
     	if (hci_dev_test_flag(hdev, HCI_MGMT))
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
    -- 
    cgit 1.3-korg
    
    
    
  • net/bluetooth/hci_event.c+14 5 modified
    diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
    index 7794f4f9815964..c66443f4cf5a7a 100644
    --- a/net/bluetooth/hci_event.c
    +++ b/net/bluetooth/hci_event.c
    @@ -5422,9 +5422,11 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	conn->passkey_notify = __le32_to_cpu(ev->passkey);
     	conn->passkey_entered = 0;
    @@ -5433,6 +5435,9 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
    @@ -5443,14 +5448,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	switch (ev->type) {
     	case HCI_KEYPRESS_STARTED:
     		conn->passkey_entered = 0;
    -		return;
    +		goto unlock;
     
     	case HCI_KEYPRESS_ENTERED:
     		conn->passkey_entered++;
    @@ -5465,13 +5472,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     		break;
     
     	case HCI_KEYPRESS_COMPLETED:
    -		return;
    +		goto unlock;
     	}
     
     	if (hci_dev_test_flag(hdev, HCI_MGMT))
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
    -- 
    cgit 1.3-korg
    
    
    
85fa35120487

Bluetooth: hci_event: fix potential UAF in SSP passkey handlers

2 files changed · +28 10
  • net/bluetooth/hci_event.c+14 5 modified
    diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
    index 83248085dd4f21..b2ee6b6a0f5650 100644
    --- a/net/bluetooth/hci_event.c
    +++ b/net/bluetooth/hci_event.c
    @@ -5495,9 +5495,11 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	conn->passkey_notify = __le32_to_cpu(ev->passkey);
     	conn->passkey_entered = 0;
    @@ -5506,6 +5508,9 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
    @@ -5516,14 +5521,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	switch (ev->type) {
     	case HCI_KEYPRESS_STARTED:
     		conn->passkey_entered = 0;
    -		return;
    +		goto unlock;
     
     	case HCI_KEYPRESS_ENTERED:
     		conn->passkey_entered++;
    @@ -5538,13 +5545,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     		break;
     
     	case HCI_KEYPRESS_COMPLETED:
    -		return;
    +		goto unlock;
     	}
     
     	if (hci_dev_test_flag(hdev, HCI_MGMT))
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
    -- 
    cgit 1.3-korg
    
    
    
  • net/bluetooth/hci_event.c+14 5 modified
    diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
    index 83248085dd4f21..b2ee6b6a0f5650 100644
    --- a/net/bluetooth/hci_event.c
    +++ b/net/bluetooth/hci_event.c
    @@ -5495,9 +5495,11 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	conn->passkey_notify = __le32_to_cpu(ev->passkey);
     	conn->passkey_entered = 0;
    @@ -5506,6 +5508,9 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
    @@ -5516,14 +5521,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	switch (ev->type) {
     	case HCI_KEYPRESS_STARTED:
     		conn->passkey_entered = 0;
    -		return;
    +		goto unlock;
     
     	case HCI_KEYPRESS_ENTERED:
     		conn->passkey_entered++;
    @@ -5538,13 +5545,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     		break;
     
     	case HCI_KEYPRESS_COMPLETED:
    -		return;
    +		goto unlock;
     	}
     
     	if (hci_dev_test_flag(hdev, HCI_MGMT))
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
    -- 
    cgit 1.3-korg
    
    
    
8c6443bb9257

Bluetooth: hci_event: fix potential UAF in SSP passkey handlers

2 files changed · +28 10
  • net/bluetooth/hci_event.c+14 5 modified
    diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
    index 3ebc5e6d45d98a..6500f7a327f608 100644
    --- a/net/bluetooth/hci_event.c
    +++ b/net/bluetooth/hci_event.c
    @@ -5498,9 +5498,11 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	conn->passkey_notify = __le32_to_cpu(ev->passkey);
     	conn->passkey_entered = 0;
    @@ -5509,6 +5511,9 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
    @@ -5519,14 +5524,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	switch (ev->type) {
     	case HCI_KEYPRESS_STARTED:
     		conn->passkey_entered = 0;
    -		return;
    +		goto unlock;
     
     	case HCI_KEYPRESS_ENTERED:
     		conn->passkey_entered++;
    @@ -5541,13 +5548,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     		break;
     
     	case HCI_KEYPRESS_COMPLETED:
    -		return;
    +		goto unlock;
     	}
     
     	if (hci_dev_test_flag(hdev, HCI_MGMT))
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
    -- 
    cgit 1.3-korg
    
    
    
  • net/bluetooth/hci_event.c+14 5 modified
    diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
    index 3ebc5e6d45d98a..6500f7a327f608 100644
    --- a/net/bluetooth/hci_event.c
    +++ b/net/bluetooth/hci_event.c
    @@ -5498,9 +5498,11 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	conn->passkey_notify = __le32_to_cpu(ev->passkey);
     	conn->passkey_entered = 0;
    @@ -5509,6 +5511,9 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
    @@ -5519,14 +5524,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	switch (ev->type) {
     	case HCI_KEYPRESS_STARTED:
     		conn->passkey_entered = 0;
    -		return;
    +		goto unlock;
     
     	case HCI_KEYPRESS_ENTERED:
     		conn->passkey_entered++;
    @@ -5541,13 +5548,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     		break;
     
     	case HCI_KEYPRESS_COMPLETED:
    -		return;
    +		goto unlock;
     	}
     
     	if (hci_dev_test_flag(hdev, HCI_MGMT))
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
    -- 
    cgit 1.3-korg
    
    
    
204028af77a2

Bluetooth: hci_event: fix potential UAF in SSP passkey handlers

2 files changed · +28 10
  • net/bluetooth/hci_event.c+14 5 modified
    diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
    index 8b184839b013ab..dcf23d9f1ef6cf 100644
    --- a/net/bluetooth/hci_event.c
    +++ b/net/bluetooth/hci_event.c
    @@ -5409,9 +5409,11 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	conn->passkey_notify = __le32_to_cpu(ev->passkey);
     	conn->passkey_entered = 0;
    @@ -5420,6 +5422,9 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     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,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	switch (ev->type) {
     	case HCI_KEYPRESS_STARTED:
     		conn->passkey_entered = 0;
    -		return;
    +		goto unlock;
     
     	case HCI_KEYPRESS_ENTERED:
     		conn->passkey_entered++;
    @@ -5452,13 +5459,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     		break;
     
     	case HCI_KEYPRESS_COMPLETED:
    -		return;
    +		goto unlock;
     	}
     
     	if (hci_dev_test_flag(hdev, HCI_MGMT))
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
    -- 
    cgit 1.3-korg
    
    
    
  • net/bluetooth/hci_event.c+14 5 modified
    diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
    index 8b184839b013ab..dcf23d9f1ef6cf 100644
    --- a/net/bluetooth/hci_event.c
    +++ b/net/bluetooth/hci_event.c
    @@ -5409,9 +5409,11 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	conn->passkey_notify = __le32_to_cpu(ev->passkey);
     	conn->passkey_entered = 0;
    @@ -5420,6 +5422,9 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     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,
     
     	bt_dev_dbg(hdev, "");
     
    +	hci_dev_lock(hdev);
    +
     	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
     	if (!conn)
    -		return;
    +		goto unlock;
     
     	switch (ev->type) {
     	case HCI_KEYPRESS_STARTED:
     		conn->passkey_entered = 0;
    -		return;
    +		goto unlock;
     
     	case HCI_KEYPRESS_ENTERED:
     		conn->passkey_entered++;
    @@ -5452,13 +5459,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
     		break;
     
     	case HCI_KEYPRESS_COMPLETED:
    -		return;
    +		goto unlock;
     	}
     
     	if (hci_dev_test_flag(hdev, HCI_MGMT))
     		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
     					 conn->dst_type, conn->passkey_notify,
     					 conn->passkey_entered);
    +
    +unlock:
    +	hci_dev_unlock(hdev);
     }
     
     static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Missing hci_dev_lock coverage in SSP passkey event handlers allows concurrent connection free leading to use-after-free."

Attack vector

An attacker within Bluetooth range can trigger SSP (Secure Simple Pairing) passkey events that are processed by `hci_user_passkey_notify_evt()` or `hci_keypress_notify_evt()` in `net/bluetooth/hci_event.c` [patch_id=2660081]. Because these handlers did not hold `hci_dev_lock` while looking up and accessing the `hci_conn`, a concurrent Bluetooth operation (e.g. disconnection) can free the connection object while the handler is still reading or writing its fields, leading to a use-after-free [patch_id=2660081]. No authentication is required beyond being able to initiate or participate in Bluetooth pairing.

Affected code

The vulnerability is in `net/bluetooth/hci_event.c` in the functions `hci_user_passkey_notify_evt()` and `hci_keypress_notify_evt()` [patch_id=2660081]. These handlers perform an `hci_conn_hash_lookup_ba()` lookup and then access `conn` fields without holding the `hdev` lock, allowing a concurrent connection free to cause a use-after-free [patch_id=2660081].

What the fix does

The patch extends the `hci_dev_lock` / `hci_dev_unlock` critical section in both `hci_user_passkey_notify_evt()` and `hci_keypress_notify_evt()` to cover the entire `hci_conn` lookup and all subsequent field accesses [patch_id=2660081]. Previously the lock was not held at all in these handlers; now `hci_dev_lock(hdev)` is called before the hash lookup, and all early-return paths (including the `!conn` case and the `HCI_KEYPRESS_STARTED`/`HCI_KEYPRESS_COMPLETED` cases) jump to a common `unlock` label that calls `hci_dev_unlock(hdev)` [patch_id=2660081]. This ensures the connection cannot be freed by another thread while the handler is using it.

Preconditions

  • networkAttacker must be within Bluetooth radio range of the target device
  • configTarget device must have Bluetooth enabled and be performing or capable of SSP (Secure Simple Pairing) passkey-based pairing
  • authNo authentication required; the attacker initiates or participates in Bluetooth pairing to trigger SSP passkey events

Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.