From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D16383019CB; Mon, 9 Feb 2026 12:27:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770640043; cv=none; b=K/fhzjmt9NA/DRPcsDNQwxThdW54cwligmd2mJJwLpydmViZrgl6gtByrZk4kGXADRvFuECb/SDVPEM62ghF1jcZuF8y0ps1R+XI4KkWQa8xaYLcfjDc9jME6lOeKYCa0P/kDkx8vTjlnkcFI+JOGvPK3QiQ/N+gRKruh8B1BuQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770640043; c=relaxed/simple; bh=NPAfYkp2Y5fwywHipD0IKHS3egv89vfBuERz//yoMv8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=QOVt7zXKGKi5l+MU7J19GbbimPcfvvfr0zMsR3jQT/5mN76DBJB0mg0h4mAYYf8TDzwGBQM3+KfWm6mr8yC97QcFHAIhZ3xtwNt9IMDTHD+/1ceCzMELN4XbUXNI0E11oNLyMzHHSw2fbG2f/grQk1YEuIyf+rIfURfRN6IpoY8= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=DTjr/10x; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="DTjr/10x" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D9C27C19423; Mon, 9 Feb 2026 12:27:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770640043; bh=NPAfYkp2Y5fwywHipD0IKHS3egv89vfBuERz//yoMv8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DTjr/10xhktGRkC7Gs2MMfwtBa23kSTi/bM9Hk1GdUsRfCblD8AgK1meR9isYbq1z FwaGswrlaqiLdJCd+q7BeyqMmWJD8CmFoMJcUdBMsW5Xor/ga/QMOl0ejQiVMUwlUs gyaP/WnTKqCw+50eysm6x3Fj1qX8ufdtfKGX1jmGShq0Ec/skU7SX+tYQwi+ff82p/ qUWyDFLDfi2iY7vmOCM6ti/7a4YMxzaj0+Fjc8iyN/898nkpk7zzgnPBPN7XQme0qc 9W0npLJob2hHGLZqx14osd7y2qun3FBgKvWMsS/bR0SngcJ2P/4trYxb7IduzFM/N8 1kZKyWghnE75Q== From: Sasha Levin To: patches@lists.linux.dev, stable@vger.kernel.org Cc: "Rafael J. Wysocki" , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Sasha Levin , 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 Message-ID: <20260209122714.1037915-4-sashal@kernel.org> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260209122714.1037915-1-sashal@kernel.org> References: <20260209122714.1037915-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 X-stable: review X-Patchwork-Hint: Ignore X-stable-base: Linux 6.18.9 Content-Transfer-Encoding: 8bit From: "Rafael J. Wysocki" [ 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 Link: https://patch.msgid.link/12825381.O9o76ZdvQC@rafael.j.wysocki Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin --- 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