mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] Bluetooth: vhci: Serialize packet reception with device creation
@ 2026-10-24 15:28 Cen Zhang
  0 siblings, 0 replies; only message in thread
From: Cen Zhang @ 2026-10-24 15:28 UTC (permalink / raw)
  To: marcel, luiz.dentz
  Cc: linux-bluetooth, linux-kernel, baijiaju1990, jjzuming, zzzccc427

The hci_dev passed to hci_recv_frame() must stay alive until the receive
operation finishes. __vhci_create_device() stores data->hdev before
hci_register_dev() and frees the device if registration fails.
vhci_get_user() checks and uses that pointer without taking the
open_mutex held by the creator or a device reference.

An incoming packet write can overlap the delayed default-create work
scheduled by vhci_open(). If registration fails before acquiring the
registration reference, the following order is possible:

  Default-create work                Packet write
  vhci_create_device()
    mutex_lock(open_mutex)
    data->hdev = hdev
                                     vhci_get_user()
                                       load data->hdev
    hci_register_dev() fails
    hci_free_dev(hdev)
      bt_host_release(): kfree(hdev)
    data->hdev = NULL
    mutex_unlock(open_mutex)
                                     hci_recv_frame(hdev, skb)
                                       read hdev->flags

The packet retains the pointer before the final put and reads flags
after the allocation is freed. The HCI_UP/HCI_INIT test therefore
accesses freed memory before it can reject the packet.

Hold open_mutex from the packet-side pointer check until
hci_recv_frame() returns. Creation and its error cleanup already hold
this mutex, so the writer waits until they finish and cannot retain a
failed device allocation. Release the mutex on the missing-device error
path too.

KASAN report as below:

    BUG: KASAN: use-after-free in hci_recv_frame+0x4e/0x7e0
    Read of size 8 at addr ffff888107034138 by task python3/500

    Call Trace:
     <TASK>
     dump_stack_lvl+0x93/0xd0
     print_report+0xce/0x630
     ? hci_recv_frame+0x4e/0x7e0
     ? srso_alias_return_thunk+0x5/0xfbef5
     ? __virt_addr_valid+0x20d/0x410
     ? hci_recv_frame+0x4e/0x7e0
     kasan_report+0xe0/0x110
     ? hci_recv_frame+0x4e/0x7e0
     kasan_check_range+0x105/0x1b0
     hci_recv_frame+0x4e/0x7e0
     vhci_write+0x35a/0x4c0
     vfs_write+0x637/0x1010
     ? __pfx_vhci_write+0x10/0x10
     ? __might_fault+0xdd/0x190
     ? __pfx_vfs_write+0x10/0x10
     ? __pfx_hrtimer_wakeup+0x10/0x10
     ? srso_alias_return_thunk+0x5/0xfbef5
     ? srso_alias_return_thunk+0x5/0xfbef5
     ? common_nsleep_timens+0xa8/0x160
     ksys_write+0x111/0x200
     ? __pfx_ksys_write+0x10/0x10
     ? srso_alias_return_thunk+0x5/0xfbef5
     ? restore_fpregs_from_fpstate+0x55/0x100
     do_syscall_64+0x115/0x6a0
     entry_SYSCALL_64_after_hwframe+0x77/0x7f
    The buggy address belongs to the physical page:
        page: refcount:0 mapcount:0 mapping:0000000000000000
    index:0xffff888107036a40 pfn:0x107034
    flags: 0x200000000000000(node=0|zone=2)
        raw: 0200000000000000 ffffea00041c0308 ffff8881887bf180
    0000000000000000
        raw: ffff888107036a40 0000000000000000 00000000ffffffff
    0000000000000000
    page dumped because: kasan: bad access detected

    Memory state around the buggy address:
     ffff888107034000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
     ffff888107034080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    >ffff888107034100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
                                            ^
     ffff888107034180: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
     ffff888107034200: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    ==================================================================

Fixes: 23424c0d3169 ("Bluetooth: Add support creating virtual AMP controllers")
Assisted-by: LLM
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
---
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index 8f7db0102b25f..de7d4d67e46e9 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -524,7 +524,9 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
 	case HCI_ACLDATA_PKT:
 	case HCI_SCODATA_PKT:
 	case HCI_ISODATA_PKT:
+		mutex_lock(&data->open_mutex);
 		if (!data->hdev) {
+			mutex_unlock(&data->open_mutex);
 			kfree_skb(skb);
 			return -ENODEV;
 		}
@@ -532,6 +534,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
 		hci_skb_pkt_type(skb) = pkt_type;
 
 		ret = hci_recv_frame(data->hdev, skb);
+		mutex_unlock(&data->open_mutex);
 		break;
 
 	case HCI_VENDOR_PKT:

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2026-10-24 15:28 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-24 15:28 [PATCH] Bluetooth: vhci: Serialize packet reception with device creation Cen Zhang

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®