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