Re: [syzbot] Re: [syzbot] [bluetooth?] KASAN: vmalloc-out-of-bounds Read in hci_devcd_dump

syzbot
2025-06-11T02:42:14Z

For archival purposes, forwarding an incoming command email to
linux-kernel@vger.kernel.org.

***

Subject: Re: [syzbot] [bluetooth?] KASAN: vmalloc-out-of-bounds Read in hci_devcd_dump
Author: ipravdin.official@gmail.com

#syz test

diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index 59f4d7bdffdc..82a1088cd662 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -380,6 +380,31 @@ static const struct file_operations force_devcoredump_fops = {
.write = force_devcd_write,
};

+static void vhci_debugfs_init(struct vhci_data *data)
+{
+ struct hci_dev *hdev = data->hdev;
+
+ if (!hdev->debugfs)
+ return;
+
+ debugfs_create_file("force_suspend", 0644, hdev->debugfs, data,
+ &force_suspend_fops);
+
+ debugfs_create_file("force_wakeup", 0644, hdev->debugfs, data,
+ &force_wakeup_fops);
+
+ if (IS_ENABLED(CONFIG_BT_MSFTEXT))
+ debugfs_create_file("msft_opcode", 0644, hdev->debugfs, data,
+ &msft_opcode_fops);
+
+ if (IS_ENABLED(CONFIG_BT_AOSPEXT))
+ debugfs_create_file("aosp_capable", 0644, hdev->debugfs, data,
+ &aosp_capable_fops);
+
+ debugfs_create_file("force_devcoredump", 0644, hdev->debugfs, data,
+ &force_devcoredump_fops);
+}
+
static int __vhci_create_device(struct vhci_data *data, __u8 opcode)
{
struct hci_dev *hdev;
@@ -434,22 +459,9 @@ static int __vhci_create_device(struct vhci_data *data, __u8 opcode)
return -EBUSY;
}

- debugfs_create_file("force_suspend", 0644, hdev->debugfs, data,
- &force_suspend_fops);
-
- debugfs_create_file("force_wakeup", 0644, hdev->debugfs, data,
- &force_wakeup_fops);
-
- if (IS_ENABLED(CONFIG_BT_MSFTEXT))
- debugfs_create_file("msft_opcode", 0644, hdev->debugfs, data,
- &msft_opcode_fops);
-
- if (IS_ENABLED(CONFIG_BT_AOSPEXT))
- debugfs_create_file("aosp_capable", 0644, hdev->debugfs, data,
- &aosp_capable_fops);
-
- debugfs_create_file("force_devcoredump", 0644, hdev->debugfs, data,
- &force_devcoredump_fops);
+#ifdef CONFIG_DEBUG_FS
+ vhci_debugfs_init(data);
+#endif

hci_skb_pkt_type(skb) = HCI_VENDOR_PKT;

@@ -651,6 +663,26 @@ static int vhci_open(struct inode *inode, struct file *file)
return 0;
}

+static void vhci_debugfs_remove(struct vhci_data *data)
+{
+ struct hci_dev *hdev = data->hdev;
+
+ if (!hdev->debugfs)
+ return;
+
+ debugfs_lookup_and_remove("force_suspend", hdev->debugfs);
+
+ debugfs_lookup_and_remove("force_wakeup", hdev->debugfs);
+
+ if (IS_ENABLED(CONFIG_BT_MSFTEXT))
+ debugfs_lookup_and_remove("msft_opcode", hdev->debugfs);
+
+ if (IS_ENABLED(CONFIG_BT_AOSPEXT))
+ debugfs_lookup_and_remove("aosp_capable", hdev->debugfs);
+
+ debugfs_lookup_and_remove("force_devcoredump", hdev->debugfs);
+}
+
static int vhci_release(struct inode *inode, struct file *file)
{
struct vhci_data *data = file->private_data;
@@ -661,6 +693,10 @@ static int vhci_release(struct inode *inode, struct file *file)

hdev = data->hdev;

+#ifdef CONFIG_DEBUG_FS
+ vhci_debugfs_remove(data);
+#endif
+
if (hdev) {
hci_unregister_dev(hdev);
hci_free_dev(hdev);
diff --git a/net/bluetooth/coredump.c b/net/bluetooth/coredump.c
index 819eacb38762..908ad0d242c3 100644
--- a/net/bluetooth/coredump.c
+++ b/net/bluetooth/coredump.c
@@ -243,6 +243,7 @@ static void hci_devcd_handle_pkt_pattern(struct hci_dev *hdev,
static void hci_devcd_dump(struct hci_dev *hdev)
{
struct sk_buff *skb;
+ char* coredump;
u32 size;

bt_dev_dbg(hdev, "state %d", hdev->dump.state);
@@ -250,7 +251,11 @@ static void hci_devcd_dump(struct hci_dev *hdev)
size = hdev->dump.tail - hdev->dump.head;

/* Emit a devcoredump with the available data */
- dev_coredumpv(&hdev->dev, hdev->dump.head, size, GFP_KERNEL);
+ coredump = vmalloc(size);
+ if (coredump) {
+ memcpy(coredump, hdev->dump.head, size);
+ dev_coredumpv(&hdev->dev, coredump, size, GFP_KERNEL);
+ }

/* Send a copy to monitor as a diagnostic packet */
skb = bt_skb_alloc(size, GFP_ATOMIC);

Ivan Pravdin