[PATCH] Bluetooth: HCI: fix slab-use-after-free in cmd_sync_work

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello, could you review the UAF bug and its fix?
The stack trace is at the bottom.

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.

To fix this, this patch makes hci_dev_close_sync() call hci_cmd_sync_clear() to clear the cmd_sync_work.

Thanks,
Sungwoo Kim.

==================================================================
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+ #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 <iam@xxxxxxxxxxxx>
---
 net/bluetooth/hci_core.c | 2 --
 net/bluetooth/hci_sync.c | 5 ++++-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index a7028d38c..c347efc4f 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2764,8 +2764,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);
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index c5d879904..aa8e0c33c 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -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);
-- 
2.34.1





[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux