public inbox for patches@lists.linux.dev
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>,
	"Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>,
	"Sasha Levin" <sashal@kernel.org>,
	cascardo@holoscopio.com, hansg@kernel.org,
	platform-driver-x86@vger.kernel.org
Subject: [PATCH AUTOSEL 6.18-5.10] platform/x86: classmate-laptop: Add missing NULL pointer checks
Date: Mon,  9 Feb 2026 07:26:43 -0500	[thread overview]
Message-ID: <20260209122714.1037915-4-sashal@kernel.org> (raw)
In-Reply-To: <20260209122714.1037915-1-sashal@kernel.org>

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>
---

LLM Generated explanations, may be completely bogus:

## Analysis

### Commit Message Analysis

The commit message clearly describes a **NULL pointer dereference** bug
in the classmate-laptop driver. The author (Rafael J. Wysocki, a
prominent kernel maintainer) explains the race condition:

1. Sysfs attributes are registered **before** `dev_set_drvdata()` is
   called to store the accel object pointer
2. Sysfs attributes are also registered **before**
   `cmpc_add_acpi_notify_device()` initializes the input device
3. If userspace accesses these sysfs attributes in the window between
   creation and initialization, `dev_get_drvdata()` returns NULL,
   leading to a NULL pointer dereference (kernel oops/crash)

### Code Change Analysis

The fix is straightforward and mechanical - it adds NULL pointer checks
after `dev_get_drvdata()` calls in the following functions:

**V4 accelerometer functions:**
- `cmpc_accel_sensitivity_show_v4()` - 2 NULL checks added
- `cmpc_accel_sensitivity_store_v4()` - 2 NULL checks added
- `cmpc_accel_g_select_show_v4()` - 2 NULL checks added
- `cmpc_accel_g_select_store_v4()` - 2 NULL checks added
- `cmpc_accel_open_v4()` - 1 NULL check added

**Non-v4 accelerometer functions:**
- `cmpc_accel_sensitivity_show()` - 2 NULL checks added
- `cmpc_accel_sensitivity_store()` - 2 NULL checks added

Each check follows the same pattern:
```c
inputdev = dev_get_drvdata(&acpi->dev);
if (!inputdev)
    return -ENXIO;

accel = dev_get_drvdata(&inputdev->dev);
if (!accel)
    return -ENXIO;
```

This is the standard defensive pattern for sysfs callbacks that may be
called during device initialization/teardown.

### Bug Classification

- **Type**: NULL pointer dereference (race between sysfs attribute
  creation and device initialization)
- **Trigger**: Userspace reading/writing sysfs attributes during device
  probe
- **Consequence**: Kernel oops/crash
- **Severity**: Medium-High (crash from userspace access)

### Stable Kernel Criteria Assessment

1. **Obviously correct and tested**: Yes - simple NULL checks with
   appropriate error returns (-ENXIO). Reviewed by Ilpo Järvinen. The
   pattern is standard kernel defensive programming.
2. **Fixes a real bug**: Yes - NULL pointer dereference that causes a
   kernel crash.
3. **Important issue**: Yes - kernel crash triggered from userspace
   sysfs access.
4. **Small and contained**: Yes - single file, only adds NULL checks. No
   behavioral changes beyond preventing the crash.
5. **No new features/APIs**: Correct - purely defensive checks.
6. **Clean application**: Should apply cleanly to any stable tree that
   has this driver, as the changes are simple additions.

### Risk Assessment

- **Risk**: Very low. The changes only add early-return paths with
  -ENXIO when pointers are NULL. This cannot cause regressions - if the
  pointer was previously non-NULL, the check is a no-op. If it was NULL,
  we now return an error instead of crashing.
- **Scope**: Single file, single driver (classmate-laptop), well-
  contained.
- **Author credibility**: Rafael J. Wysocki is a top-level kernel
  maintainer (PM subsystem, ACPI), highly trustworthy.

### User Impact

The classmate-laptop driver serves Intel Classmate PC hardware
(educational laptops). While the user base may be small, the fix
prevents a kernel crash from a realistic race condition during device
initialization. Any system with this hardware could hit this during
boot.

### Conclusion

This is a textbook stable backport candidate:
- Fixes NULL pointer dereferences (kernel crashes)
- Small, surgical, obviously correct
- Single file, no dependencies
- No new features or behavioral changes
- Written and reviewed by senior kernel developers
- Zero regression risk

**YES**

 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 6b1b8e444e241..74d3eb83f56a6 100644
--- a/drivers/platform/x86/classmate-laptop.c
+++ b/drivers/platform/x86/classmate-laptop.c
@@ -207,7 +207,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 sysfs_emit(buf, "%d\n", accel->sensitivity);
 }
@@ -224,7 +229,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)
@@ -256,7 +266,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 sysfs_emit(buf, "%d\n", accel->g_select);
 }
@@ -273,7 +288,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)
@@ -302,6 +322,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);
@@ -549,7 +571,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 sysfs_emit(buf, "%d\n", accel->sensitivity);
 }
@@ -566,7 +593,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


  parent reply	other threads:[~2026-02-09 12:27 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-09 12:26 [PATCH AUTOSEL 6.18-6.12] drm/amd/display: extend delta clamping logic to CM3 LUT helper Sasha Levin
2026-02-09 12:26 ` [PATCH AUTOSEL 6.18] io_uring/fdinfo: be a bit nicer when looping a lot of SQEs/CQEs Sasha Levin
2026-02-09 12:26 ` [PATCH AUTOSEL 6.18-6.12] ALSA: hda/realtek: Enable headset mic for Acer Nitro 5 Sasha Levin
2026-02-09 12:26 ` Sasha Levin [this message]
2026-02-09 12:26 ` [PATCH AUTOSEL 6.18-6.6] platform/x86/amd/pmc: Add quirk for MECHREVO Wujie 15X Pro Sasha Levin
2026-02-09 12:26 ` [PATCH AUTOSEL 6.18-6.6] ASoC: amd: yc: Add quirk for HP 200 G2a 16 Sasha Levin
2026-02-09 12:26 ` [PATCH AUTOSEL 6.18-5.15] platform/x86: panasonic-laptop: Fix sysfs group leak in error path Sasha Levin
2026-02-09 12:26 ` [PATCH AUTOSEL 6.18-5.15] ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put() Sasha Levin
2026-02-09 12:26 ` [PATCH AUTOSEL 6.18-6.12] tracing/dma: Cap dma_map_sg tracepoint arrays to prevent buffer overflow Sasha Levin
2026-02-09 12:26 ` [PATCH AUTOSEL 6.18-5.10] drm/tegra: hdmi: sor: Fix error: variable ‘j’ set but not used Sasha Levin
2026-02-09 12:26 ` [PATCH AUTOSEL 6.18-6.1] ASoC: Intel: sof_es8336: Add DMI quirk for Huawei BOD-WXX9 Sasha Levin
2026-02-09 12:26 ` [PATCH AUTOSEL 6.18] ASoC: sof_sdw: Add a quirk for Lenovo laptop using sidecar amps with cs42l43 Sasha Levin
2026-02-09 12:26 ` [PATCH AUTOSEL 6.18-5.10] gpiolib: acpi: Fix gpio count with string references Sasha Levin
2026-02-09 12:26 ` [PATCH AUTOSEL 6.18-6.6] ASoC: cs42l43: Correct handling of 3-pole jack load detection Sasha Levin
2026-02-09 12:26 ` [PATCH AUTOSEL 6.18-6.12] drm/amd/display: remove assert around dpp_base replacement Sasha Levin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260209122714.1037915-4-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=cascardo@holoscopio.com \
    --cc=hansg@kernel.org \
    --cc=ilpo.jarvinen@linux.intel.com \
    --cc=patches@lists.linux.dev \
    --cc=platform-driver-x86@vger.kernel.org \
    --cc=rafael.j.wysocki@intel.com \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox