Skip to content

Commit eba9ac7

Browse files
Wer-Wolfij-intel
authored andcommitted
platform/x86: wmi: Fix opening of char device
Since commit fa1f68d ("drivers: misc: pass miscdevice pointer via file private data"), the miscdevice stores a pointer to itself inside filp->private_data, which means that private_data will not be NULL when wmi_char_open() is called. This might cause memory corruption should wmi_char_open() be unable to find its driver, something which can happen when the associated WMI device is deleted in wmi_free_devices(). Fix the problem by using the miscdevice pointer to retrieve the WMI device data associated with a char device using container_of(). This also avoids wmi_char_open() picking a wrong WMI device bound to a driver with the same name as the original driver. Fixes: 44b6b76 ("platform/x86: wmi: create userspace interface for drivers") Signed-off-by: Armin Wolf <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Ilpo Järvinen <[email protected]> Signed-off-by: Ilpo Järvinen <[email protected]>
1 parent ed85891 commit eba9ac7

File tree

1 file changed

+6
-14
lines changed
  • drivers/platform/x86

1 file changed

+6
-14
lines changed

drivers/platform/x86/wmi.c

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -958,21 +958,13 @@ static int wmi_dev_match(struct device *dev, struct device_driver *driver)
958958
}
959959
static int wmi_char_open(struct inode *inode, struct file *filp)
960960
{
961-
const char *driver_name = filp->f_path.dentry->d_iname;
962-
struct wmi_block *wblock;
963-
struct wmi_block *next;
964-
965-
list_for_each_entry_safe(wblock, next, &wmi_block_list, list) {
966-
if (!wblock->dev.dev.driver)
967-
continue;
968-
if (strcmp(driver_name, wblock->dev.dev.driver->name) == 0) {
969-
filp->private_data = wblock;
970-
break;
971-
}
972-
}
961+
/*
962+
* The miscdevice already stores a pointer to itself
963+
* inside filp->private_data
964+
*/
965+
struct wmi_block *wblock = container_of(filp->private_data, struct wmi_block, char_dev);
973966

974-
if (!filp->private_data)
975-
return -ENODEV;
967+
filp->private_data = wblock;
976968

977969
return nonseekable_open(inode, filp);
978970
}

0 commit comments

Comments
 (0)