From: Ibrahim Hashimov <security@auditcode.ai>
To: Ping Cheng <ping.cheng@wacom.com>,
Jason Gerecke <jason.gerecke@wacom.com>,
Jiri Kosina <jikos@kernel.org>,
Benjamin Tissoires <bentiss@kernel.org>
Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org,
stable@vger.kernel.org
Subject: [PATCH] HID: wacom: validate report length before Intuos Pro2 BT pen parse
Date: Mon, 13 Jul 2026 09:51:10 +0200 [thread overview]
Message-ID: <20260713075110.92469-1-security@auditcode.ai> (raw)
wacom_intuos_pro2_bt_irq() receives the wire report length in `len`
but never consults it before calling wacom_intuos_pro2_bt_pen(). The
only admission check on this path is the report-id byte:
if (data[0] != 0x80 && data[0] != 0x81) {
...
return 0;
}
wacom_intuos_pro2_bt_pen(wacom);
wacom_intuos_pro2_bt_pen() itself does not even receive `len` (it
takes only `struct wacom_wac *wacom`), so it cannot bound its own
reads. For INTUOSP2_BT / INTUOSP2S_BT devices it unconditionally does:
wacom->serial[0] = get_unaligned_le64(&data[99]);
wacom->id[0] = get_unaligned_le16(&data[107]);
i.e. it reads up to offset 108 regardless of how many bytes the
peripheral actually sent. features.type is selected from the VID/PID
id_table entry (BT_DEVICE_WACOM(0x361) -> INTUOSP2_BT) and
wacom_setup_device_quirks() force-registers the pen/pad/touch inputs
for that type independent of the report descriptor, so a malicious or
malfunctioning paired/spoofed Bluetooth peripheral can advertise that
VID/PID and send an undersized report (e.g. 10 bytes) that still
satisfies the data[0] == 0x80/0x81 gate. The driver then reads past
the received report and forwards the bytes to userspace via evdev
(MSC_SERIAL / ABS_MISC on the pen input node), an out-of-bounds read
with a concrete userspace read-back channel, and a true
out-of-bounds read on transports where the backing buffer is sized to
the (small) report descriptor rather than a fixed-size staging
buffer.
The non-Pro2 branch of the same function (INTUOSHT3_BT, reading
&data[33]/&data[41]) has the identical defect at a smaller offset.
This is the same class of bug commit 2f1763f62909 ("HID: wacom: fix
out-of-bounds read in wacom_intuos_bt_irq") already hardened in the
sibling function wacom_intuos_bt_irq(), which added explicit
short-report guards before parsing:
case 0x04:
if (len < 32) {
dev_warn(..., "Report 0x04 too short: %zu bytes\n", len);
break;
}
wacom_intuos_bt_process_data(wacom, data + i);
...
case 0x03:
if (i == 1 && len < 22) {
dev_warn(..., "Report 0x03 too short: %zu bytes\n", len);
break;
}
wacom_intuos_pro2_bt_irq() never received the analogous guard.
Fix it the same way: before calling wacom_intuos_pro2_bt_pen(), check
`len` against the minimum size each branch of that function actually
dereferences (109 bytes for INTUOSP2_BT/INTUOSP2S_BT, whose furthest
read is &data[107] as a le16 -> byte index 108; 43 bytes for the
INTUOSHT3_BT ("gen3") branch, whose furthest read is &data[41] as a
le16 -> byte index 42). On a short report, warn and bail out before
touching wacom->data past what was actually received, exactly as
wacom_intuos_bt_irq() now does for its own report ids. Returning 0
here also skips the subsequent pro2 touch/pad/battery calls for the
same malformed report, which is the safe, conservative behavior.
Runtime-verified on a v6.19 stand: injecting the truncated report
via a spoofed 056a:0361 BT peripheral leaks bytes past the declared
report length to the pen evdev node (MSC_SERIAL / ABS_MISC) before
this fix, and the same input is rejected by the new length check
with no leaked event afterward. KASAN itself stays quiet on the
fixed-size uhid staging buffer used to inject the report (the
over-read there lands in-object); on a descriptor-sized USB/BT
buffer the identical read crosses the slab boundary and is a
genuine KASAN-visible out-of-bounds read.
Fixes: 4922cd26f03c ("HID: wacom: Support 2nd-gen Intuos Pro's Bluetooth classic interface")
Cc: stable@vger.kernel.org
Signed-off-by: Ibrahim Hashimov <security@auditcode.ai>
Assisted-by: AuditCode-AI:2026.07
---
drivers/hid/wacom_wac.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index da1f0ea85625..89a191cf1924 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -1548,6 +1548,19 @@ static int wacom_intuos_pro2_bt_irq(struct wacom_wac *wacom, size_t len)
return 0;
}
+ if (wacom->features.type == INTUOSP2_BT ||
+ wacom->features.type == INTUOSP2S_BT) {
+ if (len < 109) {
+ dev_warn(wacom->pen_input->dev.parent,
+ "Pro2 BT report too short: %zu bytes\n", len);
+ return 0;
+ }
+ } else if (len < 43) {
+ dev_warn(wacom->pen_input->dev.parent,
+ "Pro2 BT report too short: %zu bytes\n", len);
+ return 0;
+ }
+
wacom_intuos_pro2_bt_pen(wacom);
if (wacom->features.type == INTUOSP2_BT ||
wacom->features.type == INTUOSP2S_BT) {
--
2.50.1 (Apple Git-155)
next reply other threads:[~2026-07-13 7:51 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-13 7:51 Ibrahim Hashimov [this message]
2026-07-13 8:01 ` [PATCH] HID: wacom: validate report length before Intuos Pro2 BT pen parse sashiko-bot
2026-07-13 9:34 ` [PATCH v2] HID: wacom: validate report length in wacom_intuos_pro2_bt_irq Ibrahim Hashimov
2026-07-13 10:11 ` sashiko-bot
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=20260713075110.92469-1-security@auditcode.ai \
--to=security@auditcode.ai \
--cc=bentiss@kernel.org \
--cc=jason.gerecke@wacom.com \
--cc=jikos@kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=ping.cheng@wacom.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.