Bluetooth: hci_conn: Fix UAF Write in __hci_acl_create_connection_sync

This fixes the UAF on __hci_acl_create_connection_sync caused by
connection abortion, it uses the same logic as to LE_LINK which uses
hci_cmd_sync_cancel to prevent the callback to run if the connection is
abort prematurely.

Reported-by: syzbot+3f0a39be7a2035700868@syzkaller.appspotmail.com
Fixes: 45340097 ("Bluetooth: hci_conn: Only do ACL connections sequentially")
Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
parent bf98feea
...@@ -139,5 +139,4 @@ int hci_le_big_terminate_sync(struct hci_dev *hdev, u8 handle); ...@@ -139,5 +139,4 @@ int hci_le_big_terminate_sync(struct hci_dev *hdev, u8 handle);
int hci_le_pa_terminate_sync(struct hci_dev *hdev, u16 handle); int hci_le_pa_terminate_sync(struct hci_dev *hdev, u16 handle);
int hci_acl_create_connection_sync(struct hci_dev *hdev, int hci_connect_acl_sync(struct hci_dev *hdev, struct hci_conn *conn);
struct hci_conn *conn);
...@@ -1645,7 +1645,7 @@ struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst, ...@@ -1645,7 +1645,7 @@ struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
acl->auth_type = auth_type; acl->auth_type = auth_type;
acl->conn_timeout = timeout; acl->conn_timeout = timeout;
err = hci_acl_create_connection_sync(hdev, acl); err = hci_connect_acl_sync(hdev, acl);
if (err) { if (err) {
hci_conn_del(acl); hci_conn_del(acl);
return ERR_PTR(err); return ERR_PTR(err);
...@@ -2942,6 +2942,7 @@ int hci_abort_conn(struct hci_conn *conn, u8 reason) ...@@ -2942,6 +2942,7 @@ int hci_abort_conn(struct hci_conn *conn, u8 reason)
*/ */
if (conn->state == BT_CONNECT && hdev->req_status == HCI_REQ_PEND) { if (conn->state == BT_CONNECT && hdev->req_status == HCI_REQ_PEND) {
switch (hci_skb_event(hdev->sent_cmd)) { switch (hci_skb_event(hdev->sent_cmd)) {
case HCI_EV_CONN_COMPLETE:
case HCI_EV_LE_CONN_COMPLETE: case HCI_EV_LE_CONN_COMPLETE:
case HCI_EV_LE_ENHANCED_CONN_COMPLETE: case HCI_EV_LE_ENHANCED_CONN_COMPLETE:
case HCI_EVT_LE_CIS_ESTABLISHED: case HCI_EVT_LE_CIS_ESTABLISHED:
......
...@@ -6493,13 +6493,18 @@ int hci_update_adv_data(struct hci_dev *hdev, u8 instance) ...@@ -6493,13 +6493,18 @@ int hci_update_adv_data(struct hci_dev *hdev, u8 instance)
UINT_PTR(instance), NULL); UINT_PTR(instance), NULL);
} }
static int __hci_acl_create_connection_sync(struct hci_dev *hdev, void *data) static int hci_acl_create_conn_sync(struct hci_dev *hdev, void *data)
{ {
struct hci_conn *conn = data; struct hci_conn *conn;
u16 handle = PTR_UINT(data);
struct inquiry_entry *ie; struct inquiry_entry *ie;
struct hci_cp_create_conn cp; struct hci_cp_create_conn cp;
int err; int err;
conn = hci_conn_hash_lookup_handle(hdev, handle);
if (!conn)
return 0;
/* Many controllers disallow HCI Create Connection while it is doing /* Many controllers disallow HCI Create Connection while it is doing
* HCI Inquiry. So we cancel the Inquiry first before issuing HCI Create * HCI Inquiry. So we cancel the Inquiry first before issuing HCI Create
* Connection. This may cause the MGMT discovering state to become false * Connection. This may cause the MGMT discovering state to become false
...@@ -6556,9 +6561,8 @@ static int __hci_acl_create_connection_sync(struct hci_dev *hdev, void *data) ...@@ -6556,9 +6561,8 @@ static int __hci_acl_create_connection_sync(struct hci_dev *hdev, void *data)
return err; return err;
} }
int hci_acl_create_connection_sync(struct hci_dev *hdev, int hci_connect_acl_sync(struct hci_dev *hdev, struct hci_conn *conn)
struct hci_conn *conn)
{ {
return hci_cmd_sync_queue(hdev, __hci_acl_create_connection_sync, return hci_cmd_sync_queue(hdev, hci_acl_create_conn_sync,
conn, NULL); UINT_PTR(conn->handle), NULL);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment