mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-09-22 09:34:56 +02:00
platform/x86: intel-hid: Protect ACPI notify handler against recursion
commitc085d82613upstream. Since commite2ffcda162("ACPI: OSL: Allow Notify () handlers to run on all CPUs") ACPI notify handlers like the intel-hid notify_handler() may run on multiple CPU cores racing with themselves. On convertibles and detachables (matched by DMI chassis-type 31 and 32 in dmi_auto_add_switch[]) the SW_TABLET_MODE input device is registered lazily from notify_handler() on the first tablet-mode event, via intel_hid_switches_setup(). When two such events race on different CPUs both can pass the !priv->switches check and register the priv->switches input device twice, resulting in a duplicate sysfs entry and a subsequent NULL pointer dereference. This is the same class of bug fixed by commite075c3b13a("platform/x86: intel-vbtn: Protect ACPI notify handler against recursion") for the sibling intel-vbtn driver. Protect intel-hid notify_handler() from racing with itself with a mutex to fix this. Fixes:e2ffcda162("ACPI: OSL: Allow Notify () handlers to run on all CPUs") Cc: stable@vger.kernel.org Signed-off-by: HyeongJun An <sammiee5311@gmail.com> Link: https://patch.msgid.link/20260605174905.131095-1-sammiee5311@gmail.com Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
452945662f
commit
86df6499df
@@ -7,11 +7,13 @@
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/input/sparse-keymap.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/string_choices.h>
|
||||
#include <linux/suspend.h>
|
||||
@@ -224,6 +226,7 @@ static const struct dmi_system_id dmi_auto_add_switch[] = {
|
||||
};
|
||||
|
||||
struct intel_hid_priv {
|
||||
struct mutex mutex; /* Avoid notify_handler() racing with itself */
|
||||
struct input_dev *input_dev;
|
||||
struct input_dev *array;
|
||||
struct input_dev *switches;
|
||||
@@ -559,6 +562,8 @@ static void notify_handler(acpi_handle handle, u32 event, void *context)
|
||||
struct key_entry *ke;
|
||||
int err;
|
||||
|
||||
guard(mutex)(&priv->mutex);
|
||||
|
||||
/*
|
||||
* Some convertible have unreliable VGBS return which could cause incorrect
|
||||
* SW_TABLET_MODE report, in these cases we enable support when receiving
|
||||
@@ -714,6 +719,10 @@ static int intel_hid_probe(struct platform_device *device)
|
||||
return -ENOMEM;
|
||||
dev_set_drvdata(&device->dev, priv);
|
||||
|
||||
err = devm_mutex_init(&device->dev, &priv->mutex);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* See dual_accel_detect.h for more info on the dual_accel check. */
|
||||
if (enable_sw_tablet_mode == TABLET_SW_AUTO) {
|
||||
if (dmi_check_system(dmi_vgbs_allow_list))
|
||||
|
||||
Reference in New Issue
Block a user