[PATCH 6.6 13/39] platform/x86: classmate-laptop: Add missing NULL pointer checks

Greg Kroah-Hartman
2026-02-17T20:39:39Z

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

[ Upstream commit fe747d7112283f47169e9c16e751179a9b38611e ]

In a few places in the Classmate laptop driver, code using the accel
object may run before that object's address is stored in the driver
data of the input device using it.

For example, cmpc_accel_sensitivity_store_v4() is the "show" method
of cmpc_accel_sensitivity_attr_v4 which is added in cmpc_accel_add_v4(),
before calling dev_set_drvdata() for inputdev->dev. If the sysfs
attribute is accessed prematurely, the dev_get_drvdata(&inputdev->dev)
call in in cmpc_accel_sensitivity_store_v4() returns NULL which
leads to a NULL pointer dereference going forward.

Moreover, sysfs attributes using the input device are added before
initializing that device by cmpc_add_acpi_notify_device() and if one
of them is accessed before running that function, a NULL pointer
dereference will occur.

For example, cmpc_accel_sensitivity_attr_v4 is added before calling
cmpc_add_acpi_notify_device() and if it is read prematurely, the
dev_get_drvdata(&acpi->dev) call in cmpc_accel_sensitivity_show_v4()
returns NULL which leads to a NULL pointer dereference going forward.

Fix this by adding NULL pointer checks in all of the relevant places.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Link: https://patch.msgid.link/12825381.O9o76ZdvQC@rafael.j.wysocki
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/platform/x86/classmate-laptop.c | 32 +++++++++++++++++++++++++
1 file changed, 32 insertions(+)

diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c
index 2edaea2492df7..053c8a86d5ece 100644
--- a/drivers/platform/x86/classmate-laptop.c
+++ b/drivers/platform/x86/classmate-laptop.c
@@ -208,7 +208,12 @@ static ssize_t cmpc_accel_sensitivity_show_v4(struct device *dev,

acpi = to_acpi_device(dev);
inputdev = dev_get_drvdata(&acpi->dev);
+ if (!inputdev)
+ return -ENXIO;
+
accel = dev_get_drvdata(&inputdev->dev);
+ if (!accel)
+ return -ENXIO;

return sprintf(buf, "%d\n", accel->sensitivity);
}
@@ -225,7 +230,12 @@ static ssize_t cmpc_accel_sensitivity_store_v4(struct device *dev,

acpi = to_acpi_device(dev);
inputdev = dev_get_drvdata(&acpi->dev);
+ if (!inputdev)
+ return -ENXIO;
+
accel = dev_get_drvdata(&inputdev->dev);
+ if (!accel)
+ return -ENXIO;

r = kstrtoul(buf, 0, &sensitivity);
if (r)
@@ -257,7 +267,12 @@ static ssize_t cmpc_accel_g_select_show_v4(struct device *dev,

acpi = to_acpi_device(dev);
inputdev = dev_get_drvdata(&acpi->dev);
+ if (!inputdev)
+ return -ENXIO;
+
accel = dev_get_drvdata(&inputdev->dev);
+ if (!accel)
+ return -ENXIO;

return sprintf(buf, "%d\n", accel->g_select);
}
@@ -274,7 +289,12 @@ static ssize_t cmpc_accel_g_select_store_v4(struct device *dev,

acpi = to_acpi_device(dev);
inputdev = dev_get_drvdata(&acpi->dev);
+ if (!inputdev)
+ return -ENXIO;
+
accel = dev_get_drvdata(&inputdev->dev);
+ if (!accel)
+ return -ENXIO;

r = kstrtoul(buf, 0, &g_select);
if (r)
@@ -303,6 +323,8 @@ static int cmpc_accel_open_v4(struct input_dev *input)

acpi = to_acpi_device(input->dev.parent);
accel = dev_get_drvdata(&input->dev);
+ if (!accel)
+ return -ENXIO;

cmpc_accel_set_sensitivity_v4(acpi->handle, accel->sensitivity);
cmpc_accel_set_g_select_v4(acpi->handle, accel->g_select);
@@ -551,7 +573,12 @@ static ssize_t cmpc_accel_sensitivity_show(struct device *dev,

acpi = to_acpi_device(dev);
inputdev = dev_get_drvdata(&acpi->dev);
+ if (!inputdev)
+ return -ENXIO;
+
accel = dev_get_drvdata(&inputdev->dev);
+ if (!accel)
+ return -ENXIO;

return sprintf(buf, "%d\n", accel->sensitivity);
}
@@ -568,7 +595,12 @@ static ssize_t cmpc_accel_sensitivity_store(struct device *dev,

acpi = to_acpi_device(dev);
inputdev = dev_get_drvdata(&acpi->dev);
+ if (!inputdev)
+ return -ENXIO;
+
accel = dev_get_drvdata(&inputdev->dev);
+ if (!accel)
+ return -ENXIO;

r = kstrtoul(buf, 0, &sensitivity);
if (r)
--
2.51.0