qca_debugfs_init() creates an "ibs" directory under hdev->debugfs and stores pointers to fields of struct qca_data in the debugfs files. qca_close() frees qca_data without removing that directory, while hdev->debugfs is only removed when the HCI device is released. The HCI device can outlive the driver data, for example when an HCI socket still references it, so reading or writing one of the ibs files then dereferences freed memory. Store the directory dentry in struct qca_data and remove the directory with debugfs_remove_recursive() before qca_data is freed. debugfs_remove() waits for callers that are already inside the file operations, and any later access fails with -EIO instead of reaching the debugfs helpers. This covers the two writable files as well. Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261102113654.8724-1-25031212351%40stu.xidian.edu.cn Fixes: 0ff252c1976d ("Bluetooth: hciuart: Add support QCA chipset for UART") Cc: stable@vger.kernel.org Signed-off-by: YuanZhe Liu <25031212351@stu.xidian.edu.cn> --- drivers/bluetooth/hci_qca.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 7089e9b639b2..d96ae0fc2b2e 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -161,6 +161,7 @@ struct qca_data { struct delayed_work ctrl_memdump_timeout; struct qca_memdump_info *qca_memdump; unsigned long flags; + struct dentry *debugfs_ibs_dir; struct completion drop_ev_comp; wait_queue_head_t suspend_wait_q; enum qca_memdump_states memdump_state; @@ -665,6 +666,7 @@ static void qca_debugfs_init(struct hci_dev *hdev) return; ibs_dir = debugfs_create_dir("ibs", hdev->debugfs); + qca->debugfs_ibs_dir = ibs_dir; /* read only */ mode = 0444; @@ -744,6 +746,9 @@ static int qca_close(struct hci_uart *hu) hu->priv = NULL; + debugfs_remove_recursive(qca->debugfs_ibs_dir); + qca->debugfs_ibs_dir = NULL; + kfree(qca); return 0; -- 2.34.1