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

From
Jason Gerecke <hidden>
Date
2026-10-17 00:06:05
Also in
lkml, stable
Reply to
Jinmo Yang, 2026-09-27
On Sat, Sep 26, 2026 at 9:12 PM Jinmo Yang [off-list ref] 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.
quoted hunk ↗ jump to hunk
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: <redacted>
Signed-off-by: Jinmo Yang <redacted>
---
 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
Thread (46 messages) 46 messages, 5 authors, last reply 3d ago
Keyboard shortcuts
hback out one level
jnext message in thread / next series-diff position
kprevious message in thread / previous series-diff position
ldrill in
Escclose help / fold thread tree
?toggle this help