mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] Bluetooth: msft: Lock failed probe cleanup against feature readers
@ 2026-10-06 14:41 Cen Zhang
  2026-10-07 17:30 ` patchwork-bot+bluetooth
  0 siblings, 1 reply; 2+ messages in thread
From: Cen Zhang @ 2026-10-06 14:41 UTC (permalink / raw)
  To: marcel, luiz.dentz
  Cc: linux-bluetooth, linux-kernel, baijiaju1990, jjzuming, zzzccc427

The MSFT data must remain allocated while msft_get_features() reads
its features. read_adv_mon_features() protects that access with
hdev->lock, but msft_do_open() clears hdev->msft_data and frees the
object without that lock when read_supported_features() fails.

After a successful probe, the data survives a normal close. A later
open can fail the probe while a management feature request is running.
hci_mgmt_cmd() permits requests during HCI_INIT, and the opener's
hdev->req_lock does not serialize the management reader:

  Management feature request            HCI open
                                        hold hdev->req_lock
                                        msft_do_open()
  hold hdev->lock
  msft_get_features(): save msft
                                        read_supported_features() fails
                                        hdev->msft_data = NULL
                                        kfree(msft)
  read msft->features
  release hdev->lock                     release hdev->req_lock

The saved pointer then refers to freed memory, causing a use-after-free
read. Advertisement reporting through mgmt_device_found() also reads
the features with hdev->lock held.

Take hdev->lock around clearing and freeing msft_data in the failure
branch. An existing feature reader finishes before the free, while a
reader starting after cleanup sees NULL. Keep the synchronous probe
outside this critical section, following the existing req_lock to
hdev->lock ordering.

KASAN report as below:

    ==================================================================
    BUG: KASAN: slab-use-after-free in msft_monitor_supported+0xa9/0xb0
    Read of size 8 at addr ffff88811573ee00 by task mgmt-read-adv-m/532
    
        CPU: 2 UID: 0 PID: 532 Comm: mgmt-read-adv-m Not tainted 
    7.2.0-rc6-pmb-bt-functional-v1+ #1 PREEMPT(lazy) 
        Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps 
    fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
    Call Trace:
     <TASK>
     dump_stack_lvl+0x93/0xd0
     print_report+0xce/0x630
     ? msft_monitor_supported+0xa9/0xb0
     ? srso_alias_return_thunk+0x5/0xfbef5
     ? __virt_addr_valid+0x20d/0x410
     ? msft_monitor_supported+0xa9/0xb0
     kasan_report+0xe0/0x110
     ? msft_monitor_supported+0xa9/0xb0
     msft_monitor_supported+0xa9/0xb0
     read_adv_mon_features+0xdf/0x640
     ? trace_hardirqs_on+0x18/0x160
     ? srso_alias_return_thunk+0x5/0xfbef5
     ? __pfx_read_adv_mon_features+0x10/0x10
     ? srso_alias_return_thunk+0x5/0xfbef5
     ? srso_alias_return_thunk+0x5/0xfbef5
     ? do_raw_read_unlock+0x49/0xe0
     ? srso_alias_return_thunk+0x5/0xfbef5
     ? _raw_read_unlock+0x23/0x40
     hci_sock_sendmsg+0x12b5/0x2270
     ? __pfx_hci_sock_sendmsg+0x10/0x10
     ? srso_alias_return_thunk+0x5/0xfbef5
     ? selinux_socket_sendmsg+0x160/0x280
     __sys_sendto+0x425/0x470
     ? __pfx_hci_sock_sendmsg+0x10/0x10
     ? __pfx___sys_sendto+0x10/0x10
     ? srso_alias_return_thunk+0x5/0xfbef5
     ? srso_alias_return_thunk+0x5/0xfbef5
     ? srso_alias_return_thunk+0x5/0xfbef5
     ? __sys_setsockopt+0x119/0x180
     __x64_sys_sendto+0xe5/0x1c0
     ? lockdep_hardirqs_on_prepare+0xea/0x1a0
     ? srso_alias_return_thunk+0x5/0xfbef5
     ? trace_hardirqs_on+0x18/0x160
     do_syscall_64+0x115/0x6a0
     entry_SYSCALL_64_after_hwframe+0x77/0x7f
    RIP: 0033:0x7f9ceb04a687
        Code: 48 89 fa 4c 89 df e8 58 b3 00 00 8b 93 08 03 00 00 59 5e 48 
    83 f8 fc 74 1a 5b c3 0f 1f 84 00 00 00 00 00 48 8b 44 24 10 0f 05 <5b> 
    c3 0f 1f 80 00 00 00 00 83 e2 39 83 fa 08 75 de e8 23 ff ff ff
    RSP: 002b:00007ffe6ab96a70 EFLAGS: 00000202 ORIG_RAX: 000000000000002c
    RAX: ffffffffffffffda RBX: 00007f9ceafb8780 RCX: 00007f9ceb04a687
    RDX: 0000000000000006 RSI: 00007ffe6ab96aea RDI: 0000000000000003
    RBP: 0000000000000002 R08: 0000000000000000 R09: 0000000000000000
    R10: 0000000000000000 R11: 0000000000000202 R12: 0000000000000003
    R13: 00007ffe6ab96d50 R14: 00007f9ceb1f6000 R15: 00005625e427dd68
     </TASK>
    
    Allocated by task 506:
     kasan_save_stack+0x33/0x60
     kasan_save_track+0x14/0x30
     __kasan_kmalloc+0xaa/0xb0
     __kmalloc_cache_noprof+0x251/0x610
     msft_register+0x54/0x260
     hci_register_dev+0x6b7/0xc80
     __vhci_create_device+0x330/0x840
     vhci_write+0x287/0x440
     vfs_write+0x637/0x1010
     ksys_write+0x111/0x200
     do_syscall_64+0x115/0x6a0
     entry_SYSCALL_64_after_hwframe+0x77/0x7f
    
    Freed by task 529:
     kasan_save_stack+0x33/0x60
     kasan_save_track+0x14/0x30
     kasan_save_free_info+0x3b/0x60
     __kasan_slab_free+0x5f/0x80
     kfree+0x307/0x580
     msft_do_open+0x604/0x9e0
     hci_dev_open_sync+0x94a/0x2110
     hci_dev_do_open+0x2f/0xb0
     hci_dev_open+0x17d/0x300
     hci_sock_ioctl+0x3c6/0x710
     sock_do_ioctl+0x120/0x2b0
     sock_ioctl+0x41b/0x670
     __x64_sys_ioctl+0x163/0x1d0
     do_syscall_64+0x115/0x6a0
     entry_SYSCALL_64_after_hwframe+0x77/0x7f
    
    The buggy address belongs to the object at ffff88811573ee00
     which belongs to the cache kmalloc-256 of size 256
    The buggy address is located 0 bytes inside of
     freed 256-byte region [ffff88811573ee00, ffff88811573ef00)
    
    The buggy address belongs to the physical page:
        page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 
    pfn:0x11573e
    head: order:1 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
    flags: 0x200000000000040(head|node=0|zone=2)
    page_type: f5(slab)
        raw: 0200000000000040 ffff888100042b40 dead000000000100 
    dead000000000122
        raw: 0000000000000000 0000000000100010 00000000f5000000 
    0000000000000000
        head: 0200000000000040 ffff888100042b40 dead000000000100 
    dead000000000122
        head: 0000000000000000 0000000000100010 00000000f5000000 
    0000000000000000
        head: 0200000000000001 ffffffffffffff81 00000000ffffffff 
    00000000ffffffff
        head: 0000000000000000 0000000000000000 00000000ffffffff 
    0000000000000000
    page dumped because: kasan: bad access detected
    
    Memory state around the buggy address:
     ffff88811573ed00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
     ffff88811573ed80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
    >ffff88811573ee00: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
                       ^
     ffff88811573ee80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
     ffff88811573ef00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
    ==================================================================

Fixes: 5031ffcc79b8 ("Bluetooth: Keep MSFT ext info throughout a hci_dev's life cycle")
Assisted-by: LLM
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
---

diff --git a/net/bluetooth/msft.c b/net/bluetooth/msft.c
index d9dd722db3ebd5daf1a19fc50996c55e44494378..6f4b7c38a2474511062f38d20ccac6900035f322 100644
--- a/net/bluetooth/msft.c
+++ b/net/bluetooth/msft.c
@@ -654,8 +654,10 @@ void msft_do_open(struct hci_dev *hdev)
 	msft->features = 0;
 
 	if (!read_supported_features(hdev, msft)) {
+		hci_dev_lock(hdev);
 		hdev->msft_data = NULL;
 		kfree(msft);
+		hci_dev_unlock(hdev);
 		return;
 	}
 

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] Bluetooth: msft: Lock failed probe cleanup against feature readers
  2026-10-06 14:41 [PATCH] Bluetooth: msft: Lock failed probe cleanup against feature readers Cen Zhang
@ 2026-10-07 17:30 ` patchwork-bot+bluetooth
  0 siblings, 0 replies; 2+ messages in thread
From: patchwork-bot+bluetooth @ 2026-10-07 17:30 UTC (permalink / raw)
  To: Cen Zhang
  Cc: marcel, luiz.dentz, linux-bluetooth, linux-kernel, baijiaju1990,
	jjzuming

Hello:

This patch was applied to bluetooth/bluetooth-next.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:

On Tue,  6 Oct 2026 22:41:57 +0800 you wrote:
> The MSFT data must remain allocated while msft_get_features() reads
> its features. read_adv_mon_features() protects that access with
> hdev->lock, but msft_do_open() clears hdev->msft_data and frees the
> object without that lock when read_supported_features() fails.
> 
> After a successful probe, the data survives a normal close. A later
> open can fail the probe while a management feature request is running.
> hci_mgmt_cmd() permits requests during HCI_INIT, and the opener's
> hdev->req_lock does not serialize the management reader:
> 
> [...]

Here is the summary with links:
  - Bluetooth: msft: Lock failed probe cleanup against feature readers
    https://git.kernel.org/bluetooth/bluetooth-next/c/9cb04e601a89

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] 2+ messages in thread

end of thread, other threads:[~2026-10-07 17:30 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-06 14:41 [PATCH] Bluetooth: msft: Lock failed probe cleanup against feature readers Cen Zhang
2026-10-07 17:30 ` patchwork-bot+bluetooth

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®