mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
Bluetooth: hci_conn: Fix possible UAF
This fixes the following trace:
==================================================================
BUG: KASAN: slab-use-after-free in hci_conn_del+0xba/0x3a0
Write of size 8 at addr ffff88800208e9c8 by task iso-tester/31
CPU: 0 PID: 31 Comm: iso-tester Not tainted 6.3.0-rc2-g991aa4a69a47
#4716
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.1-2.fc36
04/01/2014
Call Trace:
<TASK>
dump_stack_lvl+0x1d/0x70
print_report+0xce/0x610
? __virt_addr_valid+0xd4/0x150
? hci_conn_del+0xba/0x3a0
kasan_report+0xdd/0x110
? hci_conn_del+0xba/0x3a0
hci_conn_del+0xba/0x3a0
hci_conn_hash_flush+0xf2/0x120
hci_dev_close_sync+0x388/0x920
hci_unregister_dev+0x122/0x260
vhci_release+0x4f/0x90
__fput+0x102/0x430
task_work_run+0xf1/0x160
? __pfx_task_work_run+0x10/0x10
? mark_held_locks+0x24/0x90
exit_to_user_mode_prepare+0x170/0x180
syscall_exit_to_user_mode+0x19/0x50
do_syscall_64+0x4e/0x90
entry_SYSCALL_64_after_hwframe+0x70/0xda
Fixes: 0f00cd322d
("Bluetooth: Free potentially unfreed SCO connection")
Link: https://syzkaller.appspot.com/bug?extid=8bb72f86fc823817bc5d
Cc: <stable@vger.kernel.org>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
975abc0c90
commit
5dc7d23e16
@ -1068,6 +1068,17 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
|
||||
return conn;
|
||||
}
|
||||
|
||||
static bool hci_conn_unlink(struct hci_conn *conn)
|
||||
{
|
||||
if (!conn->link)
|
||||
return false;
|
||||
|
||||
conn->link->link = NULL;
|
||||
conn->link = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int hci_conn_del(struct hci_conn *conn)
|
||||
{
|
||||
struct hci_dev *hdev = conn->hdev;
|
||||
@ -1079,15 +1090,16 @@ int hci_conn_del(struct hci_conn *conn)
|
||||
cancel_delayed_work_sync(&conn->idle_work);
|
||||
|
||||
if (conn->type == ACL_LINK) {
|
||||
struct hci_conn *sco = conn->link;
|
||||
if (sco) {
|
||||
sco->link = NULL;
|
||||
struct hci_conn *link = conn->link;
|
||||
|
||||
if (link) {
|
||||
hci_conn_unlink(conn);
|
||||
/* 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 (sco->handle == HCI_CONN_HANDLE_UNSET)
|
||||
hci_conn_del(sco);
|
||||
if (link->handle == HCI_CONN_HANDLE_UNSET)
|
||||
hci_conn_del(link);
|
||||
}
|
||||
|
||||
/* Unacked frames */
|
||||
@ -1103,7 +1115,7 @@ int hci_conn_del(struct hci_conn *conn)
|
||||
struct hci_conn *acl = conn->link;
|
||||
|
||||
if (acl) {
|
||||
acl->link = NULL;
|
||||
hci_conn_unlink(conn);
|
||||
hci_conn_drop(acl);
|
||||
}
|
||||
|
||||
@ -2434,6 +2446,12 @@ void hci_conn_hash_flush(struct hci_dev *hdev)
|
||||
c->state = BT_CLOSED;
|
||||
|
||||
hci_disconn_cfm(c, HCI_ERROR_LOCAL_HOST_TERM);
|
||||
|
||||
/* Unlink before deleting otherwise it is possible that
|
||||
* hci_conn_del removes the link which may cause the list to
|
||||
* contain items already freed.
|
||||
*/
|
||||
hci_conn_unlink(c);
|
||||
hci_conn_del(c);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user