From nobody Mon Sep 28 11:39:40 2026 Received: from mail-pf1-f174.google.com (mail-pf1-f174.google.com [209.85.210.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 51957376A19 for ; Sat, 22 Aug 2026 12:09:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787400586; cv=none; b=X94vvuZVoMxIAy/pYezvPpBf74L6U7Ac66rnDmuZCLMO9/4p0xoQz7ELnXIRYjDd8mxZbKkCQlCmzammGNhizouM+JlLUQ01p1M32UAh+5hzCfvmF1NhvV348LNTuE91qm3zAsH0h76levJOX6lpicltfsdlAgBMi0aPcMSpe6o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787400586; c=relaxed/simple; bh=X1gs4Rva48xs0lcq8cHDkmtAyL1/AiKJnqkvkBF40+M=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=OCt57as5mIxRQ9i96mjjGn5DMi8buD47l3c6onS2/xdMbeTzdXk8417rJhdBYTv8ygWt8M7Dv2APkKveHMeoSqF+95nDQIK/80EpCoUkIOh3pt4mi1B31JQhgqTVVREI7grlE1ObVCamv9QLB6SNjFJCwn9JLEkql+eBX/O74jQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=mI4jbV/+; arc=none smtp.client-ip=209.85.210.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="mI4jbV/+" Received: by mail-pf1-f174.google.com with SMTP id d2e1a72fcca58-84830c774a0so2175037b3a.1 for ; Sat, 22 Aug 2026 05:09:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787400584; x=1788005384; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=Iq05ZZV6+TyT8orO7GiiiROR88YN4CoCixnRT+X/gZU=; b=mI4jbV/+5n7r8oClgNIkx+NFbA8W4HjRNtNTxrMeb9ABTEXzmDvMlrEoMFIB5YWo+4 SlFeHSQr1NOrcAVp/+jhhmj8MVP4RHF0nXXOvzbN6t4e0mYBRsi5cS+RAz80gKmFlgrQ wev5EqGnM330goiVOas5YmquPW0xAFzJJzgLaIQJ9pZVxJzgVIkkO38aqM6SovrXBcSD QnoZRDl7AmIEqksCzccEiGQyMdEIeVBqN7PS/0x6m/C6LwpjrM5VWCX4CD5DdemGpNYh Ur7gpQ7i6GSxyAfCPdyJtwCUsjgBb8ILCmn/eRcpBYsMycZXuf+qUl0f68cdVaXrCwDO Fe9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787400584; x=1788005384; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Iq05ZZV6+TyT8orO7GiiiROR88YN4CoCixnRT+X/gZU=; b=rIv1ASjsG9jrlRlNKERr3QFIxj8ZLg7alG0Q7fLugUBhznN0EzMjt8HQ80Nol0Cw+M Sb1Z7sg5x77x2KgSfYDYWgDkFsPf5IKvesyE/CYHMqdVkQiFzh1Eeu3FwGONtH2tCt5B xpvu33LwRow7Kb83wXL9JwhE8JEEIqtSNdV+rJaMpo+mo7YqFPLDLUbXGvzRjn4Hjde+ ZmaELXGyWhg4ppnKqrbyNKAv10OrYx86QlHeQK1yqgz5Y8vv663F3jGjaJJhiFJRZZas 3TLX7TokxzzXCXebY6Odp3Kwn8/jtqEa+Ze/9X8lRz68zJgYhVUUGw1XgOdHU8OLn3xP l+Hg== X-Forwarded-Encrypted: i=1; AHgh+RqTdqvfz6HaDBtChYtOfpirxMMiHr3SYxYLUcUJfdypPfC2/Al1HRK+SxbtvLCrIoygQu8Z+hLobIlLvbg=@vger.kernel.org X-Gm-Message-State: AFuF++k7pnMvzN7AqGhIyysvnXWSVTx4jTzBGJafp+YfrdzsSN+X2ZjU fFDx+vaQy/dpUob4ptRRTeXVS9sqdklw1ckO7FQ9V/XxULmYVLRmcL6l X-Gm-Gg: AR+sD1121E3r/EeU8EETR7+E78nCNbsPWR7Tv0yX7c5PQZV8OmLndMWPouN7lkkiqIV ldCCkdFZ9u8GAaqMwSqd0IPV2G/TAvwSfA9yHVFt5AWHT5v2qBXQXO/y3o+4O1eMS24zPy9I/6U vBLl7XfNVd1w4dZmq4q1QLhQwmBT8vPRq7Uhcnn5M8fp7POn1Vbn1kCv6qW1tOI9gEjNP2Nm4lv dqlVZmo19BHFz86aCdWq6o4E+BszVtuSnHNEKUAM+2AnmDb+Z0DcArkCT7ZGawNOfZWREfnEn0L Ux89417Af2cO3yh6h4lRZpkFqCx8+Lyyup/vf9VyexzyJ0NaovGOelR5x7Q0LYig4hxxBwZ2BaW bzCVp5tO67FApELo6BpdSJRsgHbnBBgehAaL4haxSiEfwZxZdfntrSy8WxANSUUNtHux6bU7BsX fwrrm3uQSWrOvRtHcGMyjrIgmNTrcf+ATJFJNU3lBjvMr2XOQ9eaR7z/8qQYHq2z75/+ei/PL1o +HDXUdpDjJy3D/cCPJtKNSAh6257vr2qByJ7CYw0KXrfUE/hto2kZ6j839WzUyybvLnWqoF9s9V Kfq/LdZsfQGrXqhjN2PzsrDa X-Received: by 2002:a05:6a00:39a1:b0:847:93f3:a4b6 with SMTP id d2e1a72fcca58-851fa0667d8mr19516948b3a.17.1787400584464; Sat, 22 Aug 2026 05:09:44 -0700 (PDT) Received: from LAPTOP-UUUVNN1I.localdomain (bb119-74-6-224.singnet.com.sg. [119.74.6.224]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-8520eedccb1sm557171b3a.8.2026.08.22.05.09.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 22 Aug 2026 05:09:43 -0700 (PDT) From: Wei Jie Law <98lawweijie@gmail.com> To: Ping Cheng , Jason Gerecke , Jiri Kosina , Benjamin Tissoires Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] HID: wacom: fix OOB read in wacom_wac_pen_serial_enforce() Date: Sat, 22 Aug 2026 20:09:26 +0800 Message-ID: <20260822120926.153849-1-98lawweijie@gmail.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" wacom_wac_pen_serial_enforce() iterates over a field's usages (up to field->maxusage) but indexes the report bits by j * report_size: for (i =3D 0; i < report->maxfield; i++) { for (j =3D 0; j < report->field[i]->maxusage; j++) { ... value =3D hid_field_extract(hdev, raw_data + 1, offset + j * size, size); In hid_add_field() the usage array is sized max(usage_index, report_count), so field->maxusage can be far larger than report_count when a descriptor lists more usages than its Report Count. A field declaring Usage Minimum 0 / Usage Maximum 0x2ffe with Report Count 1 gives maxusage =3D=3D 12288 while the field's bit region is only 8 bits wide. The extract at j =3D=3D 12287 then reads bit offset 12287 * 8, i.e. byte 12287 of raw_data + 1, roughly 12 KB past a 2-byte received report. __extract() performs no bounds check. The value read that way is stored into wacom_wac->serial[0] and can be emitted to userspace as an MSC_SERIAL event by wacom_wac_pen_report(), so this is an information disclosure and not just an out-of-bounds read. A malicious device only has to claim vendor id 0x056a for hid_scan_report() to place it in HID_GROUP_WACOM and have this driver bound to it, and a single crafted input report is enough to trigger the read. Clamp the inner loop to the field's actual report region with min(maxusage, report_count), so usages that have no report data behind them are no longer extracted. Verified on v6.12.104, whose wacom_sys.c is identical to mainline here, with a UHID reproducer and with an emulated USB device (raw-gadget): a hardware watchpoint on wacom_wac->serial[0] fires with an out-of-bounds heap byte while a 2-byte report is being processed, and no longer fires once the loop is clamped. Fixes: 83417206427b ("HID: wacom: Queue events with missing type/serial dat= a for later processing") Cc: stable@vger.kernel.org Signed-off-by: Wei Jie Law <98lawweijie@gmail.com> --- The reproducer is available on request. Compile-tested on bd5f485f3f02, x86_64 defconfig + CONFIG_HID_WACOM=3Dy. drivers/hid/wacom_sys.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 0eafa483b7f7..1ea8763b68a8 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -113,8 +113,10 @@ static int wacom_wac_pen_serial_enforce(struct hid_dev= ice *hdev, =20 /* Queue events which have invalid tool type or serial number */ for (i =3D 0; i < report->maxfield; i++) { - for (j =3D 0; j < report->field[i]->maxusage; j++) { - struct hid_field *field =3D report->field[i]; + struct hid_field *field =3D report->field[i]; + unsigned int count =3D min(field->maxusage, field->report_count); + + for (j =3D 0; j < count; j++) { struct hid_usage *usage =3D &field->usage[j]; unsigned int equivalent_usage =3D wacom_equivalent_usage(usage->hid); unsigned int offset; base-commit: bd5f485f3f026225b86573e559af0b7254ef4184 --=20 2.43.0