Skip to content

Commit 8bc83f9

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 70354db commit 8bc83f9

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
@@ -3005,20 +3005,28 @@ static int unpair_device_sync(struct hci_dev *hdev, void *data)
30053005
struct mgmt_cp_unpair_device *cp = cmd->param;
30063006
struct hci_conn *conn;
30073007

3008+
hci_dev_lock(hdev);
3009+
30083010
if (cp->addr.type == BDADDR_BREDR)
30093011
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
30103012
&cp->addr.bdaddr);
30113013
else
30123014
conn = hci_conn_hash_lookup_le(hdev, &cp->addr.bdaddr,
30133015
le_addr_type(cp->addr.type));
30143016

3017+
if (conn)
3018+
hci_conn_get(conn);
3019+
3020+
hci_dev_unlock(hdev);
3021+
30153022
if (!conn)
30163023
return 0;
30173024

30183025
/* Disregard any possible error since the likes of hci_abort_conn_sync
30193026
* will clean up the connection no matter the error.
30203027
*/
30213028
hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM);
3029+
hci_conn_put(conn);
30223030

30233031
return 0;
30243032
}
@@ -3166,20 +3174,28 @@ static int disconnect_sync(struct hci_dev *hdev, void *data)
31663174
struct mgmt_cp_disconnect *cp = cmd->param;
31673175
struct hci_conn *conn;
31683176

3177+
hci_dev_lock(hdev);
3178+
31693179
if (cp->addr.type == BDADDR_BREDR)
31703180
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
31713181
&cp->addr.bdaddr);
31723182
else
31733183
conn = hci_conn_hash_lookup_le(hdev, &cp->addr.bdaddr,
31743184
le_addr_type(cp->addr.type));
31753185

3186+
if (conn)
3187+
hci_conn_get(conn);
3188+
3189+
hci_dev_unlock(hdev);
3190+
31763191
if (!conn)
31773192
return -ENOTCONN;
31783193

31793194
/* Disregard any possible error since the likes of hci_abort_conn_sync
31803195
* will clean up the connection no matter the error.
31813196
*/
31823197
hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM);
3198+
hci_conn_put(conn);
31833199

31843200
return 0;
31853201
}

0 commit comments

Comments
 (0)