Skip to content

Commit 579faba

Browse files
pvgregkh
authored andcommitted
Bluetooth: mgmt: fix locking in unpair_device/disconnect_sync
[ Upstream commit 16cd664 ] Dereferencing RCU-protected pointers outside critical sections is invalid and may lead to UAF. Take hdev->lock for hci_conn lookup and hci_abort_conn(). Don't use RCU to ensure the conn is fully initialized at this point. Fixes: 227a0cd ("Bluetooth: MGMT: Fix not generating command complete for MGMT_OP_DISCONNECT") Signed-off-by: Pauli Virtanen <pav@iki.fi> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 65ce6fe commit 579faba

1 file changed

Lines changed: 16 additions & 0 deletions

File tree

net/bluetooth/mgmt.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3012,20 +3012,28 @@ static int unpair_device_sync(struct hci_dev *hdev, void *data)
30123012
struct mgmt_cp_unpair_device *cp = cmd->param;
30133013
struct hci_conn *conn;
30143014

3015+
hci_dev_lock(hdev);
3016+
30153017
if (cp->addr.type == BDADDR_BREDR)
30163018
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
30173019
&cp->addr.bdaddr);
30183020
else
30193021
conn = hci_conn_hash_lookup_le(hdev, &cp->addr.bdaddr,
30203022
le_addr_type(cp->addr.type));
30213023

3024+
if (conn)
3025+
hci_conn_get(conn);
3026+
3027+
hci_dev_unlock(hdev);
3028+
30223029
if (!conn)
30233030
return 0;
30243031

30253032
/* Disregard any possible error since the likes of hci_abort_conn_sync
30263033
* will clean up the connection no matter the error.
30273034
*/
30283035
hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM);
3036+
hci_conn_put(conn);
30293037

30303038
return 0;
30313039
}
@@ -3173,20 +3181,28 @@ static int disconnect_sync(struct hci_dev *hdev, void *data)
31733181
struct mgmt_cp_disconnect *cp = cmd->param;
31743182
struct hci_conn *conn;
31753183

3184+
hci_dev_lock(hdev);
3185+
31763186
if (cp->addr.type == BDADDR_BREDR)
31773187
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
31783188
&cp->addr.bdaddr);
31793189
else
31803190
conn = hci_conn_hash_lookup_le(hdev, &cp->addr.bdaddr,
31813191
le_addr_type(cp->addr.type));
31823192

3193+
if (conn)
3194+
hci_conn_get(conn);
3195+
3196+
hci_dev_unlock(hdev);
3197+
31833198
if (!conn)
31843199
return -ENOTCONN;
31853200

31863201
/* Disregard any possible error since the likes of hci_abort_conn_sync
31873202
* will clean up the connection no matter the error.
31883203
*/
31893204
hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM);
3205+
hci_conn_put(conn);
31903206

31913207
return 0;
31923208
}

0 commit comments

Comments
 (0)