* [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in hci_send_acl
@ 2023-08-21 16:26 syzbot
2023-08-31 18:07 ` syzbot
2024-01-14 14:37 ` syzbot
0 siblings, 2 replies; 11+ messages in thread
From: syzbot @ 2023-08-21 16:26 UTC (permalink / raw)
To: johan.hedberg, linux-bluetooth, linux-kernel, luiz.dentz, marcel,
syzkaller-bugs
Hello,
syzbot found the following issue on:
HEAD commit: 7271b2a53042 Add linux-next specific files for 20230818
git tree: linux-next
console+strace: https://syzkaller.appspot.com/x/log.txt?x=13404b6ba80000
kernel config: https://syzkaller.appspot.com/x/.config?x=1936af09cdef7dd6
dashboard link: https://syzkaller.appspot.com/bug?extid=a0c80b06ae2cb8895bc4
compiler: gcc (Debian 12.2.0-14) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=13506923a80000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=147569efa80000
Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/d81109bc02c1/disk-7271b2a5.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/4b3bf8e2a4f7/vmlinux-7271b2a5.xz
kernel image: https://storage.googleapis.com/syzbot-assets/6404cd473c1e/bzImage-7271b2a5.xz
IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+a0c80b06ae2cb8895bc4@syzkaller.appspotmail.com
==================================================================
BUG: KASAN: slab-use-after-free in hci_send_acl+0xdf4/0xf30 net/bluetooth/hci_core.c:3228
Read of size 8 at addr ffff888025635618 by task kworker/1:1/27
CPU: 1 PID: 27 Comm: kworker/1:1 Not tainted 6.5.0-rc6-next-20230818-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/26/2023
Workqueue: events l2cap_info_timeout
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:88 [inline]
dump_stack_lvl+0xd9/0x1b0 lib/dump_stack.c:106
print_address_description mm/kasan/report.c:364 [inline]
print_report+0xc4/0x620 mm/kasan/report.c:475
kasan_report+0xda/0x110 mm/kasan/report.c:588
hci_send_acl+0xdf4/0xf30 net/bluetooth/hci_core.c:3228
l2cap_send_cmd+0x6dd/0x920 net/bluetooth/l2cap_core.c:977
l2cap_send_conn_req+0x1e5/0x260 net/bluetooth/l2cap_core.c:1286
l2cap_start_connection+0x11e/0x420 net/bluetooth/l2cap_core.c:1514
l2cap_conn_start+0x7ae/0xa40 net/bluetooth/l2cap_core.c:1661
process_one_work+0x887/0x15d0 kernel/workqueue.c:2630
process_scheduled_works kernel/workqueue.c:2703 [inline]
worker_thread+0x8bb/0x1290 kernel/workqueue.c:2784
kthread+0x33a/0x430 kernel/kthread.c:388
ret_from_fork+0x45/0x80 arch/x86/kernel/process.c:147
ret_from_fork_asm+0x11/0x20 arch/x86/entry/entry_64.S:304
</TASK>
Allocated by task 5046:
kasan_save_stack+0x33/0x50 mm/kasan/common.c:45
kasan_set_track+0x25/0x30 mm/kasan/common.c:52
____kasan_kmalloc mm/kasan/common.c:374 [inline]
__kasan_kmalloc+0xa2/0xb0 mm/kasan/common.c:383
kmalloc include/linux/slab.h:600 [inline]
kzalloc include/linux/slab.h:721 [inline]
hci_chan_create+0xa6/0x3a0 net/bluetooth/hci_conn.c:2691
l2cap_conn_add.part.0+0x1a/0xdf0 net/bluetooth/l2cap_core.c:7841
l2cap_conn_add include/net/bluetooth/l2cap.h:866 [inline]
l2cap_chan_connect+0x15b9/0x2140 net/bluetooth/l2cap_core.c:8053
bt_6lowpan_connect net/bluetooth/6lowpan.c:894 [inline]
lowpan_control_write+0x3d6/0x730 net/bluetooth/6lowpan.c:1129
full_proxy_write+0x124/0x190 fs/debugfs/file.c:236
vfs_write+0x2a4/0xe40 fs/read_write.c:582
ksys_write+0x12f/0x250 fs/read_write.c:637
do_syscall_x64 arch/x86/entry/common.c:50 [inline]
do_syscall_64+0x38/0xb0 arch/x86/entry/common.c:80
entry_SYSCALL_64_after_hwframe+0x63/0xcd
Freed by task 50:
kasan_save_stack+0x33/0x50 mm/kasan/common.c:45
kasan_set_track+0x25/0x30 mm/kasan/common.c:52
kasan_save_free_info+0x2b/0x40 mm/kasan/generic.c:522
____kasan_slab_free mm/kasan/common.c:236 [inline]
____kasan_slab_free+0x15b/0x1b0 mm/kasan/common.c:200
kasan_slab_free include/linux/kasan.h:164 [inline]
slab_free_hook mm/slub.c:1800 [inline]
slab_free_freelist_hook+0x114/0x1e0 mm/slub.c:1826
slab_free mm/slub.c:3809 [inline]
__kmem_cache_free+0xb8/0x2f0 mm/slub.c:3822
hci_chan_list_flush+0x81/0xf0 net/bluetooth/hci_conn.c:2731
hci_conn_cleanup net/bluetooth/hci_conn.c:152 [inline]
hci_conn_del+0x1fc/0xd10 net/bluetooth/hci_conn.c:1140
hci_abort_conn_sync+0xacb/0xe20 net/bluetooth/hci_sync.c:5432
abort_conn_sync+0x18e/0x3a0 net/bluetooth/hci_conn.c:2878
hci_cmd_sync_work+0x1a4/0x3c0 net/bluetooth/hci_sync.c:306
process_one_work+0x887/0x15d0 kernel/workqueue.c:2630
process_scheduled_works kernel/workqueue.c:2703 [inline]
worker_thread+0x8bb/0x1290 kernel/workqueue.c:2784
kthread+0x33a/0x430 kernel/kthread.c:388
ret_from_fork+0x45/0x80 arch/x86/kernel/process.c:147
ret_from_fork_asm+0x11/0x20 arch/x86/entry/entry_64.S:304
Last potentially related work creation:
kasan_save_stack+0x33/0x50 mm/kasan/common.c:45
__kasan_record_aux_stack+0xbc/0xd0 mm/kasan/generic.c:492
kvfree_call_rcu+0x70/0xbe0 kernel/rcu/tree.c:3373
kernfs_unlink_open_file+0x3b6/0x4b0 fs/kernfs/file.c:633
kernfs_fop_release+0xec/0x1e0 fs/kernfs/file.c:805
__fput+0x3f7/0xa70 fs/file_table.c:384
__fput_sync+0x47/0x50 fs/file_table.c:465
__do_sys_close fs/open.c:1572 [inline]
__se_sys_close fs/open.c:1557 [inline]
__x64_sys_close+0x87/0xf0 fs/open.c:1557
do_syscall_x64 arch/x86/entry/common.c:50 [inline]
do_syscall_64+0x38/0xb0 arch/x86/entry/common.c:80
entry_SYSCALL_64_after_hwframe+0x63/0xcd
Second to last potentially related work creation:
kasan_save_stack+0x33/0x50 mm/kasan/common.c:45
__kasan_record_aux_stack+0xbc/0xd0 mm/kasan/generic.c:492
kvfree_call_rcu+0x70/0xbe0 kernel/rcu/tree.c:3373
kernfs_unlink_open_file+0x3b6/0x4b0 fs/kernfs/file.c:633
kernfs_fop_release+0xec/0x1e0 fs/kernfs/file.c:805
__fput+0x3f7/0xa70 fs/file_table.c:384
__fput_sync+0x47/0x50 fs/file_table.c:465
__do_sys_close fs/open.c:1572 [inline]
__se_sys_close fs/open.c:1557 [inline]
__x64_sys_close+0x87/0xf0 fs/open.c:1557
do_syscall_x64 arch/x86/entry/common.c:50 [inline]
do_syscall_64+0x38/0xb0 arch/x86/entry/common.c:80
entry_SYSCALL_64_after_hwframe+0x63/0xcd
The buggy address belongs to the object at ffff888025635600
which belongs to the cache kmalloc-128 of size 128
The buggy address is located 24 bytes inside of
freed 128-byte region [ffff888025635600, ffff888025635680)
The buggy address belongs to the physical page:
page:ffffea0000958d40 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x25635
flags: 0xfff00000000800(slab|node=0|zone=1|lastcpupid=0x7ff)
page_type: 0xffffffff()
raw: 00fff00000000800 ffff888012c418c0 dead000000000100 dead000000000122
raw: 0000000000000000 0000000000100010 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected
page_owner tracks the page as allocated
page last allocated via order 0, migratetype Unmovable, gfp_mask 0x12cc0(GFP_KERNEL|__GFP_NOWARN|__GFP_NORETRY), pid 4500, tgid 4500 (udevd), ts 28013160887, free_ts 27864795775
set_page_owner include/linux/page_owner.h:31 [inline]
post_alloc_hook+0x2cf/0x340 mm/page_alloc.c:1536
prep_new_page mm/page_alloc.c:1543 [inline]
get_page_from_freelist+0x10d7/0x31b0 mm/page_alloc.c:3219
__alloc_pages+0x1d0/0x4a0 mm/page_alloc.c:4475
alloc_pages+0x1a9/0x270 mm/mempolicy.c:2298
alloc_slab_page mm/slub.c:1870 [inline]
allocate_slab+0x251/0x380 mm/slub.c:2017
new_slab mm/slub.c:2070 [inline]
___slab_alloc+0x8be/0x1570 mm/slub.c:3223
__slab_alloc.constprop.0+0x56/0xa0 mm/slub.c:3322
__slab_alloc_node mm/slub.c:3375 [inline]
slab_alloc_node mm/slub.c:3468 [inline]
__kmem_cache_alloc_node+0x137/0x350 mm/slub.c:3517
kmalloc_trace+0x25/0xe0 mm/slab_common.c:1095
kmalloc include/linux/slab.h:600 [inline]
kzalloc include/linux/slab.h:721 [inline]
kernfs_get_open_node fs/kernfs/file.c:572 [inline]
kernfs_fop_open+0xad1/0xe00 fs/kernfs/file.c:740
do_dentry_open+0x88b/0x1730 fs/open.c:929
do_open fs/namei.c:3636 [inline]
path_openat+0x19af/0x29c0 fs/namei.c:3793
do_filp_open+0x1de/0x430 fs/namei.c:3820
do_sys_openat2+0x176/0x1e0 fs/open.c:1422
do_sys_open fs/open.c:1437 [inline]
__do_sys_openat fs/open.c:1453 [inline]
__se_sys_openat fs/open.c:1448 [inline]
__x64_sys_openat+0x175/0x210 fs/open.c:1448
do_syscall_x64 arch/x86/entry/common.c:50 [inline]
do_syscall_64+0x38/0xb0 arch/x86/entry/common.c:80
page last free stack trace:
reset_page_owner include/linux/page_owner.h:24 [inline]
free_pages_prepare mm/page_alloc.c:1136 [inline]
free_unref_page_prepare+0x476/0xa40 mm/page_alloc.c:2348
free_unref_page+0x33/0x3b0 mm/page_alloc.c:2441
qlink_free mm/kasan/quarantine.c:166 [inline]
qlist_free_all+0x6a/0x170 mm/kasan/quarantine.c:185
kasan_quarantine_reduce+0x18b/0x1d0 mm/kasan/quarantine.c:292
__kasan_slab_alloc+0x65/0x90 mm/kasan/common.c:305
kasan_slab_alloc include/linux/kasan.h:188 [inline]
slab_post_alloc_hook mm/slab.h:762 [inline]
slab_alloc_node mm/slub.c:3478 [inline]
slab_alloc mm/slub.c:3486 [inline]
__kmem_cache_alloc_lru mm/slub.c:3493 [inline]
kmem_cache_alloc+0x172/0x3b0 mm/slub.c:3502
getname_flags.part.0+0x50/0x4d0 fs/namei.c:140
getname_flags include/linux/audit.h:319 [inline]
getname+0x90/0xe0 fs/namei.c:219
do_sys_openat2+0x100/0x1e0 fs/open.c:1416
do_sys_open fs/open.c:1437 [inline]
__do_sys_openat fs/open.c:1453 [inline]
__se_sys_openat fs/open.c:1448 [inline]
__x64_sys_openat+0x175/0x210 fs/open.c:1448
do_syscall_x64 arch/x86/entry/common.c:50 [inline]
do_syscall_64+0x38/0xb0 arch/x86/entry/common.c:80
entry_SYSCALL_64_after_hwframe+0x63/0xcd
Memory state around the buggy address:
ffff888025635500: 00 00 00 00 00 00 00 00 00 00 00 00 00 fc fc fc
ffff888025635580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>ffff888025635600: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff888025635680: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff888025635700: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================
---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.
syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.
If the bug is already fixed, let syzbot know by replying with:
#syz fix: exact-commit-title
If you want syzbot to run the reproducer, reply with:
#syz test: git://repo/address.git branch-or-commit-hash
If you attach or paste a git patch, syzbot will apply it before testing.
If you want to overwrite bug's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)
If the bug is a duplicate of another bug, reply with:
#syz dup: exact-subject-of-another-report
If you want to undo deduplication, reply with:
#syz undup
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in hci_send_acl
2023-08-25 19:01 [PATCH] Bluetooth: hci_conn: verify connection is to be aborted before doing it Pauli Virtanen
@ 2023-08-25 19:34 ` syzbot
0 siblings, 0 replies; 11+ messages in thread
From: syzbot @ 2023-08-25 19:34 UTC (permalink / raw)
To: linux-bluetooth, pav, syzkaller-bugs
Hello,
syzbot has tested the proposed patch and the reproducer did not trigger any issue:
Reported-and-tested-by: syzbot+a0c80b06ae2cb8895bc4@syzkaller.appspotmail.com
Tested on:
commit: 2a05334d Bluetooth: btusb: Do not call kfree_skb() und..
git tree: git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master
console output: https://syzkaller.appspot.com/x/log.txt?x=1521e55ba80000
kernel config: https://syzkaller.appspot.com/x/.config?x=e532e371ba4b65ca
dashboard link: https://syzkaller.appspot.com/bug?extid=a0c80b06ae2cb8895bc4
compiler: gcc (Debian 12.2.0-14) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40
patch: https://syzkaller.appspot.com/x/patch.diff?x=11eaff5ba80000
Note: testing is done by a robot and is best-effort only.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in hci_send_acl
2023-08-21 16:26 syzbot
@ 2023-08-31 18:07 ` syzbot
2024-01-14 14:37 ` syzbot
1 sibling, 0 replies; 11+ messages in thread
From: syzbot @ 2023-08-31 18:07 UTC (permalink / raw)
To: hdanton, johan.hedberg, linux-bluetooth, linux-kernel, luiz.dentz,
luiz.von.dentz, marcel, pav, syzkaller-bugs
syzbot has bisected this issue to:
commit 45c37c4e9c9aab5bb1cf5778d8e5ebd9f9ad820a
Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: Wed Aug 9 23:49:33 2023 +0000
Bluetooth: hci_sync: Fix UAF in hci_disconnect_all_sync
bisection log: https://syzkaller.appspot.com/x/bisect.txt?x=1042c5ffa80000
start commit: 7271b2a53042 Add linux-next specific files for 20230818
git tree: linux-next
final oops: https://syzkaller.appspot.com/x/report.txt?x=1242c5ffa80000
console output: https://syzkaller.appspot.com/x/log.txt?x=1442c5ffa80000
kernel config: https://syzkaller.appspot.com/x/.config?x=1936af09cdef7dd6
dashboard link: https://syzkaller.appspot.com/bug?extid=a0c80b06ae2cb8895bc4
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=13506923a80000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=147569efa80000
Reported-by: syzbot+a0c80b06ae2cb8895bc4@syzkaller.appspotmail.com
Fixes: 45c37c4e9c9a ("Bluetooth: hci_sync: Fix UAF in hci_disconnect_all_sync")
For information about bisection process see: https://goo.gl/tpsmEJ#bisection
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v2 1/2] Bluetooth: hci_sync: always check if connection is alive before deleting
@ 2023-09-30 12:53 Pauli Virtanen
2023-09-30 12:53 ` [PATCH v2 2/2] Bluetooth: hci_conn: verify connection is to be aborted before doing it Pauli Virtanen
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Pauli Virtanen @ 2023-09-30 12:53 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Pauli Virtanen
In hci_abort_conn_sync it is possible that conn is deleted concurrently
by something else, also e.g. when waiting for hdev->lock. This causes
double deletion of the conn, so UAF or conn_hash.list corruption.
Fix by having all code paths check that the connection is still in
conn_hash before deleting it, while holding hdev->lock which prevents
any races.
Log (when powering off while BAP streaming, occurs rarely):
=======================================================================
kernel BUG at lib/list_debug.c:56!
...
? __list_del_entry_valid (lib/list_debug.c:56)
hci_conn_del (net/bluetooth/hci_conn.c:154) bluetooth
hci_abort_conn_sync (net/bluetooth/hci_sync.c:5415) bluetooth
? __pfx_hci_abort_conn_sync+0x10/0x10 [bluetooth]
? lock_release+0x1d5/0x3c0
? hci_disconnect_all_sync.constprop.0+0xb2/0x230 [bluetooth]
? __pfx_lock_release+0x10/0x10
? __kmem_cache_free+0x14d/0x2e0
hci_disconnect_all_sync.constprop.0+0xda/0x230 [bluetooth]
? __pfx_hci_disconnect_all_sync.constprop.0+0x10/0x10 [bluetooth]
? hci_clear_adv_sync+0x14f/0x170 [bluetooth]
? __pfx_set_powered_sync+0x10/0x10 [bluetooth]
hci_set_powered_sync+0x293/0x450 [bluetooth]
=======================================================================
Fixes: 94d9ba9f9888 ("Bluetooth: hci_sync: Fix UAF in hci_disconnect_all_sync")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
---
Notes:
v2: rebased
net/bluetooth/hci_sync.c | 26 ++++++++++++--------------
1 file changed, 12 insertions(+), 14 deletions(-)
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index 3640d73f9595..c6f57af88bfd 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -5380,6 +5380,7 @@ int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason)
{
int err = 0;
u16 handle = conn->handle;
+ bool disconnect = false;
struct hci_conn *c;
switch (conn->state) {
@@ -5395,24 +5396,15 @@ int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason)
break;
case BT_OPEN:
case BT_BOUND:
- hci_dev_lock(hdev);
- hci_conn_failed(conn, reason);
- hci_dev_unlock(hdev);
- return 0;
+ break;
default:
- hci_dev_lock(hdev);
- conn->state = BT_CLOSED;
- hci_disconn_cfm(conn, reason);
- hci_conn_del(conn);
- hci_dev_unlock(hdev);
- return 0;
+ disconnect = true;
+ break;
}
hci_dev_lock(hdev);
- /* Check if the connection hasn't been cleanup while waiting
- * commands to complete.
- */
+ /* Check if the connection has been cleaned up concurrently */
c = hci_conn_hash_lookup_handle(hdev, handle);
if (!c || c != conn) {
err = 0;
@@ -5424,7 +5416,13 @@ int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason)
* or in case of LE it was still scanning so it can be cleanup
* safely.
*/
- hci_conn_failed(conn, reason);
+ if (disconnect) {
+ conn->state = BT_CLOSED;
+ hci_disconn_cfm(conn, reason);
+ hci_conn_del(conn);
+ } else {
+ hci_conn_failed(conn, reason);
+ }
unlock:
hci_dev_unlock(hdev);
--
2.41.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v2 2/2] Bluetooth: hci_conn: verify connection is to be aborted before doing it
2023-09-30 12:53 [PATCH v2 1/2] Bluetooth: hci_sync: always check if connection is alive before deleting Pauli Virtanen
@ 2023-09-30 12:53 ` Pauli Virtanen
2023-09-30 13:28 ` [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in hci_send_acl syzbot
2023-10-02 23:22 ` [PATCH v2 2/2] Bluetooth: hci_conn: verify connection is to be aborted before doing it Luiz Augusto von Dentz
2023-09-30 13:36 ` [v2,1/2] Bluetooth: hci_sync: always check if connection is alive before deleting bluez.test.bot
2023-10-03 17:10 ` [PATCH v2 1/2] " patchwork-bot+bluetooth
2 siblings, 2 replies; 11+ messages in thread
From: Pauli Virtanen @ 2023-09-30 12:53 UTC (permalink / raw)
To: linux-bluetooth
Cc: Pauli Virtanen, syzkaller-bugs, syzbot+a0c80b06ae2cb8895bc4
There is a race condition where a connection handle is reused, after
hci_abort_conn but before abort_conn_sync is processed in hci_sync. In
this case, hci_abort_conn_sync ends up working on the wrong connection,
which can have abort_reason==0, in which case hci_connect_cfm is called
with success status and then connection is deleted, which causes various
use-after-free.
Fix by checking abort_reason is nonzero before calling
hci_abort_conn_sync. If it's zero, then the connection is probably a
different one than we expected and should not be aborted.
Also fix some theoretical UAF / races, where something frees the conn
while hci_abort_conn_sync is working on it.
Fixes: a13f316e90fd ("Bluetooth: hci_conn: Consolidate code for aborting connections")
Reported-by: syzbot+a0c80b06ae2cb8895bc4@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/linux-bluetooth/0000000000005ab984060371583e@google.com/
Signed-off-by: Pauli Virtanen <pav@iki.fi>
---
Notes:
v2: drop one probably not necessary WARN_ON
Not sure how you'd hit this condition in real controller, but syzbot
does end up calling hci_abort_conn_sync with reason == 0 which then
causes havoc.
This can be verified: with a patch that changes abort_conn_sync to
2874 conn = hci_conn_hash_lookup_handle(hdev, handle);
2875 if (!conn || WARN_ON(!conn->abort_reason))
2876 return 0;
https://syzkaller.appspot.com/text?tag=Patch&x=16eff740680000
it hits that WARN_ON:
https://syzkaller.appspot.com/x/log.txt?x=10affb97a80000
#syz test git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master
net/bluetooth/hci_conn.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index e62a5f368a51..22de82071e35 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -2901,12 +2901,25 @@ static int abort_conn_sync(struct hci_dev *hdev, void *data)
{
struct hci_conn *conn;
u16 handle = PTR_UINT(data);
+ u8 reason;
+ int err;
+
+ rcu_read_lock();
conn = hci_conn_hash_lookup_handle(hdev, handle);
+ if (conn) {
+ reason = READ_ONCE(conn->abort_reason);
+ conn = reason ? hci_conn_get(conn) : NULL;
+ }
+
+ rcu_read_unlock();
+
if (!conn)
return 0;
- return hci_abort_conn_sync(hdev, conn, conn->abort_reason);
+ err = hci_abort_conn_sync(hdev, conn, reason);
+ hci_conn_put(conn);
+ return err;
}
int hci_abort_conn(struct hci_conn *conn, u8 reason)
@@ -2918,6 +2931,8 @@ int hci_abort_conn(struct hci_conn *conn, u8 reason)
*/
if (conn->abort_reason)
return 0;
+ if (WARN_ON(!reason))
+ reason = HCI_ERROR_UNSPECIFIED;
bt_dev_dbg(hdev, "handle 0x%2.2x reason 0x%2.2x", conn->handle, reason);
--
2.41.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in hci_send_acl
2023-09-30 12:53 ` [PATCH v2 2/2] Bluetooth: hci_conn: verify connection is to be aborted before doing it Pauli Virtanen
@ 2023-09-30 13:28 ` syzbot
2023-10-02 23:22 ` [PATCH v2 2/2] Bluetooth: hci_conn: verify connection is to be aborted before doing it Luiz Augusto von Dentz
1 sibling, 0 replies; 11+ messages in thread
From: syzbot @ 2023-09-30 13:28 UTC (permalink / raw)
To: linux-bluetooth, pav, syzkaller-bugs
Hello,
syzbot has tested the proposed patch and the reproducer did not trigger any issue:
Reported-and-tested-by: syzbot+a0c80b06ae2cb8895bc4@syzkaller.appspotmail.com
Tested on:
commit: 62dc2425 Bluetooth: ISO: Fix invalid context error
git tree: git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master
console output: https://syzkaller.appspot.com/x/log.txt?x=12897062680000
kernel config: https://syzkaller.appspot.com/x/.config?x=3d83e69abefedb6e
dashboard link: https://syzkaller.appspot.com/bug?extid=a0c80b06ae2cb8895bc4
compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40
userspace arch: arm64
patch: https://syzkaller.appspot.com/x/patch.diff?x=14a7711a680000
Note: testing is done by a robot and is best-effort only.
^ permalink raw reply [flat|nested] 11+ messages in thread
* RE: [v2,1/2] Bluetooth: hci_sync: always check if connection is alive before deleting
2023-09-30 12:53 [PATCH v2 1/2] Bluetooth: hci_sync: always check if connection is alive before deleting Pauli Virtanen
2023-09-30 12:53 ` [PATCH v2 2/2] Bluetooth: hci_conn: verify connection is to be aborted before doing it Pauli Virtanen
@ 2023-09-30 13:36 ` bluez.test.bot
2023-10-03 17:10 ` [PATCH v2 1/2] " patchwork-bot+bluetooth
2 siblings, 0 replies; 11+ messages in thread
From: bluez.test.bot @ 2023-09-30 13:36 UTC (permalink / raw)
To: linux-bluetooth, pav
[-- Attachment #1: Type: text/plain, Size: 2942 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=789014
---Test result---
Test Summary:
CheckPatch PASS 1.53 seconds
GitLint FAIL 0.86 seconds
SubjectPrefix PASS 0.20 seconds
BuildKernel PASS 33.69 seconds
CheckAllWarning PASS 36.16 seconds
CheckSparse PASS 41.46 seconds
CheckSmatch PASS 115.45 seconds
BuildKernel32 PASS 31.93 seconds
TestRunnerSetup PASS 489.12 seconds
TestRunner_l2cap-tester PASS 30.32 seconds
TestRunner_iso-tester PASS 49.69 seconds
TestRunner_bnep-tester PASS 9.79 seconds
TestRunner_mgmt-tester PASS 214.41 seconds
TestRunner_rfcomm-tester PASS 14.96 seconds
TestRunner_sco-tester PASS 18.53 seconds
TestRunner_ioctl-tester PASS 16.93 seconds
TestRunner_mesh-tester PASS 12.59 seconds
TestRunner_smp-tester PASS 13.38 seconds
TestRunner_userchan-tester PASS 10.31 seconds
IncrementalBuild PASS 37.23 seconds
Details
##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
[v2,1/2] Bluetooth: hci_sync: always check if connection is alive before deleting
WARNING: I3 - ignore-body-lines: gitlint will be switching from using Python regex 'match' (match beginning) to 'search' (match anywhere) semantics. Please review your ignore-body-lines.regex option accordingly. To remove this warning, set general.regex-style-search=True. More details: https://jorisroovers.github.io/gitlint/configuration/#regex-style-search
1: T1 Title exceeds max length (81>80): "[v2,1/2] Bluetooth: hci_sync: always check if connection is alive before deleting"
[v2,2/2] Bluetooth: hci_conn: verify connection is to be aborted before doing it
WARNING: I3 - ignore-body-lines: gitlint will be switching from using Python regex 'match' (match beginning) to 'search' (match anywhere) semantics. Please review your ignore-body-lines.regex option accordingly. To remove this warning, set general.regex-style-search=True. More details: https://jorisroovers.github.io/gitlint/configuration/#regex-style-search
18: B1 Line exceeds max length (88>80): "Closes: https://lore.kernel.org/linux-bluetooth/0000000000005ab984060371583e@google.com/"
31: B3 Line contains hard tab characters (\t): " 2874 conn = hci_conn_hash_lookup_handle(hdev, handle);"
32: B3 Line contains hard tab characters (\t): " 2875 if (!conn || WARN_ON(!conn->abort_reason))"
33: B3 Line contains hard tab characters (\t): " 2876 return 0;"
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 2/2] Bluetooth: hci_conn: verify connection is to be aborted before doing it
2023-09-30 12:53 ` [PATCH v2 2/2] Bluetooth: hci_conn: verify connection is to be aborted before doing it Pauli Virtanen
2023-09-30 13:28 ` [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in hci_send_acl syzbot
@ 2023-10-02 23:22 ` Luiz Augusto von Dentz
2023-10-03 16:41 ` Pauli Virtanen
1 sibling, 1 reply; 11+ messages in thread
From: Luiz Augusto von Dentz @ 2023-10-02 23:22 UTC (permalink / raw)
To: Pauli Virtanen
Cc: linux-bluetooth, syzkaller-bugs, syzbot+a0c80b06ae2cb8895bc4
Hi Pauli,
On Sat, Sep 30, 2023 at 3:25 PM Pauli Virtanen <pav@iki.fi> wrote:
>
> There is a race condition where a connection handle is reused, after
> hci_abort_conn but before abort_conn_sync is processed in hci_sync. In
> this case, hci_abort_conn_sync ends up working on the wrong connection,
> which can have abort_reason==0, in which case hci_connect_cfm is called
> with success status and then connection is deleted, which causes various
> use-after-free.
>
> Fix by checking abort_reason is nonzero before calling
> hci_abort_conn_sync. If it's zero, then the connection is probably a
> different one than we expected and should not be aborted.
>
> Also fix some theoretical UAF / races, where something frees the conn
> while hci_abort_conn_sync is working on it.
>
> Fixes: a13f316e90fd ("Bluetooth: hci_conn: Consolidate code for aborting connections")
> Reported-by: syzbot+a0c80b06ae2cb8895bc4@syzkaller.appspotmail.com
> Closes: https://lore.kernel.org/linux-bluetooth/0000000000005ab984060371583e@google.com/
> Signed-off-by: Pauli Virtanen <pav@iki.fi>
> ---
>
> Notes:
> v2: drop one probably not necessary WARN_ON
>
> Not sure how you'd hit this condition in real controller, but syzbot
> does end up calling hci_abort_conn_sync with reason == 0 which then
> causes havoc.
>
> This can be verified: with a patch that changes abort_conn_sync to
>
> 2874 conn = hci_conn_hash_lookup_handle(hdev, handle);
> 2875 if (!conn || WARN_ON(!conn->abort_reason))
> 2876 return 0;
>
> https://syzkaller.appspot.com/text?tag=Patch&x=16eff740680000
>
> it hits that WARN_ON:
>
> https://syzkaller.appspot.com/x/log.txt?x=10affb97a80000
>
> #syz test git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master
>
> net/bluetooth/hci_conn.c | 17 ++++++++++++++++-
> 1 file changed, 16 insertions(+), 1 deletion(-)
>
> diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
> index e62a5f368a51..22de82071e35 100644
> --- a/net/bluetooth/hci_conn.c
> +++ b/net/bluetooth/hci_conn.c
> @@ -2901,12 +2901,25 @@ static int abort_conn_sync(struct hci_dev *hdev, void *data)
> {
> struct hci_conn *conn;
> u16 handle = PTR_UINT(data);
> + u8 reason;
> + int err;
> +
> + rcu_read_lock();
>
> conn = hci_conn_hash_lookup_handle(hdev, handle);
> + if (conn) {
> + reason = READ_ONCE(conn->abort_reason);
> + conn = reason ? hci_conn_get(conn) : NULL;
> + }
> +
> + rcu_read_unlock();
> +
> if (!conn)
> return 0;
>
> - return hci_abort_conn_sync(hdev, conn, conn->abort_reason);
> + err = hci_abort_conn_sync(hdev, conn, reason);
> + hci_conn_put(conn);
> + return err;
> }
>
> int hci_abort_conn(struct hci_conn *conn, u8 reason)
> @@ -2918,6 +2931,8 @@ int hci_abort_conn(struct hci_conn *conn, u8 reason)
> */
> if (conn->abort_reason)
> return 0;
> + if (WARN_ON(!reason))
> + reason = HCI_ERROR_UNSPECIFIED;
>
> bt_dev_dbg(hdev, "handle 0x%2.2x reason 0x%2.2x", conn->handle, reason);
>
> --
> 2.41.0
Don't really like where this is going, the culprit here seems that we
are not able to cancel the callback when freeing the hci_conn so it
stays enqueued while the new connection is created with the same
handle, so I think we need to introduce a function that cancel queued
like Ive sent sometime back, that way we don't need to keep trying to
check if it is the same connection or not.
--
Luiz Augusto von Dentz
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 2/2] Bluetooth: hci_conn: verify connection is to be aborted before doing it
2023-10-02 23:22 ` [PATCH v2 2/2] Bluetooth: hci_conn: verify connection is to be aborted before doing it Luiz Augusto von Dentz
@ 2023-10-03 16:41 ` Pauli Virtanen
0 siblings, 0 replies; 11+ messages in thread
From: Pauli Virtanen @ 2023-10-03 16:41 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
Hi Luiz,
ma, 2023-10-02 kello 16:22 -0700, Luiz Augusto von Dentz kirjoitti:
> Hi Pauli,
>
> On Sat, Sep 30, 2023 at 3:25 PM Pauli Virtanen <pav@iki.fi> wrote:
> >
> > There is a race condition where a connection handle is reused, after
> > hci_abort_conn but before abort_conn_sync is processed in hci_sync. In
> > this case, hci_abort_conn_sync ends up working on the wrong connection,
> > which can have abort_reason==0, in which case hci_connect_cfm is called
> > with success status and then connection is deleted, which causes various
> > use-after-free.
> >
> > Fix by checking abort_reason is nonzero before calling
> > hci_abort_conn_sync. If it's zero, then the connection is probably a
> > different one than we expected and should not be aborted.
> >
> > Also fix some theoretical UAF / races, where something frees the conn
> > while hci_abort_conn_sync is working on it.
> >
> > Fixes: a13f316e90fd ("Bluetooth: hci_conn: Consolidate code for aborting connections")
> > Reported-by: syzbot+a0c80b06ae2cb8895bc4@syzkaller.appspotmail.com
> > Closes: https://lore.kernel.org/linux-bluetooth/0000000000005ab984060371583e@google.com/
> > Signed-off-by: Pauli Virtanen <pav@iki.fi>
> > ---
> >
> > Notes:
> > v2: drop one probably not necessary WARN_ON
> >
> > Not sure how you'd hit this condition in real controller, but syzbot
> > does end up calling hci_abort_conn_sync with reason == 0 which then
> > causes havoc.
> >
> > This can be verified: with a patch that changes abort_conn_sync to
> >
> > 2874 conn = hci_conn_hash_lookup_handle(hdev, handle);
> > 2875 if (!conn || WARN_ON(!conn->abort_reason))
> > 2876 return 0;
> >
> > https://syzkaller.appspot.com/text?tag=Patch&x=16eff740680000
> >
> > it hits that WARN_ON:
> >
> > https://syzkaller.appspot.com/x/log.txt?x=10affb97a80000
> >
> > #syz test git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master
> >
> > net/bluetooth/hci_conn.c | 17 ++++++++++++++++-
> > 1 file changed, 16 insertions(+), 1 deletion(-)
> >
> > diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
> > index e62a5f368a51..22de82071e35 100644
> > --- a/net/bluetooth/hci_conn.c
> > +++ b/net/bluetooth/hci_conn.c
> > @@ -2901,12 +2901,25 @@ static int abort_conn_sync(struct hci_dev *hdev, void *data)
> > {
> > struct hci_conn *conn;
> > u16 handle = PTR_UINT(data);
> > + u8 reason;
> > + int err;
> > +
> > + rcu_read_lock();
> >
> > conn = hci_conn_hash_lookup_handle(hdev, handle);
> > + if (conn) {
> > + reason = READ_ONCE(conn->abort_reason);
> > + conn = reason ? hci_conn_get(conn) : NULL;
> > + }
> > +
> > + rcu_read_unlock();
> > +
> > if (!conn)
> > return 0;
> >
> > - return hci_abort_conn_sync(hdev, conn, conn->abort_reason);
> > + err = hci_abort_conn_sync(hdev, conn, reason);
> > + hci_conn_put(conn);
> > + return err;
> > }
> >
> > int hci_abort_conn(struct hci_conn *conn, u8 reason)
> > @@ -2918,6 +2931,8 @@ int hci_abort_conn(struct hci_conn *conn, u8 reason)
> > */
> > if (conn->abort_reason)
> > return 0;
> > + if (WARN_ON(!reason))
> > + reason = HCI_ERROR_UNSPECIFIED;
> >
> > bt_dev_dbg(hdev, "handle 0x%2.2x reason 0x%2.2x", conn->handle, reason);
> >
> > --
> > 2.41.0
>
> Don't really like where this is going, the culprit here seems that we
> are not able to cancel the callback when freeing the hci_conn so it
> stays enqueued while the new connection is created with the same
> handle, so I think we need to introduce a function that cancel queued
> like Ive sent sometime back, that way we don't need to keep trying to
> check if it is the same connection or not.
Ack.
Note though that the first patch in series is separate issue, and won't
be fixed by canceling callbacks.
Removing the item from hci_sync queue on deletion would also avoid
syzbot hitting the issue in this second patch.
There'd be a remaining theoretical race though in
conn = hci_conn_hash_lookup_handle(hdev, handle);
/* the other workqueue frees conn here -> UAF */
if (!conn)
return 0;
unless you do the other stuff here. I wonder if there instead should be
something like hci_cmd_sync_dev_lock/unlock from
https://lore.kernel.org/linux-bluetooth/15e7863c06bd87cd991ab963132fa9d12ef7e11a.1690399379.git.pav@iki.fi/
to limit the concurrency only to the places where we wait for
controller events.
--
Pauli Virtanen
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 1/2] Bluetooth: hci_sync: always check if connection is alive before deleting
2023-09-30 12:53 [PATCH v2 1/2] Bluetooth: hci_sync: always check if connection is alive before deleting Pauli Virtanen
2023-09-30 12:53 ` [PATCH v2 2/2] Bluetooth: hci_conn: verify connection is to be aborted before doing it Pauli Virtanen
2023-09-30 13:36 ` [v2,1/2] Bluetooth: hci_sync: always check if connection is alive before deleting bluez.test.bot
@ 2023-10-03 17:10 ` patchwork-bot+bluetooth
2 siblings, 0 replies; 11+ messages in thread
From: patchwork-bot+bluetooth @ 2023-10-03 17:10 UTC (permalink / raw)
To: Pauli Virtanen; +Cc: linux-bluetooth
Hello:
This series was applied to bluetooth/bluetooth-next.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:
On Sat, 30 Sep 2023 15:53:32 +0300 you wrote:
> In hci_abort_conn_sync it is possible that conn is deleted concurrently
> by something else, also e.g. when waiting for hdev->lock. This causes
> double deletion of the conn, so UAF or conn_hash.list corruption.
>
> Fix by having all code paths check that the connection is still in
> conn_hash before deleting it, while holding hdev->lock which prevents
> any races.
>
> [...]
Here is the summary with links:
- [v2,1/2] Bluetooth: hci_sync: always check if connection is alive before deleting
https://git.kernel.org/bluetooth/bluetooth-next/c/32f6776f0083
- [v2,2/2] Bluetooth: hci_conn: verify connection is to be aborted before doing it
(no matching commit)
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in hci_send_acl
2023-08-21 16:26 syzbot
2023-08-31 18:07 ` syzbot
@ 2024-01-14 14:37 ` syzbot
1 sibling, 0 replies; 11+ messages in thread
From: syzbot @ 2024-01-14 14:37 UTC (permalink / raw)
To: davem, edumazet, hdanton, johan.hedberg, kuba, linux-bluetooth,
linux-kernel, luiz.dentz, luiz.von.dentz, marcel, netdev, pabeni,
pav, syzkaller-bugs, william.xuanziyang
syzbot suspects this issue was fixed by commit:
commit 181a42edddf51d5d9697ecdf365d72ebeab5afb0
Author: Ziyang Xuan <william.xuanziyang@huawei.com>
Date: Wed Oct 11 09:57:31 2023 +0000
Bluetooth: Make handle of hci_conn be unique
bisection log: https://syzkaller.appspot.com/x/bisect.txt?x=127944c1e80000
start commit: 4b2b606075e5 ipv4/fib: send notify when delete source addr..
git tree: net
kernel config: https://syzkaller.appspot.com/x/.config?x=d594086f139d167
dashboard link: https://syzkaller.appspot.com/bug?extid=a0c80b06ae2cb8895bc4
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=138aad9e680000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=125e0b92680000
If the result looks correct, please mark the issue as fixed by replying with:
#syz fix: Bluetooth: Make handle of hci_conn be unique
For information about bisection process see: https://goo.gl/tpsmEJ#bisection
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2024-01-14 14:37 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-09-30 12:53 [PATCH v2 1/2] Bluetooth: hci_sync: always check if connection is alive before deleting Pauli Virtanen
2023-09-30 12:53 ` [PATCH v2 2/2] Bluetooth: hci_conn: verify connection is to be aborted before doing it Pauli Virtanen
2023-09-30 13:28 ` [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in hci_send_acl syzbot
2023-10-02 23:22 ` [PATCH v2 2/2] Bluetooth: hci_conn: verify connection is to be aborted before doing it Luiz Augusto von Dentz
2023-10-03 16:41 ` Pauli Virtanen
2023-09-30 13:36 ` [v2,1/2] Bluetooth: hci_sync: always check if connection is alive before deleting bluez.test.bot
2023-10-03 17:10 ` [PATCH v2 1/2] " patchwork-bot+bluetooth
-- strict thread matches above, loose matches on Subject: below --
2023-08-25 19:01 [PATCH] Bluetooth: hci_conn: verify connection is to be aborted before doing it Pauli Virtanen
2023-08-25 19:34 ` [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in hci_send_acl syzbot
2023-08-21 16:26 syzbot
2023-08-31 18:07 ` syzbot
2024-01-14 14:37 ` syzbot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).