mirror of
https://github.com/torvalds/linux.git
synced 2024-10-23 21:50:43 +00:00
Bluetooth: hci_conn: fail SCO/ISO via hci_conn_failed if ACL gone early
Not calling hci_(dis)connect_cfm before deleting conn referred to by a
socket generally results to use-after-free.
When cleaning up SCO connections when the parent ACL is deleted too
early, use hci_conn_failed to do the connection cleanup properly.
We also need to clean up ISO connections in a similar situation when
connecting has started but LE Create CIS is not yet sent, so do it too
here.
Fixes: ca1fd42e7d
("Bluetooth: Fix potential double free caused by hci_conn_unlink")
Reported-by: syzbot+cf54c1da6574b6c1b049@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/linux-bluetooth/00000000000013b93805fbbadc50@google.com/
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
db08722fc7
commit
3344d31833
|
@ -1044,6 +1044,29 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
|
|||
return conn;
|
||||
}
|
||||
|
||||
static void hci_conn_cleanup_child(struct hci_conn *conn, u8 reason)
|
||||
{
|
||||
if (!reason)
|
||||
reason = HCI_ERROR_REMOTE_USER_TERM;
|
||||
|
||||
/* Due to race, SCO/ISO conn might be not established yet at this point,
|
||||
* and nothing else will clean it up. In other cases it is done via HCI
|
||||
* events.
|
||||
*/
|
||||
switch (conn->type) {
|
||||
case SCO_LINK:
|
||||
case ESCO_LINK:
|
||||
if (HCI_CONN_HANDLE_UNSET(conn->handle))
|
||||
hci_conn_failed(conn, reason);
|
||||
break;
|
||||
case ISO_LINK:
|
||||
if (conn->state != BT_CONNECTED &&
|
||||
!test_bit(HCI_CONN_CREATE_CIS, &conn->flags))
|
||||
hci_conn_failed(conn, reason);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void hci_conn_unlink(struct hci_conn *conn)
|
||||
{
|
||||
struct hci_dev *hdev = conn->hdev;
|
||||
|
@ -1066,14 +1089,7 @@ static void hci_conn_unlink(struct hci_conn *conn)
|
|||
if (!test_bit(HCI_UP, &hdev->flags))
|
||||
continue;
|
||||
|
||||
/* Due to race, SCO connection might be not established
|
||||
* yet at this point. Delete it now, otherwise it is
|
||||
* possible for it to be stuck and can't be deleted.
|
||||
*/
|
||||
if ((child->type == SCO_LINK ||
|
||||
child->type == ESCO_LINK) &&
|
||||
HCI_CONN_HANDLE_UNSET(child->handle))
|
||||
hci_conn_del(child);
|
||||
hci_conn_cleanup_child(child, conn->abort_reason);
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue
Block a user