mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-22 15:03:53 +02:00
Bluetooth: vhci: Prevent use-after-free by removing debugfs files early
[ Upstream commit 28010791193a4503f054e8d69a950ef815deb539 ]
Move the creation of debugfs files into a dedicated function, and ensure
they are explicitly removed during vhci_release(), before associated
data structures are freed.
Previously, debugfs files such as "force_suspend", "force_wakeup", and
others were created under hdev->debugfs but not removed in
vhci_release(). Since vhci_release() frees the backing vhci_data
structure, any access to these files after release would result in
use-after-free errors.
Although hdev->debugfs is later freed in hci_release_dev(), user can
access files after vhci_data is freed but before hdev->debugfs is
released.
Fixes: ab4e4380d4
("Bluetooth: Add vhci devcoredump support")
Signed-off-by: Ivan Pravdin <ipravdin.official@gmail.com>
Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
2acc8d3f0a
commit
bd75eba88e
|
@ -380,6 +380,28 @@ 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;
|
||||
|
||||
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;
|
||||
|
@ -435,22 +457,8 @@ 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);
|
||||
if (!IS_ERR_OR_NULL(hdev->debugfs))
|
||||
vhci_debugfs_init(data);
|
||||
|
||||
hci_skb_pkt_type(skb) = HCI_VENDOR_PKT;
|
||||
|
||||
|
@ -652,6 +660,21 @@ static int vhci_open(struct inode *inode, struct file *file)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void vhci_debugfs_remove(struct hci_dev *hdev)
|
||||
{
|
||||
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;
|
||||
|
@ -663,6 +686,8 @@ static int vhci_release(struct inode *inode, struct file *file)
|
|||
hdev = data->hdev;
|
||||
|
||||
if (hdev) {
|
||||
if (!IS_ERR_OR_NULL(hdev->debugfs))
|
||||
vhci_debugfs_remove(hdev);
|
||||
hci_unregister_dev(hdev);
|
||||
hci_free_dev(hdev);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user