[PATCH] HID: lenovo: Fix buffer over-read and unaligned access in X12 Tab raw_event handler

Kean posted 1 patch 4 weeks ago
There is a newer version of this series
drivers/hid/hid-lenovo.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
[PATCH] HID: lenovo: Fix buffer over-read and unaligned access in X12 Tab raw_event handler
Posted by Kean 4 weeks ago
In lenovo_raw_event(), the X12 Tab keyboard handler reads a 4-byte
little-endian value from the raw HID report buffer but:

  1. The size guard is size >= 3, while the access reads 4 bytes.
     A malformed 3-byte report with ID 0x03 would over-read the
     buffer by one byte.

  2. Casting u8 *data directly to __le32 * can trigger unaligned
     access faults on architectures like ARM, MIPS, and SPARC,
     because HID input buffers carry no alignment guarantee.
     (e.g. uhid payloads start at offset 6 in struct uhid_event,
     giving only 2-byte alignment.)

Fix both by tightening the size check to >= 4 and replacing the
open-coded cast + le32_to_cpu() with get_unaligned_le32(), which
handles the LE-to-CPU conversion safely regardless of alignment.

Link: https://sashiko.dev/#/message/20260512044911.99B6DC2BCB0%40smtp.kernel.org
Assisted-by: CLAUDE:claude-4-sonnet
Signed-off-by: Kean <rh_king@163.com>
---
 drivers/hid/hid-lenovo.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c
index a6b73e03c16b..c11957ae8b77 100644
--- a/drivers/hid/hid-lenovo.c
+++ b/drivers/hid/hid-lenovo.c
@@ -30,6 +30,7 @@
 #include <linux/hid.h>
 #include <linux/input.h>
 #include <linux/leds.h>
+#include <linux/unaligned.h>
 #include <linux/workqueue.h>
 
 #include "hid-ids.h"
@@ -793,8 +794,8 @@ static int lenovo_raw_event(struct hid_device *hdev,
 	 */
 	if (unlikely((hdev->product == USB_DEVICE_ID_LENOVO_X12_TAB
 			|| hdev->product == USB_DEVICE_ID_LENOVO_X12_TAB2)
-			&& size >= 3 && report->id == 0x03))
-		return lenovo_raw_event_TP_X12_tab(hdev, le32_to_cpu(*(__le32 *)data));
+			&& size >= 4 && report->id == 0x03))
+		return lenovo_raw_event_TP_X12_tab(hdev, get_unaligned_le32(data));
 
 	return 0;
 }
-- 
2.53.0
Re: [PATCH] HID: lenovo: Fix buffer over-read and unaligned access in X12 Tab raw_event handler
Posted by Benjamin Tissoires 3 weeks ago
On Thu, 14 May 2026 20:58:38 +0800, Kean wrote:
> In lenovo_raw_event(), the X12 Tab keyboard handler reads a 4-byte
> little-endian value from the raw HID report buffer but:
> 
>   1. The size guard is size >= 3, while the access reads 4 bytes.
>      A malformed 3-byte report with ID 0x03 would over-read the
>      buffer by one byte.
> 
> [...]

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git (for-7.1/upstream-fixes), thanks!

[1/1] HID: lenovo: Fix buffer over-read and unaligned access in X12 Tab raw_event handler
      https://git.kernel.org/hid/hid/c/c7ee0b73c8c4

Cheers,
-- 
Benjamin Tissoires <bentiss@kernel.org>