Re: [PATCH 5/5] HID: wacom: check the input devices in the Bamboo handlers

From: Jason Gerecke

Date: Fri Oct 16 2026 - 20:08:15 EST


On Sat, Sep 26, 2026 at 9:12 PM Jinmo Yang <jinmo44.yang@xxxxxxxxx> wrote:
>
> wacom_bpt_touch() takes both touch_input and pad_input, and
> wacom_bpt3_touch_msg() and wacom_bpt3_button_msg() take touch_input and
> pad_input respectively, none of them checked. An interface that declares
> only pen usages leaves touch_input and pad_input NULL on a fully
> successful probe, and wacom_bpt_irq() still dispatches to these
> handlers.
>
Similar to patch 2/5 and 4/5, I believe wacom_bpt_touch only operates
on devices that are expected to have both touch and pad input. To the
best of my knowledge, this function is exclusively used by
1st-generation Bamboo Touch hardware which mixes touch and pad data in
the same report (both get reported side-by-side). The original
implementation of the code in cb734c03680e ("Input: wacom - add
support for the Bamboo Touch trackpad") highlights this mixing on the
same interface. As with the other patches, a single check that both
touch and pad are valid at the beginning of the function should be
valid.

> Four locations fault, each reproduced on linux-next 20260925 (x86_64,
> KASAN) from one /dev/uhid device plus a single UHID_INPUT2 write:
>
> wacom_wac.c:3100 wacom_bpt_touch touch_input
> wacom_wac.c:3117 wacom_bpt_touch pad_input
> wacom_wac.c:3130 wacom_bpt3_touch_msg touch_input
> wacom_wac.c:3178 wacom_bpt3_button_msg pad_input
>
> for example, with vendor 0x056a product 0x00D4 (BAMBOO_PEN), a pen-only
> descriptor and report id 2:
>
> BUG: KASAN: null-ptr-deref in input_event+0x44/0xb0
> Read of size 8 at addr 0000000000000028
> wacom_wac_irq+0x8185/0xb3f0
> wacom_raw_event+0x68f/0xb60
> __hid_input_report+0x398/0x4d0
> uhid_char_write+0xa99/0xfc0
>
> wacom_bpt_touch() serves touch and pad in one report, so its two blocks
> are guarded separately - an interface with a pad but no touch must keep
> delivering pad events. In wacom_bpt3_touch_msg() the slot lookup moves
> below the check because it dereferences the input device itself.
>
> The touch block of wacom_bpt_touch() is reindented into the new
> conditional; git diff -w shows no change there beyond the two style
> fixes checkpatch asks for on the lines that move.
>
> Fixes: 2a6cdbdd4cc0 ("HID: wacom: Introduce new 'touch_input' device")
> Fixes: 3116871f4273 ("Input: wacom - split out the pad device for Bamboos")
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Jinmo Yang <jinmo44.yang@xxxxxxxxx>
> ---
> drivers/hid/wacom_wac.c | 56 +++++++++++++++++++++++++----------------
> 1 file changed, 34 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
> index 11544adb74f5..dac67885f81e 100644
> --- a/drivers/hid/wacom_wac.c
> +++ b/drivers/hid/wacom_wac.c
> @@ -3118,31 +3118,36 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
> if (data[0] != 0x02)
> return 0;
>
> - for (i = 0; i < 2; i++) {
> - int offset = (data[1] & 0x80) ? (8 * i) : (9 * i);
> - bool touch = report_touch_events(wacom)
> - && (data[offset + 3] & 0x80);
> -
> - input_mt_slot(input, i);
> - input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
> - if (touch) {
> - int x = get_unaligned_be16(&data[offset + 3]) & 0x7ff;
> - int y = get_unaligned_be16(&data[offset + 5]) & 0x7ff;
> - if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) {
> - x <<= 5;
> - y <<= 5;
> + if (input) {
> + for (i = 0; i < 2; i++) {
> + int offset = (data[1] & 0x80) ? (8 * i) : (9 * i);
> + bool touch = report_touch_events(wacom) &&
> + (data[offset + 3] & 0x80);
> +
> + input_mt_slot(input, i);
> + input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
> + if (touch) {
> + int x = get_unaligned_be16(&data[offset + 3]) & 0x7ff;
> + int y = get_unaligned_be16(&data[offset + 5]) & 0x7ff;
> +
> + if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) {
> + x <<= 5;
> + y <<= 5;
> + }
> + input_report_abs(input, ABS_MT_POSITION_X, x);
> + input_report_abs(input, ABS_MT_POSITION_Y, y);
> }
> - input_report_abs(input, ABS_MT_POSITION_X, x);
> - input_report_abs(input, ABS_MT_POSITION_Y, y);
> }
> - }
>
> - input_mt_sync_frame(input);
> + input_mt_sync_frame(input);
> + }
>
> - input_report_key(pad_input, BTN_LEFT, (data[1] & 0x08) != 0);
> - input_report_key(pad_input, BTN_FORWARD, (data[1] & 0x04) != 0);
> - input_report_key(pad_input, BTN_BACK, (data[1] & 0x02) != 0);
> - input_report_key(pad_input, BTN_RIGHT, (data[1] & 0x01) != 0);
> + if (pad_input) {
> + input_report_key(pad_input, BTN_LEFT, (data[1] & 0x08) != 0);
> + input_report_key(pad_input, BTN_FORWARD, (data[1] & 0x04) != 0);
> + input_report_key(pad_input, BTN_BACK, (data[1] & 0x02) != 0);
> + input_report_key(pad_input, BTN_RIGHT, (data[1] & 0x01) != 0);
> + }
> wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom);
>
> return 1;
> @@ -3153,8 +3158,12 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)
> struct wacom_features *features = &wacom->features;
> struct input_dev *input = wacom->touch_input;
> bool touch = data[1] & 0x80;
> - int slot = input_mt_get_slot_by_key(input, data[0]);
> + int slot;
>
> + if (!input)
> + return;
> +
> + slot = input_mt_get_slot_by_key(input, data[0]);
> if (slot < 0)
> return;
>
> @@ -3196,6 +3205,9 @@ static void wacom_bpt3_button_msg(struct wacom_wac *wacom, unsigned char *data)
> struct input_dev *input = wacom->pad_input;
> struct wacom_features *features = &wacom->features;
>
> + if (!input)
> + return;
> +

As with patch 1, each of these checks is for an unusual error
condition so a dev_warn_once or hid_warn_once before returning is
suggested.

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....


> if (features->type == INTUOSHT || features->type == INTUOSHT2) {
> input_report_key(input, BTN_LEFT, (data[1] & 0x02) != 0);
> input_report_key(input, BTN_BACK, (data[1] & 0x08) != 0);
> --
> 2.53.0
>
>