Skip to content

Commit

Permalink
Bluetooth: HCI: fix slab-use-after-free in cmd_sync_work
Browse files Browse the repository at this point in the history
mgmt sync cmd could be used after freed in this scenario:

set_local_name()       ... cmd is allocated, set_name_complete() is
                           queued in cmd_sync_work.
hci_error_reset()      ... hci device reset.
  hci_dev_close_sync() ... close hdev, at this point, cmd is freed.
set_name_complete()    ... callback from cmd_sync_work. cmd->param causes UAF.

==================================================================
BUG: KASAN: slab-use-after-free in set_name_complete+0x4a/0x330
net/bluetooth/mgmt.c:3815
Read of size 8 at addr ffff888107259098 by task kworker/u3:0/66

CPU: 0 PID: 66 Comm: kworker/u3:0 Not tainted 6.8.0+ torvalds#61
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1
04/01/2014
Workqueue: hci0 hci_cmd_sync_work
Call Trace:
 <TASK>
 __dump_stack lib/dump_stack.c:88 [inline]
 dump_stack_lvl+0x85/0xb0 lib/dump_stack.c:106
 print_address_description mm/kasan/report.c:377 [inline]
 print_report+0x18f/0x560 mm/kasan/report.c:488
 kasan_report+0xd7/0x110 mm/kasan/report.c:601
 __asan_report_load8_noabort+0x18/0x20 mm/kasan/report_generic.c:381
 set_name_complete+0x4a/0x330 net/bluetooth/mgmt.c:3815
 hci_cmd_sync_work+0x269/0x3e0 net/bluetooth/hci_sync.c:308
 process_one_work kernel/workqueue.c:2633 [inline]
 process_scheduled_works+0x6b9/0xdc0 kernel/workqueue.c:2706
 worker_thread+0xb2b/0x13d0 kernel/workqueue.c:2787
 kthread+0x2a9/0x340 kernel/kthread.c:388
 ret_from_fork+0x5c/0x90 arch/x86/kernel/process.c:147
 ret_from_fork_asm+0x1b/0x30 arch/x86/entry/entry_64.S:243
 </TASK>

Allocated by task 308:
 kasan_save_stack mm/kasan/common.c:47 [inline]
 kasan_save_track+0x30/0x70 mm/kasan/common.c:68
 kasan_save_alloc_info+0x3c/0x50 mm/kasan/generic.c:575
 poison_kmalloc_redzone mm/kasan/common.c:370 [inline]
 __kasan_kmalloc+0xa2/0xc0 mm/kasan/common.c:387
 kasan_kmalloc include/linux/kasan.h:211 [inline]
 kmalloc_trace+0x1c9/0x390 mm/slub.c:4012
 kmalloc include/linux/slab.h:590 [inline]
 kzalloc include/linux/slab.h:711 [inline]
 mgmt_pending_new+0x6f/0x230 net/bluetooth/mgmt_util.c:269
 mgmt_pending_add+0x3f/0x120 net/bluetooth/mgmt_util.c:296
 set_local_name+0x15a/0x4c0 net/bluetooth/mgmt.c:3892
 hci_mgmt_cmd+0xb79/0x1190 net/bluetooth/hci_sock.c:1715
 hci_sock_sendmsg+0x63a/0xf00 net/bluetooth/hci_sock.c:1835
 sock_sendmsg_nosec net/socket.c:730 [inline]
 __sock_sendmsg+0x227/0x270 net/socket.c:745
 sock_write_iter+0x28d/0x3d0 net/socket.c:1160
 do_iter_readv_writev+0x331/0x4c0
 vfs_writev+0x2e6/0xa40 fs/read_write.c:971
 do_writev+0xfd/0x250 fs/read_write.c:1018
 __do_sys_writev fs/read_write.c:1091 [inline]
 __se_sys_writev fs/read_write.c:1088 [inline]
 __x64_sys_writev+0x86/0xa0 fs/read_write.c:1088
 do_syscall_x64 arch/x86/entry/common.c:52 [inline]
 do_syscall_64+0x84/0x120 arch/x86/entry/common.c:83
 entry_SYSCALL_64_after_hwframe+0x6e/0x76

Freed by task 66:
 kasan_save_stack mm/kasan/common.c:47 [inline]
 kasan_save_track+0x30/0x70 mm/kasan/common.c:68
 kasan_save_free_info+0x44/0x50 mm/kasan/generic.c:589
 poison_slab_object+0x11a/0x190 mm/kasan/common.c:240
 __kasan_slab_free+0x3b/0x60 mm/kasan/common.c:256
 kasan_slab_free include/linux/kasan.h:184 [inline]
 slab_free_hook mm/slub.c:2121 [inline]
 slab_free mm/slub.c:4299 [inline]
 kfree+0x106/0x2e0 mm/slub.c:4409
 mgmt_pending_free net/bluetooth/mgmt_util.c:309 [inline]
 mgmt_pending_remove+0x19e/0x1d0 net/bluetooth/mgmt_util.c:315
 cmd_complete_rsp+0x104/0x1a0
 mgmt_pending_foreach+0xc7/0x120 net/bluetooth/mgmt_util.c:259
 __mgmt_power_off+0x137/0x370 net/bluetooth/mgmt.c:9496
 hci_dev_close_sync+0x4ab/0xe80 net/bluetooth/hci_sync.c:4953
 hci_dev_do_close net/bluetooth/hci_core.c:554 [inline]
 hci_error_reset+0x150/0x410 net/bluetooth/hci_core.c:1060
 process_one_work kernel/workqueue.c:2633 [inline]
 process_scheduled_works+0x6b9/0xdc0 kernel/workqueue.c:2706
 worker_thread+0xb2b/0x13d0 kernel/workqueue.c:2787
 kthread+0x2a9/0x340 kernel/kthread.c:388
 ret_from_fork+0x5c/0x90 arch/x86/kernel/process.c:147
 ret_from_fork_asm+0x1b/0x30 arch/x86/entry/entry_64.S:243

The buggy address belongs to the object at ffff888107259080
 which belongs to the cache kmalloc-96 of size 96
The buggy address is located 24 bytes inside of
 freed 96-byte region [ffff888107259080, ffff8881072590e0)

The buggy address belongs to the physical page:
page:000000006bdb81a5 refcount:1 mapcount:0 mapping:0000000000000000
index:0xffff888107259280 pfn:0x107259
flags: 0x17ffffc0000a00(workingset|slab|node=0|zone=2|lastcpupid=0x1fffff)
page_type: 0xffffffff()
raw: 0017ffffc0000a00 ffff888100041780 ffffea0004145510 ffffea0004240190
raw: ffff888107259280 000000000020000f 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 ffff888107258f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
 ffff888107259000: 00 00 00 00 00 00 00 00 00 00 00 fc fc fc fc fc
>ffff888107259080: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
                            ^
 ffff888107259100: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
 ffff888107259180: 00 00 00 00 00 00 00 00 00 00 00 00 fc fc fc fc
==================================================================

Signed-off-by: Sungwoo Kim <[email protected]>
Signed-off-by: Luiz Augusto von Dentz <[email protected]>
  • Loading branch information
swkim101 authored and Vudentz committed Apr 25, 2024
1 parent 1b69bac commit 37dd04e
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 3 deletions.
2 changes: 0 additions & 2 deletions net/bluetooth/hci_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2771,8 +2771,6 @@ void hci_unregister_dev(struct hci_dev *hdev)

cancel_work_sync(&hdev->power_on);

hci_cmd_sync_clear(hdev);

hci_unregister_suspend_notifier(hdev);

msft_unregister(hdev);
Expand Down
5 changes: 4 additions & 1 deletion net/bluetooth/hci_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -5181,9 +5181,12 @@ int hci_dev_close_sync(struct hci_dev *hdev)
clear_bit(HCI_INIT, &hdev->flags);
}

/* flush cmd work */
/* flush cmd work */
flush_work(&hdev->cmd_work);

/* flush cmd sync work */
hci_cmd_sync_clear(hdev);

/* Drop queues */
skb_queue_purge(&hdev->rx_q);
skb_queue_purge(&hdev->cmd_q);
Expand Down

0 comments on commit 37dd04e

Please sign in to comment.