Linux kernel -stable discussions
 help / color / mirror / Atom feed
* [PATCH] HID: wacom: validate report length before Intuos Pro2 BT pen parse
@ 2026-07-13  7:51 Ibrahim Hashimov
  2026-07-13  9:34 ` [PATCH v2] HID: wacom: validate report length in wacom_intuos_pro2_bt_irq Ibrahim Hashimov
  0 siblings, 1 reply; 5+ messages in thread
From: Ibrahim Hashimov @ 2026-07-13  7:51 UTC (permalink / raw)
  To: Ping Cheng, Jason Gerecke, Jiri Kosina, Benjamin Tissoires
  Cc: linux-input, linux-kernel, stable

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)


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2] HID: wacom: validate report length in wacom_intuos_pro2_bt_irq
  2026-07-13  7:51 [PATCH] HID: wacom: validate report length before Intuos Pro2 BT pen parse Ibrahim Hashimov
@ 2026-07-13  9:34 ` Ibrahim Hashimov
  2026-08-14 12:24   ` Jiri Kosina
  2026-08-21 14:01   ` Jiri Kosina
  0 siblings, 2 replies; 5+ messages in thread
From: Ibrahim Hashimov @ 2026-07-13  9:34 UTC (permalink / raw)
  To: ping.cheng, jason.gerecke, jikos, bentiss
  Cc: dmitry.torokhov, linux-input, linux-kernel, stable

wacom_intuos_pro2_bt_irq() receives the wire report length in `len`
but never consults it before parsing. After the report-id gate it
unconditionally calls wacom_intuos_pro2_bt_pen() and then, selected by
features.type, a fixed chain of sub-parsers, none of which receive
`len`:

	wacom_intuos_pro2_bt_pen(wacom);
	if (type == INTUOSP2_BT || type == INTUOSP2S_BT) {
		wacom_intuos_pro2_bt_touch(wacom);
		wacom_intuos_pro2_bt_pad(wacom);
		wacom_intuos_pro2_bt_battery(wacom);
	} else {
		wacom_intuos_gen3_bt_pad(wacom);
		wacom_intuos_gen3_bt_battery(wacom);
	}

Each sub-parser dereferences wacom->data at fixed offsets. The furthest
byte touched on each branch is:

  INTUOSP2_BT / INTUOSP2S_BT: wacom_intuos_pro2_bt_pad() reads data[285]
	(the touchring byte), so the report must be at least 286 bytes;
  INTUOSHT3_BT ("gen3"): wacom_intuos_gen3_bt_battery() reads data[45],
	so the report must be at least 46 bytes.

features.type is selected from the VID/PID id_table entry 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 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 / ABS_WHEEL on the pen and pad input nodes), an out-of-bounds
read with a concrete userspace read-back channel, and a true
out-of-bounds read on transports whose backing buffer is sized to the
(small) report descriptor rather than a fixed-size staging buffer.

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 wacom_intuos_bt_irq(), which guards each report id against its
minimum length before parsing.

Guard wacom_intuos_pro2_bt_irq() the same way: before parsing, reject
reports shorter than the furthest offset the selected branch actually
dereferences, warn, and bail out. Because the whole pen/touch/pad/
battery chain runs unconditionally per branch, a single up-front check
against the maximum offset (286 bytes for INTUOSP2_BT/INTUOSP2S_BT,
46 bytes for the gen3 branch) bounds every sub-parser. Returning 0 on
a short report also skips those calls for the same malformed report,
which is the safe, conservative behavior.

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
---
v2: the v1 check (len < 109 / len < 43) only bounded
    wacom_intuos_pro2_bt_pen(). As sashiko-bot pointed out, the
    unconditional touch/pad/battery calls read much further --
    wacom_intuos_pro2_bt_pad() up to data[285] and
    wacom_intuos_gen3_bt_battery() up to data[45] -- so a report in the
    gap (109..285 / 43..45) passed the guard yet still over-read. Raise
    the minimums to the furthest offset each branch dereferences
    (286 / 46) so the guard actually bounds the whole call chain.

 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 < 286) {
+			dev_warn(wacom->pen_input->dev.parent,
+				 "Pro2 BT report too short: %zu bytes\n", len);
+			return 0;
+		}
+	} else if (len < 46) {
+		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)


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] HID: wacom: validate report length in wacom_intuos_pro2_bt_irq
  2026-07-13  9:34 ` [PATCH v2] HID: wacom: validate report length in wacom_intuos_pro2_bt_irq Ibrahim Hashimov
@ 2026-08-14 12:24   ` Jiri Kosina
  2026-08-14 22:00     ` Jason Gerecke
  2026-08-21 14:01   ` Jiri Kosina
  1 sibling, 1 reply; 5+ messages in thread
From: Jiri Kosina @ 2026-08-14 12:24 UTC (permalink / raw)
  To: Ibrahim Hashimov
  Cc: ping.cheng, jason.gerecke, bentiss, dmitry.torokhov, linux-input,
	linux-kernel, stable

Ping, Jason, could you please Ack this one? Looks good to me, but I always 
prefer to have an Ack from one of you on the Wacom HID driver.

Thanks,

-- 
Jiri Kosina
SUSE Labs

On Mon, 13 Jul 2026, Ibrahim Hashimov wrote:

> wacom_intuos_pro2_bt_irq() receives the wire report length in `len`
> but never consults it before parsing. After the report-id gate it
> unconditionally calls wacom_intuos_pro2_bt_pen() and then, selected by
> features.type, a fixed chain of sub-parsers, none of which receive
> `len`:
> 
> 	wacom_intuos_pro2_bt_pen(wacom);
> 	if (type == INTUOSP2_BT || type == INTUOSP2S_BT) {
> 		wacom_intuos_pro2_bt_touch(wacom);
> 		wacom_intuos_pro2_bt_pad(wacom);
> 		wacom_intuos_pro2_bt_battery(wacom);
> 	} else {
> 		wacom_intuos_gen3_bt_pad(wacom);
> 		wacom_intuos_gen3_bt_battery(wacom);
> 	}
> 
> Each sub-parser dereferences wacom->data at fixed offsets. The furthest
> byte touched on each branch is:
> 
>   INTUOSP2_BT / INTUOSP2S_BT: wacom_intuos_pro2_bt_pad() reads data[285]
> 	(the touchring byte), so the report must be at least 286 bytes;
>   INTUOSHT3_BT ("gen3"): wacom_intuos_gen3_bt_battery() reads data[45],
> 	so the report must be at least 46 bytes.
> 
> features.type is selected from the VID/PID id_table entry 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 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 / ABS_WHEEL on the pen and pad input nodes), an out-of-bounds
> read with a concrete userspace read-back channel, and a true
> out-of-bounds read on transports whose backing buffer is sized to the
> (small) report descriptor rather than a fixed-size staging buffer.
> 
> 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 wacom_intuos_bt_irq(), which guards each report id against its
> minimum length before parsing.
> 
> Guard wacom_intuos_pro2_bt_irq() the same way: before parsing, reject
> reports shorter than the furthest offset the selected branch actually
> dereferences, warn, and bail out. Because the whole pen/touch/pad/
> battery chain runs unconditionally per branch, a single up-front check
> against the maximum offset (286 bytes for INTUOSP2_BT/INTUOSP2S_BT,
> 46 bytes for the gen3 branch) bounds every sub-parser. Returning 0 on
> a short report also skips those calls for the same malformed report,
> which is the safe, conservative behavior.
> 
> 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
> ---
> v2: the v1 check (len < 109 / len < 43) only bounded
>     wacom_intuos_pro2_bt_pen(). As sashiko-bot pointed out, the
>     unconditional touch/pad/battery calls read much further --
>     wacom_intuos_pro2_bt_pad() up to data[285] and
>     wacom_intuos_gen3_bt_battery() up to data[45] -- so a report in the
>     gap (109..285 / 43..45) passed the guard yet still over-read. Raise
>     the minimums to the furthest offset each branch dereferences
>     (286 / 46) so the guard actually bounds the whole call chain.
> 
>  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 < 286) {
> +			dev_warn(wacom->pen_input->dev.parent,
> +				 "Pro2 BT report too short: %zu bytes\n", len);
> +			return 0;
> +		}
> +	} else if (len < 46) {
> +		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)
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] HID: wacom: validate report length in wacom_intuos_pro2_bt_irq
  2026-08-14 12:24   ` Jiri Kosina
@ 2026-08-14 22:00     ` Jason Gerecke
  0 siblings, 0 replies; 5+ messages in thread
From: Jason Gerecke @ 2026-08-14 22:00 UTC (permalink / raw)
  To: Jiri Kosina
  Cc: Ibrahim Hashimov, ping.cheng, jason.gerecke, bentiss,
	dmitry.torokhov, linux-input, linux-kernel, stable

On Fri, Aug 14, 2026 at 5:24 AM Jiri Kosina <jikos@kernel.org> wrote:
>
> Ping, Jason, could you please Ack this one? Looks good to me, but I always
> prefer to have an Ack from one of you on the Wacom HID driver.
>

LGTM. I suspect there are plenty more similar cases that need
cleaning, but this is a straightforward improvement.

Acked-by: Jason Gerecke <jason.gerecke@wacom.com>

Jason (she/they)
---
Now instead of four in the eights place /
you’ve got three, ‘Cause you added one  /
(That is to say, eight) to the two,     /
But you can’t take seven from three,    /
So you look at the sixty-fours....

> Thanks,
>
> --
> Jiri Kosina
> SUSE Labs
>
> On Mon, 13 Jul 2026, Ibrahim Hashimov wrote:
>
> > wacom_intuos_pro2_bt_irq() receives the wire report length in `len`
> > but never consults it before parsing. After the report-id gate it
> > unconditionally calls wacom_intuos_pro2_bt_pen() and then, selected by
> > features.type, a fixed chain of sub-parsers, none of which receive
> > `len`:
> >
> >       wacom_intuos_pro2_bt_pen(wacom);
> >       if (type == INTUOSP2_BT || type == INTUOSP2S_BT) {
> >               wacom_intuos_pro2_bt_touch(wacom);
> >               wacom_intuos_pro2_bt_pad(wacom);
> >               wacom_intuos_pro2_bt_battery(wacom);
> >       } else {
> >               wacom_intuos_gen3_bt_pad(wacom);
> >               wacom_intuos_gen3_bt_battery(wacom);
> >       }
> >
> > Each sub-parser dereferences wacom->data at fixed offsets. The furthest
> > byte touched on each branch is:
> >
> >   INTUOSP2_BT / INTUOSP2S_BT: wacom_intuos_pro2_bt_pad() reads data[285]
> >       (the touchring byte), so the report must be at least 286 bytes;
> >   INTUOSHT3_BT ("gen3"): wacom_intuos_gen3_bt_battery() reads data[45],
> >       so the report must be at least 46 bytes.
> >
> > features.type is selected from the VID/PID id_table entry 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 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 / ABS_WHEEL on the pen and pad input nodes), an out-of-bounds
> > read with a concrete userspace read-back channel, and a true
> > out-of-bounds read on transports whose backing buffer is sized to the
> > (small) report descriptor rather than a fixed-size staging buffer.
> >
> > 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 wacom_intuos_bt_irq(), which guards each report id against its
> > minimum length before parsing.
> >
> > Guard wacom_intuos_pro2_bt_irq() the same way: before parsing, reject
> > reports shorter than the furthest offset the selected branch actually
> > dereferences, warn, and bail out. Because the whole pen/touch/pad/
> > battery chain runs unconditionally per branch, a single up-front check
> > against the maximum offset (286 bytes for INTUOSP2_BT/INTUOSP2S_BT,
> > 46 bytes for the gen3 branch) bounds every sub-parser. Returning 0 on
> > a short report also skips those calls for the same malformed report,
> > which is the safe, conservative behavior.
> >
> > 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
> > ---
> > v2: the v1 check (len < 109 / len < 43) only bounded
> >     wacom_intuos_pro2_bt_pen(). As sashiko-bot pointed out, the
> >     unconditional touch/pad/battery calls read much further --
> >     wacom_intuos_pro2_bt_pad() up to data[285] and
> >     wacom_intuos_gen3_bt_battery() up to data[45] -- so a report in the
> >     gap (109..285 / 43..45) passed the guard yet still over-read. Raise
> >     the minimums to the furthest offset each branch dereferences
> >     (286 / 46) so the guard actually bounds the whole call chain.
> >
> >  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 < 286) {
> > +                     dev_warn(wacom->pen_input->dev.parent,
> > +                              "Pro2 BT report too short: %zu bytes\n", len);
> > +                     return 0;
> > +             }
> > +     } else if (len < 46) {
> > +             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)
> >
>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] HID: wacom: validate report length in wacom_intuos_pro2_bt_irq
  2026-07-13  9:34 ` [PATCH v2] HID: wacom: validate report length in wacom_intuos_pro2_bt_irq Ibrahim Hashimov
  2026-08-14 12:24   ` Jiri Kosina
@ 2026-08-21 14:01   ` Jiri Kosina
  1 sibling, 0 replies; 5+ messages in thread
From: Jiri Kosina @ 2026-08-21 14:01 UTC (permalink / raw)
  To: Ibrahim Hashimov
  Cc: ping.cheng, jason.gerecke, bentiss, dmitry.torokhov, linux-input,
	linux-kernel, stable

On Mon, 13 Jul 2026, Ibrahim Hashimov wrote:

> wacom_intuos_pro2_bt_irq() receives the wire report length in `len`
> but never consults it before parsing. After the report-id gate it
> unconditionally calls wacom_intuos_pro2_bt_pen() and then, selected by
> features.type, a fixed chain of sub-parsers, none of which receive
> `len`:
> 
> 	wacom_intuos_pro2_bt_pen(wacom);
> 	if (type == INTUOSP2_BT || type == INTUOSP2S_BT) {
> 		wacom_intuos_pro2_bt_touch(wacom);
> 		wacom_intuos_pro2_bt_pad(wacom);
> 		wacom_intuos_pro2_bt_battery(wacom);
> 	} else {
> 		wacom_intuos_gen3_bt_pad(wacom);
> 		wacom_intuos_gen3_bt_battery(wacom);
> 	}
> 
> Each sub-parser dereferences wacom->data at fixed offsets. The furthest
> byte touched on each branch is:
> 
>   INTUOSP2_BT / INTUOSP2S_BT: wacom_intuos_pro2_bt_pad() reads data[285]
> 	(the touchring byte), so the report must be at least 286 bytes;
>   INTUOSHT3_BT ("gen3"): wacom_intuos_gen3_bt_battery() reads data[45],
> 	so the report must be at least 46 bytes.
> 
> features.type is selected from the VID/PID id_table entry 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 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 / ABS_WHEEL on the pen and pad input nodes), an out-of-bounds
> read with a concrete userspace read-back channel, and a true
> out-of-bounds read on transports whose backing buffer is sized to the
> (small) report descriptor rather than a fixed-size staging buffer.
> 
> 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 wacom_intuos_bt_irq(), which guards each report id against its
> minimum length before parsing.
> 
> Guard wacom_intuos_pro2_bt_irq() the same way: before parsing, reject
> reports shorter than the furthest offset the selected branch actually
> dereferences, warn, and bail out. Because the whole pen/touch/pad/
> battery chain runs unconditionally per branch, a single up-front check
> against the maximum offset (286 bytes for INTUOSP2_BT/INTUOSP2S_BT,
> 46 bytes for the gen3 branch) bounds every sub-parser. Returning 0 on
> a short report also skips those calls for the same malformed report,
> which is the safe, conservative behavior.
> 
> 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

Applied, thanks.

-- 
Jiri Kosina
SUSE Labs


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-08-21 14:02 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-13  7:51 [PATCH] HID: wacom: validate report length before Intuos Pro2 BT pen parse Ibrahim Hashimov
2026-07-13  9:34 ` [PATCH v2] HID: wacom: validate report length in wacom_intuos_pro2_bt_irq Ibrahim Hashimov
2026-08-14 12:24   ` Jiri Kosina
2026-08-14 22:00     ` Jason Gerecke
2026-08-21 14:01   ` Jiri Kosina

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox