* [PATCH] HID: wacom: fix NULL pointer dereference in wacom_intuos_pad()
@ 2026-05-23 15:01 Jinmo Yang
2026-05-23 15:06 ` [PATCH v2] " Jinmo Yang
2026-05-23 15:45 ` [PATCH] HID: wacom: fix NULL pointer dereference in wacom_intuos_pad() sashiko-bot
0 siblings, 2 replies; 36+ messages in thread
From: Jinmo Yang @ 2026-05-23 15:01 UTC (permalink / raw)
To: Ping Cheng, Jason Gerecke, Jiri Kosina, Benjamin Tissoires
Cc: linux-input, linux-kernel, Jinmo Yang
wacom_intuos_pad() dereferences wacom->pad_input without a NULL check.
When a Wacom tablet is created via UHID with parameters that route
through wacom_bpt_irq() -> wacom_intuos_irq() -> wacom_intuos_pad(),
but probe did not allocate pad_input, the call to
wacom_report_numbered_buttons() passes a NULL input_dev, causing a
general protection fault in input_get_drvdata().
Add a NULL check for pad_input at the top of wacom_intuos_pad() to
bail out early when the pad input device was not set up.
The bug was found by syzkaller and confirmed on a Pixel 9 Pro
(Android 16, kernel 6.1.124) where it causes an immediate kernel
panic and reboot via /dev/uhid without requiring root privileges:
KP: Oops: Fatal exception: comm:wacom_27qhdt
Reboot reason: 0xbaba - Kernel PANIC
Reproducer (unprivileged):
open("/dev/uhid", O_RDWR)
write(fd, UHID_CREATE2{vendor=0x056a, product=0x0020})
write(fd, UHID_INPUT2{report_id=0x0c, size=10})
Fixes: c7f0522a1ad1 ("HID: wacom: Slim down wacom_intuos_pad processing")
Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
---
drivers/hid/wacom_wac.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index da1f0ea85..251ddda3e 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -515,7 +515,6 @@ static int wacom_intuos_pad(struct wacom_wac *wacom)
struct wacom_features *features = &wacom->features;
unsigned char *data = wacom->data;
struct input_dev *input = wacom->pad_input;
- int i;
int buttons = 0, nbuttons = features->numbered_buttons;
int keys = 0, nkeys = 0;
int ring1 = 0, ring2 = 0;
@@ -523,6 +522,10 @@ static int wacom_intuos_pad(struct wacom_wac *wacom)
bool prox = false;
bool wrench = false, keyboard = false, mute_touch = false, menu = false,
info = false;
+ int i;
+
+ if (!input)
+ return 0;
/* pad packets. Works as a second tool and is always in prox */
if (!(data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD ||
--
2.53.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v2] HID: wacom: fix NULL pointer dereference in wacom_intuos_pad()
2026-05-23 15:01 [PATCH] HID: wacom: fix NULL pointer dereference in wacom_intuos_pad() Jinmo Yang
@ 2026-05-23 15:06 ` Jinmo Yang
2026-05-23 15:50 ` sashiko-bot
2026-05-29 21:44 ` Dmitry Torokhov
2026-05-23 15:45 ` [PATCH] HID: wacom: fix NULL pointer dereference in wacom_intuos_pad() sashiko-bot
1 sibling, 2 replies; 36+ messages in thread
From: Jinmo Yang @ 2026-05-23 15:06 UTC (permalink / raw)
To: Ping Cheng, Jason Gerecke, Jiri Kosina, Benjamin Tissoires
Cc: linux-input, linux-kernel, Jinmo Yang
wacom_intuos_pad() dereferences wacom->pad_input without a NULL check.
When a Wacom tablet is created via UHID with parameters that route
through wacom_bpt_irq() -> wacom_intuos_irq() -> wacom_intuos_pad(),
but probe did not allocate pad_input, the call to
wacom_report_numbered_buttons() passes a NULL input_dev, causing a
general protection fault in input_get_drvdata().
Add a NULL check for pad_input at the top of wacom_intuos_pad() to
bail out early when the pad input device was not set up.
The bug was found by syzkaller on linux-next 7.1.0-rc4 (next-20260522):
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000052
KASAN: null-ptr-deref in range [0x0000000000000290-0x0000000000000297]
RIP: 0010:input_get_drvdata include/linux/input.h:390 [inline]
RIP: 0010:wacom_report_numbered_buttons+0x37/0x210 drivers/hid/wacom_wac.c:4210
Call Trace:
wacom_intuos_pad drivers/hid/wacom_wac.c:643 [inline]
wacom_intuos_irq+0x29a/0x32b0 drivers/hid/wacom_wac.c:1042
wacom_bpt_irq drivers/hid/wacom_wac.c:3275 [inline]
wacom_wac_irq+0x12ed/0xaef0 drivers/hid/wacom_wac.c:3545
wacom_raw_event+0x677/0xa90 drivers/hid/wacom_sys.c:184
__hid_input_report.constprop.0+0x39a/0x4d0 drivers/hid/hid-core.c:2161
uhid_dev_input2 drivers/hid/uhid.c:618 [inline]
uhid_char_write+0xa8a/0xfa0 drivers/hid/uhid.c:776
Also confirmed on a Pixel 9 Pro (Android 16, kernel 6.1.124) where
it causes an immediate kernel panic and reboot via /dev/uhid without
requiring root privileges:
KP: Oops: Fatal exception: comm:wacom_27qhdt
Reboot reason: 0xbaba - Kernel PANIC
Reproducer (unprivileged):
open("/dev/uhid", O_RDWR)
write(fd, UHID_CREATE2{vendor=0x056a, product=0x0020})
write(fd, UHID_INPUT2{report_id=0x0c, size=10})
Fixes: c7f0522a1ad1 ("HID: wacom: Slim down wacom_intuos_pad processing")
Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
---
drivers/hid/wacom_wac.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index da1f0ea85..251ddda3e 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -515,7 +515,6 @@ static int wacom_intuos_pad(struct wacom_wac *wacom)
struct wacom_features *features = &wacom->features;
unsigned char *data = wacom->data;
struct input_dev *input = wacom->pad_input;
- int i;
int buttons = 0, nbuttons = features->numbered_buttons;
int keys = 0, nkeys = 0;
int ring1 = 0, ring2 = 0;
@@ -523,6 +522,10 @@ static int wacom_intuos_pad(struct wacom_wac *wacom)
bool prox = false;
bool wrench = false, keyboard = false, mute_touch = false, menu = false,
info = false;
+ int i;
+
+ if (!input)
+ return 0;
/* pad packets. Works as a second tool and is always in prox */
if (!(data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD ||
--
2.53.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [PATCH] HID: wacom: fix NULL pointer dereference in wacom_intuos_pad()
2026-05-23 15:01 [PATCH] HID: wacom: fix NULL pointer dereference in wacom_intuos_pad() Jinmo Yang
2026-05-23 15:06 ` [PATCH v2] " Jinmo Yang
@ 2026-05-23 15:45 ` sashiko-bot
1 sibling, 0 replies; 36+ messages in thread
From: sashiko-bot @ 2026-05-23 15:45 UTC (permalink / raw)
To: Jinmo Yang; +Cc: linux-input, dmitry.torokhov
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [High] The added early return `if (!input) return 0;` in `wacom_intuos_pad()` fails to consume unhandled pad packets, causing them to fall through and be misinterpreted as pen events.
Pre-existing issues:
- [High] Identical NULL pointer dereference vulnerabilities exist for `pen_input` and `touch_input` in other event handlers.
--
commit f0fe30c63ed06d22404bffeeaa7efc7e1da7f7c0
Author: Jinmo Yang <jinmo44.yang@gmail.com>
HID: wacom: fix NULL pointer dereference in wacom_intuos_pad()
This commit adds a NULL check for pad_input at the top of wacom_intuos_pad()
to bail out early when the pad input device was not set up. This prevents
a general protection fault in input_get_drvdata() when a Wacom tablet is
created via UHID with missing interfaces.
> diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
> index da1f0ea85625d..251ddda3ecb3d 100644
> --- a/drivers/hid/wacom_wac.c
> +++ b/drivers/hid/wacom_wac.c
> @@ -523,6 +522,10 @@ static int wacom_intuos_pad(struct wacom_wac *wacom)
> bool prox = false;
> bool wrench = false, keyboard = false, mute_touch = false, menu = false,
> info = false;
> + int i;
> +
> + if (!input)
> + return 0;
[Severity: High]
Does returning 0 here instead of 1 when input is NULL cause the pad packet
to be treated as unhandled?
If wacom_intuos_irq() receives a 0, it falls through to wacom_intuos_inout().
Since wacom_intuos_inout() does not validate the report ID in data[0],
could a pad packet coincidentally matching proximity masks be incorrectly
processed as a pen event, causing spurious events and state corruption?
Should the !input check be moved after the data[0] check, and return 1
to consume and discard the unhandled packet?
[Severity: High]
This is a pre-existing issue, but are there identical NULL pointer dereference
vulnerabilities for wacom->pen_input and wacom->touch_input?
If an attacker uses /dev/uhid to create a virtual device without PEN or TOUCH
collections, pen_input and touch_input remain NULL.
If packets for these missing interfaces are sent, will handlers like
wacom_bpt_touch(), wacom_bpt_pen(), or wacom_intuos_inout() unconditionally
dereference these NULL pointers during input_event() calls or when reporting
out-of-proximity events?
>
> /* pad packets. Works as a second tool and is always in prox */
> if (!(data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD ||
> data[0] == WACOM_REPORT_CINTIQPAD))
> return 0;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260523150101.611473-1-jinmo44.yang@gmail.com?part=1
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2] HID: wacom: fix NULL pointer dereference in wacom_intuos_pad()
2026-05-23 15:06 ` [PATCH v2] " Jinmo Yang
@ 2026-05-23 15:50 ` sashiko-bot
2026-05-29 21:44 ` Dmitry Torokhov
1 sibling, 0 replies; 36+ messages in thread
From: sashiko-bot @ 2026-05-23 15:50 UTC (permalink / raw)
To: Jinmo Yang; +Cc: linux-input, dmitry.torokhov
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
New issues:
- [High] The patch's early return in `wacom_intuos_pad()` causes valid pad reports to fall through to pen handlers when `pad_input` is NULL.
Pre-existing issues:
- [High] The patch addresses a NULL pointer dereference for `pad_input` but completely misses identical vulnerabilities for `pen_input` and `touch_input`.
- [High] Concurrent execution of `wacom_mode_change_work()` and `wacom_raw_event()` can lead to a Use-After-Free of input devices.
- [High] A dangling pointer in `wacom->shared->touch_input` leads to Use-After-Free when the Touch interface unbinds while the Pad interface remains active.
--
commit e74a772fd06994c14eb8d49710acd3ad8740df1f
Author: Jinmo Yang <jinmo44.yang@gmail.com>
HID: wacom: fix NULL pointer dereference in wacom_intuos_pad()
This commit adds a NULL check for pad_input at the top of
wacom_intuos_pad() to bail out early when the pad input device was not set
up, preventing a general protection fault.
> diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
> index da1f0ea85625d..251ddda3ecb3d 100644
> --- a/drivers/hid/wacom_wac.c
> +++ b/drivers/hid/wacom_wac.c
> @@ -515,7 +515,6 @@ static int wacom_intuos_pad(struct wacom_wac *wacom)
> struct wacom_features *features = &wacom->features;
> unsigned char *data = wacom->data;
> struct input_dev *input = wacom->pad_input;
> - int i;
> int buttons = 0, nbuttons = features->numbered_buttons;
> int keys = 0, nkeys = 0;
> int ring1 = 0, ring2 = 0;
> @@ -523,6 +522,10 @@ static int wacom_intuos_pad(struct wacom_wac *wacom)
> bool prox = false;
> bool wrench = false, keyboard = false, mute_touch = false, menu = false,
> info = false;
> + int i;
> +
> + if (!input)
> + return 0;
[Severity: High]
Does returning 0 here allow the event to fall through to other handlers?
wacom_intuos_irq() relies on a non-zero return to halt processing. If this
returns 0, a crafted pad packet might fall through to wacom_intuos_inout().
Since wacom_intuos_inout() only checks data[1] and not the report ID, it
could misinterpret a pad report as a pen proximity event. For example, if
data[1] == 0x80, could it trigger wacom_exit_report() and either inject a
spurious pen exit event or cause a NULL pointer dereference if pen_input
is also NULL?
Would it be better to place this check after verifying the report ID, and
return 1 to securely drop the packet?
[Severity: High]
This isn't a bug introduced by this patch, but does the same NULL pointer
vulnerability exist for pen_input and touch_input?
A crafted UHID descriptor can omit pen and touch capabilities, leaving
wacom->pen_input and wacom->touch_input as NULL.
If valid pen or touch packets are subsequently received, handlers like
wacom_exit_report(), wacom_intuos_general(), and wacom_bpt3_touch_msg()
appear to blindly dereference these NULL pointers.
[Severity: High]
This is a pre-existing issue, but can concurrent execution of
wacom_mode_change_work() and wacom_raw_event() lead to a use-after-free
of the input devices?
wacom_mode_change_work() frees input devices asynchronously via
wacom_release_resources() and devres_release_group(), without holding the
lock that serializes input report processing.
Concurrently, a raw input report could enter wacom_intuos_pad(), read the
wacom->pad_input pointer, successfully pass this new if (!input) check,
and then access the input device right after it gets freed.
>
> /* pad packets. Works as a second tool and is always in prox */
> if (!(data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD ||
[Severity: High]
This is a pre-existing issue, but can wacom->shared->touch_input become a
dangling pointer if the touch interface unbinds while the pad interface
remains active?
When a touch interface is unbound, its input devices are freed via
devres_release_group(), but wacom_remove_shared_data() does not appear to
set wacom->shared->touch_input to NULL.
If a pad event is received later, the pad event handler invokes
input_report_switch() and input_sync() on the dangling pointer:
if (wacom->shared && wacom->shared->touch_input) {
input_report_switch(wacom->shared->touch_input,
SW_MUTE_DEVICE,
!wacom->shared->is_touch_on);
input_sync(wacom->shared->touch_input);
}
Could this result in a use-after-free?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260523150619.615565-1-jinmo44.yang@gmail.com?part=1
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2] HID: wacom: fix NULL pointer dereference in wacom_intuos_pad()
2026-05-23 15:06 ` [PATCH v2] " Jinmo Yang
2026-05-23 15:50 ` sashiko-bot
@ 2026-05-29 21:44 ` Dmitry Torokhov
2026-06-10 15:48 ` Jiri Kosina
1 sibling, 1 reply; 36+ messages in thread
From: Dmitry Torokhov @ 2026-05-29 21:44 UTC (permalink / raw)
To: Jinmo Yang
Cc: Ping Cheng, Jason Gerecke, Jiri Kosina, Benjamin Tissoires,
linux-input, linux-kernel
On Sun, May 24, 2026 at 12:06:19AM +0900, Jinmo Yang wrote:
> wacom_intuos_pad() dereferences wacom->pad_input without a NULL check.
> When a Wacom tablet is created via UHID with parameters that route
> through wacom_bpt_irq() -> wacom_intuos_irq() -> wacom_intuos_pad(),
> but probe did not allocate pad_input, the call to
> wacom_report_numbered_buttons() passes a NULL input_dev, causing a
> general protection fault in input_get_drvdata().
>
> Add a NULL check for pad_input at the top of wacom_intuos_pad() to
> bail out early when the pad input device was not set up.
>
> The bug was found by syzkaller on linux-next 7.1.0-rc4 (next-20260522):
>
> Oops: general protection fault, probably for non-canonical address 0xdffffc0000000052
> KASAN: null-ptr-deref in range [0x0000000000000290-0x0000000000000297]
> RIP: 0010:input_get_drvdata include/linux/input.h:390 [inline]
> RIP: 0010:wacom_report_numbered_buttons+0x37/0x210 drivers/hid/wacom_wac.c:4210
> Call Trace:
> wacom_intuos_pad drivers/hid/wacom_wac.c:643 [inline]
> wacom_intuos_irq+0x29a/0x32b0 drivers/hid/wacom_wac.c:1042
> wacom_bpt_irq drivers/hid/wacom_wac.c:3275 [inline]
> wacom_wac_irq+0x12ed/0xaef0 drivers/hid/wacom_wac.c:3545
> wacom_raw_event+0x677/0xa90 drivers/hid/wacom_sys.c:184
> __hid_input_report.constprop.0+0x39a/0x4d0 drivers/hid/hid-core.c:2161
> uhid_dev_input2 drivers/hid/uhid.c:618 [inline]
> uhid_char_write+0xa8a/0xfa0 drivers/hid/uhid.c:776
>
> Also confirmed on a Pixel 9 Pro (Android 16, kernel 6.1.124) where
> it causes an immediate kernel panic and reboot via /dev/uhid without
> requiring root privileges:
>
> KP: Oops: Fatal exception: comm:wacom_27qhdt
> Reboot reason: 0xbaba - Kernel PANIC
>
> Reproducer (unprivileged):
> open("/dev/uhid", O_RDWR)
> write(fd, UHID_CREATE2{vendor=0x056a, product=0x0020})
> write(fd, UHID_INPUT2{report_id=0x0c, size=10})
>
> Fixes: c7f0522a1ad1 ("HID: wacom: Slim down wacom_intuos_pad processing")
> Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
> ---
> drivers/hid/wacom_wac.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
> index da1f0ea85..251ddda3e 100644
> --- a/drivers/hid/wacom_wac.c
> +++ b/drivers/hid/wacom_wac.c
> @@ -515,7 +515,6 @@ static int wacom_intuos_pad(struct wacom_wac *wacom)
> struct wacom_features *features = &wacom->features;
> unsigned char *data = wacom->data;
> struct input_dev *input = wacom->pad_input;
> - int i;
> int buttons = 0, nbuttons = features->numbered_buttons;
> int keys = 0, nkeys = 0;
> int ring1 = 0, ring2 = 0;
> @@ -523,6 +522,10 @@ static int wacom_intuos_pad(struct wacom_wac *wacom)
> bool prox = false;
> bool wrench = false, keyboard = false, mute_touch = false, menu = false,
> info = false;
> + int i;
> +
> + if (!input)
> + return 0;
>
> /* pad packets. Works as a second tool and is always in prox */
> if (!(data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD ||
I think there are many more places in the driver where it used
wacom->pad_input without verifying that it exists.
Thanks.
--
Dmitry
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2] HID: wacom: fix NULL pointer dereference in wacom_intuos_pad()
2026-05-29 21:44 ` Dmitry Torokhov
@ 2026-06-10 15:48 ` Jiri Kosina
2026-09-26 18:37 ` Jinmo Yang
2026-09-27 4:11 ` [PATCH 0/5] HID: wacom: check input devices in the report handlers Jinmo Yang
0 siblings, 2 replies; 36+ messages in thread
From: Jiri Kosina @ 2026-06-10 15:48 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Jinmo Yang, Ping Cheng, Jason Gerecke, Benjamin Tissoires,
linux-input, linux-kernel
On Fri, 29 May 2026, Dmitry Torokhov wrote:
> I think there are many more places in the driver where it used
> wacom->pad_input without verifying that it exists.
Absolutely correct observation, thanks :)
Jinmo, are you planning to submit extended version of the patch, please?
--
Jiri Kosina
SUSE Labs
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2] HID: wacom: fix NULL pointer dereference in wacom_intuos_pad()
2026-06-10 15:48 ` Jiri Kosina
@ 2026-09-26 18:37 ` Jinmo Yang
2026-09-27 4:11 ` [PATCH 0/5] HID: wacom: check input devices in the report handlers Jinmo Yang
1 sibling, 0 replies; 36+ messages in thread
From: Jinmo Yang @ 2026-09-26 18:37 UTC (permalink / raw)
To: Jiri Kosina, Dmitry Torokhov
Cc: Jinmo Yang, Ping Cheng, Jason Gerecke, Benjamin Tissoires,
linux-input, linux-kernel
On Wed, 10 Jun 2026, Jiri Kosina wrote:
> Jinmo, are you planning to submit extended version of the patch, please?
Yes - sorry for the long delay. Dmitry's observation turned out to be
broader than pad_input, so I audited the whole driver before replying.
The check already exists in three places, just not everywhere:
wacom_wac.c:1807/1815 wacom_tpc_irq pen, touch
wacom_wac.c:1210 wacom_intuos_bt_process_data pad
wacom_wac.c:2192 wacom_wac_pad_event (HID_GENERIC)
so the inconsistency is inside the legacy dispatch. The clearest case is
two adjacent lines in wacom_intuos_bt_process_data(), one checked and
one not:
input_sync(wacom->pen_input); /* :1209 */
if (wacom->pad_input) /* :1210 */
input_sync(wacom->pad_input);
The pointers can be NULL on a fully successful probe: the handler is
chosen by features.type from the id table (wacom_sys.c:2945), while the
input devices are allocated from what the descriptor declares. When
wacom_setup_{pen,touch,pad}_input_capabilities() returns -ENODEV,
wacom_setup_inputs() frees that input, NULLs the pointer and still
returns 0 (wacom_sys.c:2172-2196) - "no pen in use on this interface".
wacom_wac_irq() then still routes reports to a handler that dereferences
it. No error injection is needed; a descriptor declaring only touch
usages is enough.
15 locations, each reproduced as a KASAN NULL-pointer dereference on
linux-next 20260925, x86_64, from one /dev/uhid device plus a single
UHID_INPUT2 write:
wacom_wac.c:137 wacom_penpartner_irq pen_input
wacom_wac.c:227 wacom_pl_irq pen_input
wacom_wac.c:244 wacom_ptu_irq pen_input
wacom_wac.c:303 wacom_dtus_irq pad_input
wacom_wac.c:326 wacom_dtus_irq pen_input
wacom_wac.c:391 wacom_graphire_irq pen_input
wacom_wac.c:444 wacom_graphire_irq pad_input
wacom_wac.c:594 wacom_intuos_pad pad_input
wacom_wac.c:1209 wacom_intuos_bt_process_data pen_input
wacom_wac.c:1232 wacom_intuos_bt_irq pen_input (dev_warn)
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
wacom_wac.c:4229 wacom_report_numbered_buttons pad_input
Jason, your review of my earlier series ("HID: wacom: add report length
validation in irq handlers", 17 May) asked for the length checks to move
into the sub-functions with len passed in, plus WACOM_PKGLEN_* names.
Eight handlers already take len and eight do not, and six of those eight
are also on the list above - so I would like to fold the two together
and do one edit per handler: take len, use a named constant, and check
the input device in the same place.
On the shape of the fix: I plan to put a check where each pointer is
taken, as wacom_tpc_irq() already does. A per-features.type table of
required inputs would be one place instead of ~15, but a handler's needs
vary by report id - wacom_graphire_irq() takes pen_input on one branch
and pad_input on another - so the mask would have to demand every input
the handler might touch, and would then reject reports that work today
on a pen-only interface, which the "no pen in use on this interface"
case says is legitimate. Say the word if you would rather have that
anyway.
I will post it as a series split by device family shortly, with the
shared helpers (wacom_report_numbered_buttons(),
wacom_wac_finger_count_touches()) guarded once each, since several
handlers converge on them.
Thanks,
Jinmo
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 0/5] HID: wacom: check input devices in the report handlers
2026-06-10 15:48 ` Jiri Kosina
2026-09-26 18:37 ` Jinmo Yang
@ 2026-09-27 4:11 ` Jinmo Yang
2026-09-27 4:11 ` [PATCH 1/5] HID: wacom: check the input device in the shared report helpers Jinmo Yang
` (8 more replies)
1 sibling, 9 replies; 36+ messages in thread
From: Jinmo Yang @ 2026-09-27 4:11 UTC (permalink / raw)
To: ping.cheng, jason.gerecke, jikos, bentiss
Cc: dmitry.torokhov, linux-input, linux-kernel, Jinmo Yang
This is the extended version Jiri asked for in
<579o8so3-09o3-o312-4sq0-0qp6n672q46p@xreary.bet>, after Dmitry's
observation that "there are many more places in the driver where it used
wacom->pad_input without verifying that it exists".
The audit turned out broader than pad_input. Of the 155 lines in
wacom_wac.c that reference pen_input, touch_input or pad_input, three
places already test the pointer first:
wacom_wac.c:1807/1815 wacom_tpc_irq pen, touch
wacom_wac.c:1210 wacom_intuos_bt_process_data pad
wacom_wac.c:2192 wacom_wac_pad_event (HID_GENERIC)
so the inconsistency is inside the legacy dispatch rather than between it
and the HID_GENERIC path. The clearest illustration is two adjacent lines
in wacom_intuos_bt_process_data(), one checked and one not:
input_sync(wacom->pen_input); /* :1209 */
if (wacom->pad_input) /* :1210 */
input_sync(wacom->pad_input);
Why the pointers can be NULL on a *successful* probe
====================================================
For a non-HID_GENERIC device the report handler is selected by
features.type, which comes from the id table (wacom_sys.c:2945), while the
three input devices are allocated from what the report descriptor declares.
When wacom_setup_{pen,touch,pad}_input_capabilities() returns -ENODEV,
wacom_setup_inputs() frees that input device, sets the pointer to NULL and
still returns 0 (wacom_sys.c:2172-2196) - the "no pen in use on this
interface" case. wacom_wac_irq() then still routes reports to a handler
that dereferences it.
No error injection is needed. A descriptor declaring only touch usages
leaves pen_input and pad_input NULL; one declaring only pen usages leaves
touch_input and pad_input NULL.
What the series fixes
=====================
15 locations, each reproduced as a KASAN NULL-pointer dereference from one
/dev/uhid device plus a single UHID_INPUT2 write, with no privilege beyond
access to /dev/uhid:
patch file:line function pointer
1 wacom_wac.c:4229 wacom_report_numbered_buttons pad
2 wacom_wac.c:137 wacom_penpartner_irq pen
2 wacom_wac.c:227 wacom_pl_irq pen
2 wacom_wac.c:244 wacom_ptu_irq pen
2 wacom_wac.c:303 wacom_dtus_irq pad
2 wacom_wac.c:326 wacom_dtus_irq pen
2 wacom_wac.c:391 wacom_graphire_irq pen
2 wacom_wac.c:444 wacom_graphire_irq pad
3 wacom_wac.c:594 wacom_intuos_pad pad
4 wacom_wac.c:1209 wacom_intuos_bt_process_data pen
4 wacom_wac.c:1232 wacom_intuos_bt_irq pen
(both covered by one check at wacom_intuos_bt_irq() entry)
5 wacom_wac.c:3100 wacom_bpt_touch touch
5 wacom_wac.c:3117 wacom_bpt_touch pad
5 wacom_wac.c:3130 wacom_bpt3_touch_msg touch
5 wacom_wac.c:3178 wacom_bpt3_button_msg pad
Patch 1 also guards wacom_wac_finger_count_touches(), and patch 2 also
guards wacom_dtu_irq(); both are reachable with a NULL pointer but their
only dereference is in a dev_dbg(), so they do not fault with
CONFIG_DYNAMIC_DEBUG=n.
Dereferences that are reached only through dev_dbg() are otherwise out of
scope here. A few remain, on unknown-report paths in wacom_dtus_irq(),
wacom_graphire_irq() and wacom_intuos_irq(); guarding those needs a
separate look at what a pen-only or pad-only interface should still
report, so I have left them for a follow-up rather than mixing them in.
Approach
========
A check where each pointer is taken, which is what wacom_tpc_irq() already
does. Where a handler serves both pen and pad reports - wacom_dtus_irq(),
wacom_graphire_irq(), wacom_bpt_touch() - the checks are per branch rather
than at function entry, so an interface that has a pad but no pen keeps
delivering pad events.
A per-features.type table of required input devices would be one place
instead of 15, but a handler's needs vary by report id, so such a mask
would have to demand every input the handler might touch and would then
reject reports that work today on a partial interface. I am happy to build
that instead if you would rather have it.
Testing
=======
linux-next 20260925 (7.3.0-rc4-next-20260925-gf5f84daefcd9), x86_64,
CONFIG_KASAN_GENERIC=y, CONFIG_DYNAMIC_DEBUG=n. 27 uhid reproducer cases
covering the sites above plus the dev_dbg-only ones, one fresh VM per case
because the oops leaves driver_input_lock held:
before after
KASAN faults 17 0
probe failures 0 0
hidraw nodes created 26 26
input devices registered 25 25
and the set of input devices registered is identical in all 27 cases, so
the checks remove the faults without changing what a device exposes. The
one case that creates no device is a product whose table entry sets
.check_for_hid_type, which uhid cannot satisfy; it behaves the same before
and after.
Each patch builds standalone with no new warnings, and checkpatch --strict
reports 0 errors, 0 warnings and 0 checks for all five.
Not in this series
==================
Jason, your review of "HID: wacom: add report length validation in irq
handlers" (17 May) asked for the length checks to move into the
sub-functions with len passed in, plus WACOM_PKGLEN_* names. Eight
handlers already take len and eight do not, and six of those eight are
also on the list above, so that work overlaps this series closely. I have
kept it out here because I have only reproduced and verified the
input-device faults; I would rather send the length revision once it has
the same evidence behind it, on top of this series.
Jinmo Yang (5):
HID: wacom: check the input device in the shared report helpers
HID: wacom: check the input devices in the legacy irq handlers
HID: wacom: check the input device in wacom_intuos_pad()
HID: wacom: check the input device in wacom_intuos_bt_irq()
HID: wacom: check the input devices in the Bamboo handlers
drivers/hid/wacom_wac.c | 97 +++++++++++++++++++++++++++++------------
1 file changed, 70 insertions(+), 27 deletions(-)
base-commit: f5f84daefcd92d7a630066635ecea1433ed5eac7
--
2.53.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 1/5] HID: wacom: check the input device in the shared report helpers
2026-09-27 4:11 ` [PATCH 0/5] HID: wacom: check input devices in the report handlers Jinmo Yang
@ 2026-09-27 4:11 ` Jinmo Yang
2026-10-17 0:05 ` Jason Gerecke
2026-09-27 4:11 ` [PATCH 2/5] HID: wacom: check the input devices in the legacy irq handlers Jinmo Yang
` (7 subsequent siblings)
8 siblings, 1 reply; 36+ messages in thread
From: Jinmo Yang @ 2026-09-27 4:11 UTC (permalink / raw)
To: ping.cheng, jason.gerecke, jikos, bentiss
Cc: dmitry.torokhov, linux-input, linux-kernel, Jinmo Yang, stable
wacom_report_numbered_buttons() and wacom_wac_finger_count_touches() are
reached from several report handlers and use the input device they are
given without checking it.
Both can see a NULL input device on a fully successful probe. The report
handler is selected by features.type from the id table, while the three
input devices are allocated from what the report descriptor declares.
When wacom_setup_{pen,touch,pad}_input_capabilities() returns -ENODEV,
wacom_setup_inputs() frees that input device, sets the pointer to NULL
and still returns 0 - the "no pen in use on this interface" case.
wacom_wac_irq() then still routes reports to a handler that passes the
NULL pointer down.
Reproduced on linux-next 20260925 (x86_64, KASAN) from one /dev/uhid
device plus a single UHID_INPUT2 write:
BUG: KASAN: null-ptr-deref in range [0x290-0x297]
RIP: 0010:wacom_report_numbered_buttons+0x37/0x210
wacom_intuos_irq+0x29e/0x3300
wacom_wac_irq+0x1b59/0xb3f0
wacom_raw_event+0x68f/0xb60
__hid_input_report+0x398/0x4d0
uhid_char_write+0xa99/0xfc0
Check the pointer in both helpers, following the convention the driver
already uses in wacom_tpc_irq() and wacom_wac_pad_event().
Fixes: 10059cdc0ad0 ("Input: wacom - split out the pad device for Intuos/Cintiq")
Fixes: 2a6cdbdd4cc0 ("HID: wacom: Introduce new 'touch_input' device")
Cc: stable@vger.kernel.org
Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
---
drivers/hid/wacom_wac.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index c4cd87b781c4..177a1e09fd05 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -1263,6 +1263,9 @@ static int wacom_wac_finger_count_touches(struct wacom_wac *wacom)
int count = 0;
int i;
+ if (!input)
+ return 0;
+
if (!touch_max)
return 0;
@@ -4226,9 +4229,14 @@ static void wacom_update_led(struct wacom *wacom, int button_count, int mask,
static void wacom_report_numbered_buttons(struct input_dev *input_dev,
int button_count, int mask)
{
- struct wacom *wacom = input_get_drvdata(input_dev);
+ struct wacom *wacom;
int i;
+ if (!input_dev)
+ return;
+
+ wacom = input_get_drvdata(input_dev);
+
for (i = 0; i < wacom->led.count; i++)
wacom_update_led(wacom, button_count, mask, i);
--
2.53.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 2/5] HID: wacom: check the input devices in the legacy irq handlers
2026-09-27 4:11 ` [PATCH 0/5] HID: wacom: check input devices in the report handlers Jinmo Yang
2026-09-27 4:11 ` [PATCH 1/5] HID: wacom: check the input device in the shared report helpers Jinmo Yang
@ 2026-09-27 4:11 ` Jinmo Yang
2026-10-17 0:05 ` Jason Gerecke
2026-09-27 4:11 ` [PATCH 3/5] HID: wacom: check the input device in wacom_intuos_pad() Jinmo Yang
` (6 subsequent siblings)
8 siblings, 1 reply; 36+ messages in thread
From: Jinmo Yang @ 2026-09-27 4:11 UTC (permalink / raw)
To: ping.cheng, jason.gerecke, jikos, bentiss
Cc: dmitry.torokhov, linux-input, linux-kernel, Jinmo Yang, stable
wacom_penpartner_irq(), wacom_pl_irq(), wacom_ptu_irq(),
wacom_dtu_irq(), wacom_dtus_irq() and wacom_graphire_irq() take
pen_input, and the latter two also take pad_input, without checking
either.
As described in "HID: wacom: check the input device in the shared
report helpers", a partial interface leaves one or two of the three
input devices NULL on a fully successful probe, and wacom_wac_irq()
still dispatches to these handlers. Seven 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:137 wacom_penpartner_irq pen_input
wacom_wac.c:227 wacom_pl_irq pen_input
wacom_wac.c:244 wacom_ptu_irq pen_input
wacom_wac.c:303 wacom_dtus_irq pad_input
wacom_wac.c:326 wacom_dtus_irq pen_input
wacom_wac.c:391 wacom_graphire_irq pen_input
wacom_wac.c:444 wacom_graphire_irq pad_input
for example, with vendor 0x056a product 0x0030 (PL) and report id 2:
BUG: KASAN: null-ptr-deref in input_event+0x44/0xb0
Read of size 8 at addr 0000000000000028
wacom_wac_irq+0x2b27/0xb3f0
wacom_raw_event+0x68f/0xb60
__hid_input_report+0x398/0x4d0
uhid_char_write+0xa99/0xfc0
Check each pointer where it is taken. wacom_dtus_irq() and
wacom_graphire_irq() serve both pen and pad reports, so the checks are
placed per branch rather than at function entry: an interface that has
a pad but no pen must keep delivering pad events.
wacom_dtu_irq() gets a check too. Its only dereference is in a
dev_dbg(), so it does not fault with CONFIG_DYNAMIC_DEBUG=n, but it is
unconditional in the source.
Fixes: 2a6cdbdd4cc0 ("HID: wacom: Introduce new 'touch_input' device")
Fixes: 862cf5535c0c ("HID: wacom: Introduce a new WACOM_DEVICETYPE_PAD device_type")
Cc: stable@vger.kernel.org
Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
---
drivers/hid/wacom_wac.c | 25 +++++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index 177a1e09fd05..794c2865064a 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -128,6 +128,9 @@ static int wacom_penpartner_irq(struct wacom_wac *wacom)
unsigned char *data = wacom->data;
struct input_dev *input = wacom->pen_input;
+ if (!input)
+ return 0;
+
switch (data[0]) {
case 1:
if (data[5] & 0x80) {
@@ -174,6 +177,9 @@ static int wacom_pl_irq(struct wacom_wac *wacom)
struct input_dev *input = wacom->pen_input;
int prox, pressure;
+ if (!input)
+ return 0;
+
if (data[0] != WACOM_REPORT_PENABLED) {
dev_dbg(input->dev.parent,
"%s: received unknown report #%d\n", __func__, data[0]);
@@ -233,6 +239,9 @@ static int wacom_ptu_irq(struct wacom_wac *wacom)
unsigned char *data = wacom->data;
struct input_dev *input = wacom->pen_input;
+ if (!input)
+ return 0;
+
if (data[0] != WACOM_REPORT_PENABLED) {
dev_dbg(input->dev.parent,
"%s: received unknown report #%d\n", __func__, data[0]);
@@ -263,6 +272,9 @@ static int wacom_dtu_irq(struct wacom_wac *wacom)
struct input_dev *input = wacom->pen_input;
int prox = data[1] & 0x20;
+ if (!input)
+ return 0;
+
dev_dbg(input->dev.parent,
"%s: received report #%d", __func__, data[0]);
@@ -299,6 +311,8 @@ static int wacom_dtus_irq(struct wacom_wac *wacom)
return 0;
} else if (data[0] == WACOM_REPORT_DTUSPAD) {
input = wacom->pad_input;
+ if (!input)
+ return 0;
input_report_key(input, BTN_0, (data[1] & 0x01));
input_report_key(input, BTN_1, (data[1] & 0x02));
input_report_key(input, BTN_2, (data[1] & 0x04));
@@ -307,6 +321,9 @@ static int wacom_dtus_irq(struct wacom_wac *wacom)
data[1] & 0x0f ? PAD_DEVICE_ID : 0);
return 1;
} else {
+ if (!input)
+ return 0;
+
prox = data[1] & 0x80;
if (prox) {
switch ((data[1] >> 3) & 3) {
@@ -363,7 +380,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom)
}
prox = data[1] & 0x80;
- if (prox || wacom->id[0]) {
+ if (input && (prox || wacom->id[0])) {
if (prox) {
switch ((data[1] >> 5) & 3) {
@@ -438,7 +455,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom)
switch (features->type) {
case WACOM_G4:
prox = data[7] & 0xf8;
- if (prox || wacom->id[1]) {
+ if (pad_input && (prox || wacom->id[1])) {
wacom->id[1] = PAD_DEVICE_ID;
input_report_key(pad_input, BTN_BACK, (data[7] & 0x40));
input_report_key(pad_input, BTN_FORWARD, (data[7] & 0x80));
@@ -453,7 +470,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom)
case WACOM_MO:
prox = (data[7] & 0xf8) || data[8];
- if (prox || wacom->id[1]) {
+ if (pad_input && (prox || wacom->id[1])) {
wacom->id[1] = PAD_DEVICE_ID;
input_report_key(pad_input, BTN_BACK, (data[7] & 0x08));
input_report_key(pad_input, BTN_LEFT, (data[7] & 0x20));
@@ -468,7 +485,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom)
break;
case GRAPHIRE_BT:
prox = data[7] & 0x03;
- if (prox || wacom->id[1]) {
+ if (pad_input && (prox || wacom->id[1])) {
wacom->id[1] = PAD_DEVICE_ID;
input_report_key(pad_input, BTN_0, (data[7] & 0x02));
input_report_key(pad_input, BTN_1, (data[7] & 0x01));
--
2.53.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 3/5] HID: wacom: check the input device in wacom_intuos_pad()
2026-09-27 4:11 ` [PATCH 0/5] HID: wacom: check input devices in the report handlers Jinmo Yang
2026-09-27 4:11 ` [PATCH 1/5] HID: wacom: check the input device in the shared report helpers Jinmo Yang
2026-09-27 4:11 ` [PATCH 2/5] HID: wacom: check the input devices in the legacy irq handlers Jinmo Yang
@ 2026-09-27 4:11 ` Jinmo Yang
2026-09-27 4:24 ` sashiko-bot
2026-10-17 0:05 ` Jason Gerecke
2026-09-27 4:11 ` [PATCH 4/5] HID: wacom: check the input device in wacom_intuos_bt_irq() Jinmo Yang
` (5 subsequent siblings)
8 siblings, 2 replies; 36+ messages in thread
From: Jinmo Yang @ 2026-09-27 4:11 UTC (permalink / raw)
To: ping.cheng, jason.gerecke, jikos, bentiss
Cc: dmitry.torokhov, linux-input, linux-kernel, Jinmo Yang, stable
wacom_intuos_pad() takes wacom->pad_input without checking it. An
interface that declares no pad leaves the pointer NULL on a fully
successful probe, and wacom_intuos_irq() still calls this function for
pad report ids.
Reproduced on linux-next 20260925 (x86_64, KASAN) with vendor 0x056a
product 0x032A and report id 12:
BUG: KASAN: null-ptr-deref in input_event+0x44/0xb0
Read of size 8 at addr 0000000000000028
wacom_intuos_irq+0x1b46/0x3300
wacom_wac_irq+0x1b59/0xb3f0
wacom_raw_event+0x68f/0xb60
__hid_input_report+0x398/0x4d0
uhid_char_write+0xa99/0xfc0
The function only ever serves pad reports, so the check goes at entry.
Fixes: 10059cdc0ad0 ("Input: wacom - split out the pad device for Intuos/Cintiq")
Cc: stable@vger.kernel.org
Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
---
drivers/hid/wacom_wac.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index 794c2865064a..48a58a6672c2 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -553,6 +553,9 @@ static int wacom_intuos_pad(struct wacom_wac *wacom)
bool wrench = false, keyboard = false, mute_touch = false, menu = false,
info = false;
+ if (!input)
+ return 0;
+
/* pad packets. Works as a second tool and is always in prox */
if (!(data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD ||
data[0] == WACOM_REPORT_CINTIQPAD))
--
2.53.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 4/5] HID: wacom: check the input device in wacom_intuos_bt_irq()
2026-09-27 4:11 ` [PATCH 0/5] HID: wacom: check input devices in the report handlers Jinmo Yang
` (2 preceding siblings ...)
2026-09-27 4:11 ` [PATCH 3/5] HID: wacom: check the input device in wacom_intuos_pad() Jinmo Yang
@ 2026-09-27 4:11 ` Jinmo Yang
2026-10-17 0:05 ` Jason Gerecke
2026-09-27 4:11 ` [PATCH 5/5] HID: wacom: check the input devices in the Bamboo handlers Jinmo Yang
` (4 subsequent siblings)
8 siblings, 1 reply; 36+ messages in thread
From: Jinmo Yang @ 2026-09-27 4:11 UTC (permalink / raw)
To: ping.cheng, jason.gerecke, jikos, bentiss
Cc: dmitry.torokhov, linux-input, linux-kernel, Jinmo Yang, stable
wacom_intuos_bt_irq() reaches for wacom->pen_input three ways without
checking it: two dev_warn() calls on the short-report paths, a dev_dbg()
on the unknown-report path, and input_sync(wacom->pen_input) inside
wacom_intuos_bt_process_data(), which is called only from here. That last
one is the odd one out, because the pad_input sync two lines below it is
guarded:
input_sync(wacom->pen_input);
if (wacom->pad_input)
input_sync(wacom->pad_input);
An interface that declares no pen leaves the pointer NULL on a fully
successful probe, as described in "HID: wacom: check the input device in
the shared report helpers".
Reproduced on linux-next 20260925 (x86_64, KASAN) with bus BUS_BLUETOOTH,
vendor 0x056a product 0x00BD (INTUOS4WL):
BUG: KASAN: null-ptr-deref in range [0x258-0x25f]
RIP: 0010:wacom_wac_irq.cold+0x8f/0x16a
wacom_raw_event+0x68f/0xb60
__hid_input_report+0x398/0x4d0
uhid_char_write+0xa99/0xfc0
One check at function entry covers all of them. It is safe to bail out
there: this handler only runs for INTUOS4WL, and
wacom_setup_device_quirks() only adds WACOM_DEVICETYPE_PAD for that
range of types when WACOM_DEVICETYPE_PEN is already set, so a NULL
pen_input implies a NULL pad_input and there is nothing the function can
report. Every path that reaches the battery notification passes through
wacom_intuos_bt_process_data() first, so no reachable work is lost.
Fixes: 2a6cdbdd4cc0 ("HID: wacom: Introduce new 'touch_input' device")
Cc: stable@vger.kernel.org
Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
---
drivers/hid/wacom_wac.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index 48a58a6672c2..11544adb74f5 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -1237,6 +1237,9 @@ static int wacom_intuos_bt_irq(struct wacom_wac *wacom, size_t len)
int i = 1;
unsigned power_raw, battery_capacity, bat_charging, ps_connected;
+ if (!wacom->pen_input)
+ return 0;
+
switch (data[0]) {
case 0x04:
if (len < 32) {
--
2.53.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 5/5] HID: wacom: check the input devices in the Bamboo handlers
2026-09-27 4:11 ` [PATCH 0/5] HID: wacom: check input devices in the report handlers Jinmo Yang
` (3 preceding siblings ...)
2026-09-27 4:11 ` [PATCH 4/5] HID: wacom: check the input device in wacom_intuos_bt_irq() Jinmo Yang
@ 2026-09-27 4:11 ` Jinmo Yang
2026-10-17 0:05 ` Jason Gerecke
2026-10-16 9:27 ` [PATCH 0/5] HID: wacom: check input devices in the report handlers Jiri Kosina
` (3 subsequent siblings)
8 siblings, 1 reply; 36+ messages in thread
From: Jinmo Yang @ 2026-09-27 4:11 UTC (permalink / raw)
To: ping.cheng, jason.gerecke, jikos, bentiss
Cc: dmitry.torokhov, linux-input, linux-kernel, Jinmo Yang, stable
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.
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@vger.kernel.org
Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
---
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;
+
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
^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [PATCH 3/5] HID: wacom: check the input device in wacom_intuos_pad()
2026-09-27 4:11 ` [PATCH 3/5] HID: wacom: check the input device in wacom_intuos_pad() Jinmo Yang
@ 2026-09-27 4:24 ` sashiko-bot
2026-10-17 0:05 ` Jason Gerecke
1 sibling, 0 replies; 36+ messages in thread
From: sashiko-bot @ 2026-09-27 4:24 UTC (permalink / raw)
To: Jinmo Yang; +Cc: dmitry.torokhov, linux-input
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] HID: wacom: unintended fall-through for pad packets causes data corruption or crash
--
commit b724787c53f0eff408a5ebd5d5a4bed152ed7f82
Author: Jinmo Yang <jinmo44.yang@gmail.com>
HID: wacom: check the input device in wacom_intuos_pad()
wacom_intuos_pad() takes wacom->pad_input without checking it. An
interface that declares no pad leaves the pointer NULL on a fully
successful probe, and wacom_intuos_irq() still calls this function for
pad report ids.
[ ... ]
Fixes: 10059cdc0ad0 ("Input: wacom - split out the pad device for Intuos/Cintiq")
Cc: stable@vger.kernel.org
Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
> diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
> index 794c2865064aa..48a58a6672c21 100644
> --- a/drivers/hid/wacom_wac.c
> +++ b/drivers/hid/wacom_wac.c
> @@ -553,6 +553,9 @@ static int wacom_intuos_pad(struct wacom_wac *wacom)
> bool wrench = false, keyboard = false, mute_touch = false, menu = false,
> info = false;
>
> + if (!input)
> + return 0;
> +
[Severity: High]
Does returning 0 here for a pad packet cause it to fall through and be misparsed
by other handlers?
In wacom_intuos_irq(), if wacom_intuos_pad() returns 0, the packet falls through
to wacom_intuos_inout():
drivers/hid/wacom_wac.c:wacom_intuos_irq() {
...
/* process pad events */
result = wacom_intuos_pad(wacom);
if (result)
return result;
/* process in/out prox events */
result = wacom_intuos_inout(wacom);
...
}
Because wacom_intuos_inout() only checks data[1] and doesn't verify the report
ID in data[0]:
drivers/hid/wacom_wac.c:wacom_intuos_inout() {
...
if (!(((data[1] & 0xfc) == 0xc0) || /* in prox */
((data[1] & 0xfe) == 0x20) || /* in range */
((data[1] & 0xfe) == 0x80))) /* out prox */
return 0;
...
}
If data[1] of the unhandled pad packet happens to match one of these proximity
bitmasks (like 0x80 for out-prox), wacom_intuos_inout() will misparse the
packet. If it hits the out-prox case, it calls wacom_exit_report() which
dereferences wacom->pen_input. If pen_input is NULL (e.g. on a touch-only
interface), could this cause another NULL pointer dereference?
Should this !input check be placed after validating data[0], and return 1 to
correctly consume the report without falling through?
> /* pad packets. Works as a second tool and is always in prox */
> if (!(data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD ||
> data[0] == WACOM_REPORT_CINTIQPAD))
> return 0;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260927041138.4112920-1-jinmo44.yang@gmail.com?part=3
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 0/5] HID: wacom: check input devices in the report handlers
2026-09-27 4:11 ` [PATCH 0/5] HID: wacom: check input devices in the report handlers Jinmo Yang
` (4 preceding siblings ...)
2026-09-27 4:11 ` [PATCH 5/5] HID: wacom: check the input devices in the Bamboo handlers Jinmo Yang
@ 2026-10-16 9:27 ` Jiri Kosina
2026-10-17 0:05 ` Jason Gerecke
` (2 subsequent siblings)
8 siblings, 0 replies; 36+ messages in thread
From: Jiri Kosina @ 2026-10-16 9:27 UTC (permalink / raw)
To: Jinmo Yang
Cc: ping.cheng, jason.gerecke, bentiss, dmitry.torokhov, linux-input,
linux-kernel
Ping, Jason, can you please Ack/Review this series? Thanks.
On Sun, 27 Sep 2026, Jinmo Yang wrote:
> This is the extended version Jiri asked for in
> <579o8so3-09o3-o312-4sq0-0qp6n672q46p@xreary.bet>, after Dmitry's
> observation that "there are many more places in the driver where it used
> wacom->pad_input without verifying that it exists".
>
> The audit turned out broader than pad_input. Of the 155 lines in
> wacom_wac.c that reference pen_input, touch_input or pad_input, three
> places already test the pointer first:
>
> wacom_wac.c:1807/1815 wacom_tpc_irq pen, touch
> wacom_wac.c:1210 wacom_intuos_bt_process_data pad
> wacom_wac.c:2192 wacom_wac_pad_event (HID_GENERIC)
>
> so the inconsistency is inside the legacy dispatch rather than between it
> and the HID_GENERIC path. The clearest illustration is two adjacent lines
> in wacom_intuos_bt_process_data(), one checked and one not:
>
> input_sync(wacom->pen_input); /* :1209 */
> if (wacom->pad_input) /* :1210 */
> input_sync(wacom->pad_input);
>
> Why the pointers can be NULL on a *successful* probe
> ====================================================
> For a non-HID_GENERIC device the report handler is selected by
> features.type, which comes from the id table (wacom_sys.c:2945), while the
> three input devices are allocated from what the report descriptor declares.
> When wacom_setup_{pen,touch,pad}_input_capabilities() returns -ENODEV,
> wacom_setup_inputs() frees that input device, sets the pointer to NULL and
> still returns 0 (wacom_sys.c:2172-2196) - the "no pen in use on this
> interface" case. wacom_wac_irq() then still routes reports to a handler
> that dereferences it.
>
> No error injection is needed. A descriptor declaring only touch usages
> leaves pen_input and pad_input NULL; one declaring only pen usages leaves
> touch_input and pad_input NULL.
>
> What the series fixes
> =====================
> 15 locations, each reproduced as a KASAN NULL-pointer dereference from one
> /dev/uhid device plus a single UHID_INPUT2 write, with no privilege beyond
> access to /dev/uhid:
>
> patch file:line function pointer
> 1 wacom_wac.c:4229 wacom_report_numbered_buttons pad
> 2 wacom_wac.c:137 wacom_penpartner_irq pen
> 2 wacom_wac.c:227 wacom_pl_irq pen
> 2 wacom_wac.c:244 wacom_ptu_irq pen
> 2 wacom_wac.c:303 wacom_dtus_irq pad
> 2 wacom_wac.c:326 wacom_dtus_irq pen
> 2 wacom_wac.c:391 wacom_graphire_irq pen
> 2 wacom_wac.c:444 wacom_graphire_irq pad
> 3 wacom_wac.c:594 wacom_intuos_pad pad
> 4 wacom_wac.c:1209 wacom_intuos_bt_process_data pen
> 4 wacom_wac.c:1232 wacom_intuos_bt_irq pen
> (both covered by one check at wacom_intuos_bt_irq() entry)
> 5 wacom_wac.c:3100 wacom_bpt_touch touch
> 5 wacom_wac.c:3117 wacom_bpt_touch pad
> 5 wacom_wac.c:3130 wacom_bpt3_touch_msg touch
> 5 wacom_wac.c:3178 wacom_bpt3_button_msg pad
>
> Patch 1 also guards wacom_wac_finger_count_touches(), and patch 2 also
> guards wacom_dtu_irq(); both are reachable with a NULL pointer but their
> only dereference is in a dev_dbg(), so they do not fault with
> CONFIG_DYNAMIC_DEBUG=n.
>
> Dereferences that are reached only through dev_dbg() are otherwise out of
> scope here. A few remain, on unknown-report paths in wacom_dtus_irq(),
> wacom_graphire_irq() and wacom_intuos_irq(); guarding those needs a
> separate look at what a pen-only or pad-only interface should still
> report, so I have left them for a follow-up rather than mixing them in.
>
> Approach
> ========
> A check where each pointer is taken, which is what wacom_tpc_irq() already
> does. Where a handler serves both pen and pad reports - wacom_dtus_irq(),
> wacom_graphire_irq(), wacom_bpt_touch() - the checks are per branch rather
> than at function entry, so an interface that has a pad but no pen keeps
> delivering pad events.
>
> A per-features.type table of required input devices would be one place
> instead of 15, but a handler's needs vary by report id, so such a mask
> would have to demand every input the handler might touch and would then
> reject reports that work today on a partial interface. I am happy to build
> that instead if you would rather have it.
>
> Testing
> =======
> linux-next 20260925 (7.3.0-rc4-next-20260925-gf5f84daefcd9), x86_64,
> CONFIG_KASAN_GENERIC=y, CONFIG_DYNAMIC_DEBUG=n. 27 uhid reproducer cases
> covering the sites above plus the dev_dbg-only ones, one fresh VM per case
> because the oops leaves driver_input_lock held:
>
> before after
> KASAN faults 17 0
> probe failures 0 0
> hidraw nodes created 26 26
> input devices registered 25 25
>
> and the set of input devices registered is identical in all 27 cases, so
> the checks remove the faults without changing what a device exposes. The
> one case that creates no device is a product whose table entry sets
> .check_for_hid_type, which uhid cannot satisfy; it behaves the same before
> and after.
>
> Each patch builds standalone with no new warnings, and checkpatch --strict
> reports 0 errors, 0 warnings and 0 checks for all five.
>
> Not in this series
> ==================
> Jason, your review of "HID: wacom: add report length validation in irq
> handlers" (17 May) asked for the length checks to move into the
> sub-functions with len passed in, plus WACOM_PKGLEN_* names. Eight
> handlers already take len and eight do not, and six of those eight are
> also on the list above, so that work overlaps this series closely. I have
> kept it out here because I have only reproduced and verified the
> input-device faults; I would rather send the length revision once it has
> the same evidence behind it, on top of this series.
>
> Jinmo Yang (5):
> HID: wacom: check the input device in the shared report helpers
> HID: wacom: check the input devices in the legacy irq handlers
> HID: wacom: check the input device in wacom_intuos_pad()
> HID: wacom: check the input device in wacom_intuos_bt_irq()
> HID: wacom: check the input devices in the Bamboo handlers
>
> drivers/hid/wacom_wac.c | 97 +++++++++++++++++++++++++++++------------
> 1 file changed, 70 insertions(+), 27 deletions(-)
>
>
> base-commit: f5f84daefcd92d7a630066635ecea1433ed5eac7
> --
> 2.53.0
>
--
Jiri Kosina
SUSE Labs
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 0/5] HID: wacom: check input devices in the report handlers
2026-09-27 4:11 ` [PATCH 0/5] HID: wacom: check input devices in the report handlers Jinmo Yang
` (5 preceding siblings ...)
2026-10-16 9:27 ` [PATCH 0/5] HID: wacom: check input devices in the report handlers Jiri Kosina
@ 2026-10-17 0:05 ` Jason Gerecke
2026-10-18 10:46 ` [PATCH v2 0/5] HID: wacom: guard against NULL input devices on successful probe Jinmo Yang
2026-10-18 12:47 ` [PATCH v3 0/6] HID: wacom: guard against NULL input devices on successful probe Jinmo Yang
8 siblings, 0 replies; 36+ messages in thread
From: Jason Gerecke @ 2026-10-17 0:05 UTC (permalink / raw)
To: Jinmo Yang
Cc: ping.cheng, jason.gerecke, jikos, bentiss, dmitry.torokhov,
linux-input, linux-kernel
On Sat, Sep 26, 2026 at 9:11 PM Jinmo Yang <jinmo44.yang@gmail.com> wrote:
>
> This is the extended version Jiri asked for in
> <579o8so3-09o3-o312-4sq0-0qp6n672q46p@xreary.bet>, after Dmitry's
> observation that "there are many more places in the driver where it used
> wacom->pad_input without verifying that it exists".
>
> The audit turned out broader than pad_input. Of the 155 lines in
> wacom_wac.c that reference pen_input, touch_input or pad_input, three
> places already test the pointer first:
>
> wacom_wac.c:1807/1815 wacom_tpc_irq pen, touch
> wacom_wac.c:1210 wacom_intuos_bt_process_data pad
> wacom_wac.c:2192 wacom_wac_pad_event (HID_GENERIC)
>
> so the inconsistency is inside the legacy dispatch rather than between it
> and the HID_GENERIC path. The clearest illustration is two adjacent lines
> in wacom_intuos_bt_process_data(), one checked and one not:
>
> input_sync(wacom->pen_input); /* :1209 */
> if (wacom->pad_input) /* :1210 */
> input_sync(wacom->pad_input);
>
> Why the pointers can be NULL on a *successful* probe
> ====================================================
> For a non-HID_GENERIC device the report handler is selected by
> features.type, which comes from the id table (wacom_sys.c:2945), while the
> three input devices are allocated from what the report descriptor declares.
> When wacom_setup_{pen,touch,pad}_input_capabilities() returns -ENODEV,
> wacom_setup_inputs() frees that input device, sets the pointer to NULL and
> still returns 0 (wacom_sys.c:2172-2196) - the "no pen in use on this
> interface" case. wacom_wac_irq() then still routes reports to a handler
> that dereferences it.
>
> No error injection is needed. A descriptor declaring only touch usages
> leaves pen_input and pad_input NULL; one declaring only pen usages leaves
> touch_input and pad_input NULL.
>
> What the series fixes
> =====================
> 15 locations, each reproduced as a KASAN NULL-pointer dereference from one
> /dev/uhid device plus a single UHID_INPUT2 write, with no privilege beyond
> access to /dev/uhid:
>
> patch file:line function pointer
> 1 wacom_wac.c:4229 wacom_report_numbered_buttons pad
> 2 wacom_wac.c:137 wacom_penpartner_irq pen
> 2 wacom_wac.c:227 wacom_pl_irq pen
> 2 wacom_wac.c:244 wacom_ptu_irq pen
> 2 wacom_wac.c:303 wacom_dtus_irq pad
> 2 wacom_wac.c:326 wacom_dtus_irq pen
> 2 wacom_wac.c:391 wacom_graphire_irq pen
> 2 wacom_wac.c:444 wacom_graphire_irq pad
> 3 wacom_wac.c:594 wacom_intuos_pad pad
> 4 wacom_wac.c:1209 wacom_intuos_bt_process_data pen
> 4 wacom_wac.c:1232 wacom_intuos_bt_irq pen
> (both covered by one check at wacom_intuos_bt_irq() entry)
> 5 wacom_wac.c:3100 wacom_bpt_touch touch
> 5 wacom_wac.c:3117 wacom_bpt_touch pad
> 5 wacom_wac.c:3130 wacom_bpt3_touch_msg touch
> 5 wacom_wac.c:3178 wacom_bpt3_button_msg pad
>
> Patch 1 also guards wacom_wac_finger_count_touches(), and patch 2 also
> guards wacom_dtu_irq(); both are reachable with a NULL pointer but their
> only dereference is in a dev_dbg(), so they do not fault with
> CONFIG_DYNAMIC_DEBUG=n.
>
> Dereferences that are reached only through dev_dbg() are otherwise out of
> scope here. A few remain, on unknown-report paths in wacom_dtus_irq(),
> wacom_graphire_irq() and wacom_intuos_irq(); guarding those needs a
> separate look at what a pen-only or pad-only interface should still
> report, so I have left them for a follow-up rather than mixing them in.
>
There are a large class of devices in the legacy codepath for which a
pen-only interface is not valid. There are exceptions (e.g. GRAPHIRE
is a pen-only interface), but in many cases (see
wacom_setup_device_quirks) interfaces which have a pen interface will
also have a pad. I'm not aware of *any* Wacom device which has a
pad-only interface (though I could be wrong; I can try to dig up old
spec documents or original commits that would shed light about any
cases where there is doubt).
> Approach
> ========
> A check where each pointer is taken, which is what wacom_tpc_irq() already
> does. Where a handler serves both pen and pad reports - wacom_dtus_irq(),
> wacom_graphire_irq(), wacom_bpt_touch() - the checks are per branch rather
> than at function entry, so an interface that has a pad but no pen keeps
> delivering pad events.
>
> A per-features.type table of required input devices would be one place
> instead of 15, but a handler's needs vary by report id, so such a mask
> would have to demand every input the handler might touch and would then
> reject reports that work today on a partial interface. I am happy to build
> that instead if you would rather have it.
>
> Testing
> =======
> linux-next 20260925 (7.3.0-rc4-next-20260925-gf5f84daefcd9), x86_64,
> CONFIG_KASAN_GENERIC=y, CONFIG_DYNAMIC_DEBUG=n. 27 uhid reproducer cases
> covering the sites above plus the dev_dbg-only ones, one fresh VM per case
> because the oops leaves driver_input_lock held:
>
> before after
> KASAN faults 17 0
> probe failures 0 0
> hidraw nodes created 26 26
> input devices registered 25 25
>
> and the set of input devices registered is identical in all 27 cases, so
> the checks remove the faults without changing what a device exposes. The
> one case that creates no device is a product whose table entry sets
> .check_for_hid_type, which uhid cannot satisfy; it behaves the same before
> and after.
>
> Each patch builds standalone with no new warnings, and checkpatch --strict
> reports 0 errors, 0 warnings and 0 checks for all five.
>
> Not in this series
> ==================
> Jason, your review of "HID: wacom: add report length validation in irq
> handlers" (17 May) asked for the length checks to move into the
> sub-functions with len passed in, plus WACOM_PKGLEN_* names. Eight
> handlers already take len and eight do not, and six of those eight are
> also on the list above, so that work overlaps this series closely. I have
> kept it out here because I have only reproduced and verified the
> input-device faults; I would rather send the length revision once it has
> the same evidence behind it, on top of this series.
This is understandable. I will note, however, that while evidence of
misbehavior is appreciated, it is not required. Consistently
performing various precondition checks across similar functions, even
if they are not *strictly* necessary at this time, can still encourage
good habits for future code.
>
> Jinmo Yang (5):
> HID: wacom: check the input device in the shared report helpers
> HID: wacom: check the input devices in the legacy irq handlers
> HID: wacom: check the input device in wacom_intuos_pad()
> HID: wacom: check the input device in wacom_intuos_bt_irq()
> HID: wacom: check the input devices in the Bamboo handlers
>
I do somewhat question the decision to split this series into five
pieces. I feel that most could be combined, especially after I have
checked that the few per-branch checks in this series can be
simplified to per-function checks. Combining the patches is not a hard
request, however.
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....
> drivers/hid/wacom_wac.c | 97 +++++++++++++++++++++++++++++------------
> 1 file changed, 70 insertions(+), 27 deletions(-)
>
>
> base-commit: f5f84daefcd92d7a630066635ecea1433ed5eac7
> --
> 2.53.0
>
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 1/5] HID: wacom: check the input device in the shared report helpers
2026-09-27 4:11 ` [PATCH 1/5] HID: wacom: check the input device in the shared report helpers Jinmo Yang
@ 2026-10-17 0:05 ` Jason Gerecke
0 siblings, 0 replies; 36+ messages in thread
From: Jason Gerecke @ 2026-10-17 0:05 UTC (permalink / raw)
To: Jinmo Yang
Cc: ping.cheng, jason.gerecke, jikos, bentiss, dmitry.torokhov,
linux-input, linux-kernel, stable
On Sat, Sep 26, 2026 at 9:12 PM Jinmo Yang <jinmo44.yang@gmail.com> wrote:
>
> wacom_report_numbered_buttons() and wacom_wac_finger_count_touches() are
> reached from several report handlers and use the input device they are
> given without checking it.
>
> Both can see a NULL input device on a fully successful probe. The report
> handler is selected by features.type from the id table, while the three
> input devices are allocated from what the report descriptor declares.
> When wacom_setup_{pen,touch,pad}_input_capabilities() returns -ENODEV,
> wacom_setup_inputs() frees that input device, sets the pointer to NULL
> and still returns 0 - the "no pen in use on this interface" case.
> wacom_wac_irq() then still routes reports to a handler that passes the
> NULL pointer down.
>
> Reproduced on linux-next 20260925 (x86_64, KASAN) from one /dev/uhid
> device plus a single UHID_INPUT2 write:
>
> BUG: KASAN: null-ptr-deref in range [0x290-0x297]
> RIP: 0010:wacom_report_numbered_buttons+0x37/0x210
> wacom_intuos_irq+0x29e/0x3300
> wacom_wac_irq+0x1b59/0xb3f0
> wacom_raw_event+0x68f/0xb60
> __hid_input_report+0x398/0x4d0
> uhid_char_write+0xa99/0xfc0
>
> Check the pointer in both helpers, following the convention the driver
> already uses in wacom_tpc_irq() and wacom_wac_pad_event().
>
> Fixes: 10059cdc0ad0 ("Input: wacom - split out the pad device for Intuos/Cintiq")
> Fixes: 2a6cdbdd4cc0 ("HID: wacom: Introduce new 'touch_input' device")
> Cc: stable@vger.kernel.org
> Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
> ---
> drivers/hid/wacom_wac.c | 10 +++++++++-
> 1 file changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
> index c4cd87b781c4..177a1e09fd05 100644
> --- a/drivers/hid/wacom_wac.c
> +++ b/drivers/hid/wacom_wac.c
> @@ -1263,6 +1263,9 @@ static int wacom_wac_finger_count_touches(struct wacom_wac *wacom)
> int count = 0;
> int i;
>
> + if (!input)
> + return 0;
> +
Checks like this are for an unusual error condition so a dev_warn_once
or hid_warn_once before returning is suggested. I could even see an
argument for removing the device if these conditions are encountered,
but that's probably too extreme. In general, each of the places that
you perform this check should be updated with such a warning (in this
and other patches).
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 (!touch_max)
> return 0;
>
> @@ -4226,9 +4229,14 @@ static void wacom_update_led(struct wacom *wacom, int button_count, int mask,
> static void wacom_report_numbered_buttons(struct input_dev *input_dev,
> int button_count, int mask)
> {
> - struct wacom *wacom = input_get_drvdata(input_dev);
> + struct wacom *wacom;
> int i;
>
> + if (!input_dev)
> + return;
> +
> + wacom = input_get_drvdata(input_dev);
> +
> for (i = 0; i < wacom->led.count; i++)
> wacom_update_led(wacom, button_count, mask, i);
>
> --
> 2.53.0
>
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 2/5] HID: wacom: check the input devices in the legacy irq handlers
2026-09-27 4:11 ` [PATCH 2/5] HID: wacom: check the input devices in the legacy irq handlers Jinmo Yang
@ 2026-10-17 0:05 ` Jason Gerecke
0 siblings, 0 replies; 36+ messages in thread
From: Jason Gerecke @ 2026-10-17 0:05 UTC (permalink / raw)
To: Jinmo Yang
Cc: ping.cheng, jason.gerecke, jikos, bentiss, dmitry.torokhov,
linux-input, linux-kernel, stable
On Sat, Sep 26, 2026 at 9:12 PM Jinmo Yang <jinmo44.yang@gmail.com> wrote:
>
> wacom_penpartner_irq(), wacom_pl_irq(), wacom_ptu_irq(),
> wacom_dtu_irq(), wacom_dtus_irq() and wacom_graphire_irq() take
> pen_input, and the latter two also take pad_input, without checking
> either.
>
> As described in "HID: wacom: check the input device in the shared
> report helpers", a partial interface leaves one or two of the three
> input devices NULL on a fully successful probe, and wacom_wac_irq()
> still dispatches to these handlers. Seven 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:137 wacom_penpartner_irq pen_input
> wacom_wac.c:227 wacom_pl_irq pen_input
> wacom_wac.c:244 wacom_ptu_irq pen_input
> wacom_wac.c:303 wacom_dtus_irq pad_input
> wacom_wac.c:326 wacom_dtus_irq pen_input
> wacom_wac.c:391 wacom_graphire_irq pen_input
> wacom_wac.c:444 wacom_graphire_irq pad_input
>
> for example, with vendor 0x056a product 0x0030 (PL) and report id 2:
>
> BUG: KASAN: null-ptr-deref in input_event+0x44/0xb0
> Read of size 8 at addr 0000000000000028
> wacom_wac_irq+0x2b27/0xb3f0
> wacom_raw_event+0x68f/0xb60
> __hid_input_report+0x398/0x4d0
> uhid_char_write+0xa99/0xfc0
>
> Check each pointer where it is taken. wacom_dtus_irq() and
> wacom_graphire_irq() serve both pen and pad reports, so the checks are
> placed per branch rather than at function entry: an interface that has
> a pad but no pen must keep delivering pad events.
>
Such a device does not exist for the cases handled by
wacom_graphire_irq and wacom_dtus_irq. A pen interface is expected for
all of these device types, and a pad interface is expected for all but
the GRAPHIRE case. The wacom_setup_device_quirks function takes care
of ensuring that the pad type gets added to the same interface as the
pen (for all but GRAPHIRE) so that wacom_setup_pad_input_capabilities
does not cull the interface later.
It should be safe to move the checks for valid pen and touch
interfaces to the top of both of these functions (again, with the
additional condition that wacom_graphire_irq must must ignore a NULL
pad in the case of a GRAPHIRE type).
> wacom_dtu_irq() gets a check too. Its only dereference is in a
> dev_dbg(), so it does not fault with CONFIG_DYNAMIC_DEBUG=n, but it is
> unconditional in the source.
>
> Fixes: 2a6cdbdd4cc0 ("HID: wacom: Introduce new 'touch_input' device")
> Fixes: 862cf5535c0c ("HID: wacom: Introduce a new WACOM_DEVICETYPE_PAD device_type")
> Cc: stable@vger.kernel.org
> Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
> ---
> drivers/hid/wacom_wac.c | 25 +++++++++++++++++++++----
> 1 file changed, 21 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
> index 177a1e09fd05..794c2865064a 100644
> --- a/drivers/hid/wacom_wac.c
> +++ b/drivers/hid/wacom_wac.c
> @@ -128,6 +128,9 @@ static int wacom_penpartner_irq(struct wacom_wac *wacom)
> unsigned char *data = wacom->data;
> struct input_dev *input = wacom->pen_input;
>
> + if (!input)
> + return 0;
> +
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....
> switch (data[0]) {
> case 1:
> if (data[5] & 0x80) {
> @@ -174,6 +177,9 @@ static int wacom_pl_irq(struct wacom_wac *wacom)
> struct input_dev *input = wacom->pen_input;
> int prox, pressure;
>
> + if (!input)
> + return 0;
> +
> if (data[0] != WACOM_REPORT_PENABLED) {
> dev_dbg(input->dev.parent,
> "%s: received unknown report #%d\n", __func__, data[0]);
> @@ -233,6 +239,9 @@ static int wacom_ptu_irq(struct wacom_wac *wacom)
> unsigned char *data = wacom->data;
> struct input_dev *input = wacom->pen_input;
>
> + if (!input)
> + return 0;
> +
> if (data[0] != WACOM_REPORT_PENABLED) {
> dev_dbg(input->dev.parent,
> "%s: received unknown report #%d\n", __func__, data[0]);
> @@ -263,6 +272,9 @@ static int wacom_dtu_irq(struct wacom_wac *wacom)
> struct input_dev *input = wacom->pen_input;
> int prox = data[1] & 0x20;
>
> + if (!input)
> + return 0;
> +
> dev_dbg(input->dev.parent,
> "%s: received report #%d", __func__, data[0]);
>
> @@ -299,6 +311,8 @@ static int wacom_dtus_irq(struct wacom_wac *wacom)
> return 0;
> } else if (data[0] == WACOM_REPORT_DTUSPAD) {
> input = wacom->pad_input;
> + if (!input)
> + return 0;
> input_report_key(input, BTN_0, (data[1] & 0x01));
> input_report_key(input, BTN_1, (data[1] & 0x02));
> input_report_key(input, BTN_2, (data[1] & 0x04));
> @@ -307,6 +321,9 @@ static int wacom_dtus_irq(struct wacom_wac *wacom)
> data[1] & 0x0f ? PAD_DEVICE_ID : 0);
> return 1;
> } else {
> + if (!input)
> + return 0;
> +
> prox = data[1] & 0x80;
> if (prox) {
> switch ((data[1] >> 3) & 3) {
> @@ -363,7 +380,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom)
> }
>
> prox = data[1] & 0x80;
> - if (prox || wacom->id[0]) {
> + if (input && (prox || wacom->id[0])) {
> if (prox) {
> switch ((data[1] >> 5) & 3) {
>
> @@ -438,7 +455,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom)
> switch (features->type) {
> case WACOM_G4:
> prox = data[7] & 0xf8;
> - if (prox || wacom->id[1]) {
> + if (pad_input && (prox || wacom->id[1])) {
> wacom->id[1] = PAD_DEVICE_ID;
> input_report_key(pad_input, BTN_BACK, (data[7] & 0x40));
> input_report_key(pad_input, BTN_FORWARD, (data[7] & 0x80));
> @@ -453,7 +470,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom)
>
> case WACOM_MO:
> prox = (data[7] & 0xf8) || data[8];
> - if (prox || wacom->id[1]) {
> + if (pad_input && (prox || wacom->id[1])) {
> wacom->id[1] = PAD_DEVICE_ID;
> input_report_key(pad_input, BTN_BACK, (data[7] & 0x08));
> input_report_key(pad_input, BTN_LEFT, (data[7] & 0x20));
> @@ -468,7 +485,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom)
> break;
> case GRAPHIRE_BT:
> prox = data[7] & 0x03;
> - if (prox || wacom->id[1]) {
> + if (pad_input && (prox || wacom->id[1])) {
> wacom->id[1] = PAD_DEVICE_ID;
> input_report_key(pad_input, BTN_0, (data[7] & 0x02));
> input_report_key(pad_input, BTN_1, (data[7] & 0x01));
> --
> 2.53.0
>
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 3/5] HID: wacom: check the input device in wacom_intuos_pad()
2026-09-27 4:11 ` [PATCH 3/5] HID: wacom: check the input device in wacom_intuos_pad() Jinmo Yang
2026-09-27 4:24 ` sashiko-bot
@ 2026-10-17 0:05 ` Jason Gerecke
1 sibling, 0 replies; 36+ messages in thread
From: Jason Gerecke @ 2026-10-17 0:05 UTC (permalink / raw)
To: Jinmo Yang
Cc: ping.cheng, jason.gerecke, jikos, bentiss, dmitry.torokhov,
linux-input, linux-kernel, stable
On Sat, Sep 26, 2026 at 9:12 PM Jinmo Yang <jinmo44.yang@gmail.com> wrote:
>
> wacom_intuos_pad() takes wacom->pad_input without checking it. An
> interface that declares no pad leaves the pointer NULL on a fully
> successful probe, and wacom_intuos_irq() still calls this function for
> pad report ids.
>
> Reproduced on linux-next 20260925 (x86_64, KASAN) with vendor 0x056a
> product 0x032A and report id 12:
>
> BUG: KASAN: null-ptr-deref in input_event+0x44/0xb0
> Read of size 8 at addr 0000000000000028
> wacom_intuos_irq+0x1b46/0x3300
> wacom_wac_irq+0x1b59/0xb3f0
> wacom_raw_event+0x68f/0xb60
> __hid_input_report+0x398/0x4d0
> uhid_char_write+0xa99/0xfc0
>
> The function only ever serves pad reports, so the check goes at entry.
>
> Fixes: 10059cdc0ad0 ("Input: wacom - split out the pad device for Intuos/Cintiq")
> Cc: stable@vger.kernel.org
> Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
> ---
> drivers/hid/wacom_wac.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
> index 794c2865064a..48a58a6672c2 100644
> --- a/drivers/hid/wacom_wac.c
> +++ b/drivers/hid/wacom_wac.c
> @@ -553,6 +553,9 @@ static int wacom_intuos_pad(struct wacom_wac *wacom)
> bool wrench = false, keyboard = false, mute_touch = false, menu = false,
> info = false;
>
> + if (!input)
> + return 0;
> +
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....
> /* pad packets. Works as a second tool and is always in prox */
> if (!(data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD ||
> data[0] == WACOM_REPORT_CINTIQPAD))
> --
> 2.53.0
>
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/5] HID: wacom: check the input device in wacom_intuos_bt_irq()
2026-09-27 4:11 ` [PATCH 4/5] HID: wacom: check the input device in wacom_intuos_bt_irq() Jinmo Yang
@ 2026-10-17 0:05 ` Jason Gerecke
0 siblings, 0 replies; 36+ messages in thread
From: Jason Gerecke @ 2026-10-17 0:05 UTC (permalink / raw)
To: Jinmo Yang
Cc: ping.cheng, jason.gerecke, jikos, bentiss, dmitry.torokhov,
linux-input, linux-kernel, stable
On Sat, Sep 26, 2026 at 9:12 PM Jinmo Yang <jinmo44.yang@gmail.com> wrote:
>
> wacom_intuos_bt_irq() reaches for wacom->pen_input three ways without
> checking it: two dev_warn() calls on the short-report paths, a dev_dbg()
> on the unknown-report path, and input_sync(wacom->pen_input) inside
> wacom_intuos_bt_process_data(), which is called only from here. That last
> one is the odd one out, because the pad_input sync two lines below it is
> guarded:
>
> input_sync(wacom->pen_input);
> if (wacom->pad_input)
> input_sync(wacom->pad_input);
>
> An interface that declares no pen leaves the pointer NULL on a fully
> successful probe, as described in "HID: wacom: check the input device in
> the shared report helpers".
>
> Reproduced on linux-next 20260925 (x86_64, KASAN) with bus BUS_BLUETOOTH,
> vendor 0x056a product 0x00BD (INTUOS4WL):
>
> BUG: KASAN: null-ptr-deref in range [0x258-0x25f]
> RIP: 0010:wacom_wac_irq.cold+0x8f/0x16a
> wacom_raw_event+0x68f/0xb60
> __hid_input_report+0x398/0x4d0
> uhid_char_write+0xa99/0xfc0
>
> One check at function entry covers all of them. It is safe to bail out
> there: this handler only runs for INTUOS4WL, and
> wacom_setup_device_quirks() only adds WACOM_DEVICETYPE_PAD for that
> range of types when WACOM_DEVICETYPE_PEN is already set, so a NULL
> pen_input implies a NULL pad_input and there is nothing the function can
> report. Every path that reaches the battery notification passes through
> wacom_intuos_bt_process_data() first, so no reachable work is lost.
>
Similar to patch 2/5, INTUOS4WL is a case where all hardware of this
type should have both pen and pad on a single interface. The existing
explicit check for a non-NULL pad does not imply that pen-only devices
of this type exist. As you describe here, there are no situations
where only the pad would exist, and there is also no situation in
which only the pen would exist (the WACOM_DEVICETYPE_PEN will already
be set, as described). A check for both pen and touch pointer validity
can be performed at the beginning of both wacom_setup_device_quirks
and wacom_intuos_bt_process_data.
> Fixes: 2a6cdbdd4cc0 ("HID: wacom: Introduce new 'touch_input' device")
> Cc: stable@vger.kernel.org
> Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
> ---
> drivers/hid/wacom_wac.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
> index 48a58a6672c2..11544adb74f5 100644
> --- a/drivers/hid/wacom_wac.c
> +++ b/drivers/hid/wacom_wac.c
> @@ -1237,6 +1237,9 @@ static int wacom_intuos_bt_irq(struct wacom_wac *wacom, size_t len)
> int i = 1;
> unsigned power_raw, battery_capacity, bat_charging, ps_connected;
>
> + if (!wacom->pen_input)
> + return 0;
> +
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....
> switch (data[0]) {
> case 0x04:
> if (len < 32) {
> --
> 2.53.0
>
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 5/5] HID: wacom: check the input devices in the Bamboo handlers
2026-09-27 4:11 ` [PATCH 5/5] HID: wacom: check the input devices in the Bamboo handlers Jinmo Yang
@ 2026-10-17 0:05 ` Jason Gerecke
0 siblings, 0 replies; 36+ messages in thread
From: Jason Gerecke @ 2026-10-17 0:05 UTC (permalink / raw)
To: Jinmo Yang
Cc: ping.cheng, jason.gerecke, jikos, bentiss, dmitry.torokhov,
linux-input, linux-kernel, stable
On Sat, Sep 26, 2026 at 9:12 PM Jinmo Yang <jinmo44.yang@gmail.com> 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@vger.kernel.org
> Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
> ---
> 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
>
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v2 0/5] HID: wacom: guard against NULL input devices on successful probe
2026-09-27 4:11 ` [PATCH 0/5] HID: wacom: check input devices in the report handlers Jinmo Yang
` (6 preceding siblings ...)
2026-10-17 0:05 ` Jason Gerecke
@ 2026-10-18 10:46 ` Jinmo Yang
2026-10-18 10:46 ` [PATCH v2 1/5] HID: wacom: check the input device in the shared report helpers Jinmo Yang
` (4 more replies)
2026-10-18 12:47 ` [PATCH v3 0/6] HID: wacom: guard against NULL input devices on successful probe Jinmo Yang
8 siblings, 5 replies; 36+ messages in thread
From: Jinmo Yang @ 2026-10-18 10:46 UTC (permalink / raw)
To: ping.cheng, jason.gerecke, jikos, bentiss
Cc: dmitry.torokhov, linux-input, linux-kernel, stable, jinmo44.yang
When wacom_setup_{pen,touch,pad}_input_capabilities() returns -ENODEV,
the corresponding input pointer is set to NULL but probe still succeeds.
Subsequent irq handlers dereference those pointers unconditionally,
causing NULL-pointer dereferences reachable from a spoofed HID device.
This series adds per-function NULL guards across all affected handlers.
Changes in v2:
- Restructured per Jason Gerecke's review: replaced per-branch checks
with per-function checks for dtus_irq, graphire_irq, and the Bamboo
handlers — simpler and matches what each function actually requires.
- wacom_intuos_pad() now returns 1 (not 0) when pad_input is NULL, so
the report is consumed and does not fall through to
wacom_intuos_inout() which would misparse a pad packet as a pen
event (sashiko-bot).
- wacom_intuos_bt_irq() now guards both pen_input and pad_input, since
INTUOS4WL always has both on a single interface.
- Added dev_warn_once at every guard (Jason).
- Dropped the cp2112 patch (Benjamin prefers Dmitry's series).
Tested with uhid across 27 Wacom device types (spoofed bus):
unpatched patched
KASAN crashes 17 0
probe failures 0 0
hidraw nodes 26 26
input registrations 25 25
Jinmo Yang (5):
HID: wacom: check the input device in the shared report helpers
HID: wacom: check the input devices in the legacy irq handlers
HID: wacom: add NULL pad_input guard to wacom_intuos_pad()
HID: wacom: add NULL input guards to wacom_intuos_bt_irq()
HID: wacom: add NULL input guards to Bamboo touch/button handlers
drivers/hid/wacom_wac.c | 90 +++++++++++++++++++++++++++++++++++++++--
1 file changed, 87 insertions(+), 3 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v2 1/5] HID: wacom: check the input device in the shared report helpers
2026-10-18 10:46 ` [PATCH v2 0/5] HID: wacom: guard against NULL input devices on successful probe Jinmo Yang
@ 2026-10-18 10:46 ` Jinmo Yang
2026-10-18 11:00 ` sashiko-bot
2026-10-18 10:46 ` [PATCH v2 2/5] HID: wacom: check the input devices in the legacy irq handlers Jinmo Yang
` (3 subsequent siblings)
4 siblings, 1 reply; 36+ messages in thread
From: Jinmo Yang @ 2026-10-18 10:46 UTC (permalink / raw)
To: ping.cheng, jason.gerecke, jikos, bentiss
Cc: dmitry.torokhov, linux-input, linux-kernel, stable, jinmo44.yang
wacom_report_numbered_buttons() and wacom_wac_finger_count_touches() are
reached from several report handlers and use the input device they are
given without checking it.
Both can see a NULL input device on a fully successful probe. The report
handler is selected by features.type from the id table, while the three
input devices are allocated from what the report descriptor declares.
When wacom_setup_{pen,touch,pad}_input_capabilities() returns -ENODEV,
wacom_setup_inputs() frees that input device, sets the pointer to NULL
and still returns 0 - the "no pen in use on this interface" case.
wacom_wac_irq() then still routes reports to a handler that passes the
NULL pointer down.
Reproduced on linux-next 20260925 (x86_64, KASAN) from one /dev/uhid
device plus a single UHID_INPUT2 write:
BUG: KASAN: null-ptr-deref in range [0x290-0x297]
RIP: 0010:wacom_report_numbered_buttons+0x37/0x210
wacom_intuos_irq+0x29e/0x3300
wacom_wac_irq+0x1b59/0xb3f0
wacom_raw_event+0x68f/0xb60
__hid_input_report+0x398/0x4d0
uhid_char_write+0xa99/0xfc0
Check the pointer in both helpers, following the convention the driver
already uses in wacom_tpc_irq() and wacom_wac_pad_event(). Log a
warning on the first occurrence so the condition is not silently
swallowed.
Fixes: 10059cdc0ad0 ("Input: wacom - split out the pad device for Intuos/Cintiq")
Fixes: 2a6cdbdd4cc0 ("HID: wacom: Introduce new 'touch_input' device")
Cc: stable@vger.kernel.org
Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
---
drivers/hid/wacom_wac.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index c4cd87b781c4..567b01882eb1 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -1263,6 +1263,12 @@ static int wacom_wac_finger_count_touches(struct wacom_wac *wacom)
int count = 0;
int i;
+ if (!input) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: touch_input is NULL\n", __func__);
+ return 0;
+ }
+
if (!touch_max)
return 0;
@@ -4226,9 +4232,16 @@ static void wacom_update_led(struct wacom *wacom, int button_count, int mask,
static void wacom_report_numbered_buttons(struct input_dev *input_dev,
int button_count, int mask)
{
- struct wacom *wacom = input_get_drvdata(input_dev);
+ struct wacom *wacom;
int i;
+ if (!input_dev) {
+ pr_warn_once("%s: input_dev is NULL\n", __func__);
+ return;
+ }
+
+ wacom = input_get_drvdata(input_dev);
+
for (i = 0; i < wacom->led.count; i++)
wacom_update_led(wacom, button_count, mask, i);
--
2.53.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v2 2/5] HID: wacom: check the input devices in the legacy irq handlers
2026-10-18 10:46 ` [PATCH v2 0/5] HID: wacom: guard against NULL input devices on successful probe Jinmo Yang
2026-10-18 10:46 ` [PATCH v2 1/5] HID: wacom: check the input device in the shared report helpers Jinmo Yang
@ 2026-10-18 10:46 ` Jinmo Yang
2026-10-18 10:53 ` sashiko-bot
2026-10-18 10:46 ` [PATCH v2 3/5] HID: wacom: add NULL pad_input guard to wacom_intuos_pad() Jinmo Yang
` (2 subsequent siblings)
4 siblings, 1 reply; 36+ messages in thread
From: Jinmo Yang @ 2026-10-18 10:46 UTC (permalink / raw)
To: ping.cheng, jason.gerecke, jikos, bentiss
Cc: dmitry.torokhov, linux-input, linux-kernel, stable, jinmo44.yang
wacom_penpartner_irq(), wacom_pl_irq(), wacom_ptu_irq(),
wacom_dtu_irq(), wacom_dtus_irq() and wacom_graphire_irq() dereference
pen_input and, for the latter two, pad_input without checking them.
As described in "HID: wacom: check the input device in the shared
report helpers", a partial interface leaves one or two of the three
input devices NULL on a fully successful probe, and wacom_wac_irq()
still dispatches to these handlers. Seven locations fault, each
reproduced on linux-next 20260925 (x86_64, KASAN) from one /dev/uhid
device plus a single UHID_INPUT2 write.
For wacom_dtus_irq() and wacom_graphire_irq(), all hardware served by
these handlers is expected to have both pen and pad on a single
interface (the one exception is GRAPHIRE, which is pen-only). Rather
than scattering checks per branch, validate the expected input devices
at function entry and bail out early if any are missing.
wacom_dtu_irq() gets a check too. Its only dereference is in a
dev_dbg(), so it does not fault with CONFIG_DYNAMIC_DEBUG=n, but it is
unconditional in the source.
Fixes: 2a6cdbdd4cc0 ("HID: wacom: Introduce new 'touch_input' device")
Fixes: 862cf5535c0c ("HID: wacom: Introduce a new WACOM_DEVICETYPE_PAD device_type")
Cc: stable@vger.kernel.org
Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
---
drivers/hid/wacom_wac.c | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index 567b01882eb1..aa08afb3c5ef 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -128,6 +128,12 @@ static int wacom_penpartner_irq(struct wacom_wac *wacom)
unsigned char *data = wacom->data;
struct input_dev *input = wacom->pen_input;
+ if (!input) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: pen_input is NULL\n", __func__);
+ return 0;
+ }
+
switch (data[0]) {
case 1:
if (data[5] & 0x80) {
@@ -174,6 +180,12 @@ static int wacom_pl_irq(struct wacom_wac *wacom)
struct input_dev *input = wacom->pen_input;
int prox, pressure;
+ if (!input) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: pen_input is NULL\n", __func__);
+ return 0;
+ }
+
if (data[0] != WACOM_REPORT_PENABLED) {
dev_dbg(input->dev.parent,
"%s: received unknown report #%d\n", __func__, data[0]);
@@ -233,6 +245,12 @@ static int wacom_ptu_irq(struct wacom_wac *wacom)
unsigned char *data = wacom->data;
struct input_dev *input = wacom->pen_input;
+ if (!input) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: pen_input is NULL\n", __func__);
+ return 0;
+ }
+
if (data[0] != WACOM_REPORT_PENABLED) {
dev_dbg(input->dev.parent,
"%s: received unknown report #%d\n", __func__, data[0]);
@@ -263,6 +281,12 @@ static int wacom_dtu_irq(struct wacom_wac *wacom)
struct input_dev *input = wacom->pen_input;
int prox = data[1] & 0x20;
+ if (!input) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: pen_input is NULL\n", __func__);
+ return 0;
+ }
+
dev_dbg(input->dev.parent,
"%s: received report #%d", __func__, data[0]);
@@ -293,6 +317,13 @@ static int wacom_dtus_irq(struct wacom_wac *wacom)
struct input_dev *input = wacom->pen_input;
unsigned short prox, pressure = 0;
+ if (!input || !wacom->pad_input) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: expected pen and pad input devices\n",
+ __func__);
+ return 0;
+ }
+
if (data[0] != WACOM_REPORT_DTUS && data[0] != WACOM_REPORT_DTUSPAD) {
dev_dbg(input->dev.parent,
"%s: received unknown report #%d", __func__, data[0]);
@@ -349,6 +380,12 @@ static int wacom_graphire_irq(struct wacom_wac *wacom)
int rw = 0;
int retval = 0;
+ if (!input || (!pad_input && features->type != GRAPHIRE)) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: missing input device(s)\n", __func__);
+ return 0;
+ }
+
if (features->type == GRAPHIRE_BT) {
if (data[0] != WACOM_REPORT_PENABLED_BT) {
dev_dbg(input->dev.parent,
--
2.53.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v2 3/5] HID: wacom: add NULL pad_input guard to wacom_intuos_pad()
2026-10-18 10:46 ` [PATCH v2 0/5] HID: wacom: guard against NULL input devices on successful probe Jinmo Yang
2026-10-18 10:46 ` [PATCH v2 1/5] HID: wacom: check the input device in the shared report helpers Jinmo Yang
2026-10-18 10:46 ` [PATCH v2 2/5] HID: wacom: check the input devices in the legacy irq handlers Jinmo Yang
@ 2026-10-18 10:46 ` Jinmo Yang
2026-10-18 10:46 ` [PATCH v2 4/5] HID: wacom: add NULL input guards to wacom_intuos_bt_irq() Jinmo Yang
2026-10-18 10:46 ` [PATCH v2 5/5] HID: wacom: add NULL input guards to Bamboo touch/button handlers Jinmo Yang
4 siblings, 0 replies; 36+ messages in thread
From: Jinmo Yang @ 2026-10-18 10:46 UTC (permalink / raw)
To: ping.cheng, jason.gerecke, jikos, bentiss
Cc: dmitry.torokhov, linux-input, linux-kernel, stable, jinmo44.yang,
Claude Opus 4.6
wacom_intuos_pad() uses wacom->pad_input throughout, but pad_input can
be NULL when wacom_setup_pad_input_capabilities() returns -ENODEV during
a successful probe.
Place the guard after the data[0] report-ID check and return 1 so the
report is consumed. Returning 0 would let the caller fall through to
wacom_intuos_inout(), which would misparse the pad packet as a pen
event.
Fixes: 10059cdc0ad0 ("Input: wacom - split out the pad device for Intuos/Cintiq")
Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---
drivers/hid/wacom_wac.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index aa08afb3c5ef..acf24360d547 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -578,6 +578,12 @@ static int wacom_intuos_pad(struct wacom_wac *wacom)
data[0] == WACOM_REPORT_CINTIQPAD))
return 0;
+ if (!input) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: pad_input is NULL\n", __func__);
+ return 1; /* consume the report to prevent fall-through */
+ }
+
if (features->type >= INTUOS4S && features->type <= INTUOS4L) {
buttons = (data[3] << 1) | (data[2] & 0x01);
ring1 = data[1];
--
2.53.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v2 4/5] HID: wacom: add NULL input guards to wacom_intuos_bt_irq()
2026-10-18 10:46 ` [PATCH v2 0/5] HID: wacom: guard against NULL input devices on successful probe Jinmo Yang
` (2 preceding siblings ...)
2026-10-18 10:46 ` [PATCH v2 3/5] HID: wacom: add NULL pad_input guard to wacom_intuos_pad() Jinmo Yang
@ 2026-10-18 10:46 ` Jinmo Yang
2026-10-18 10:46 ` [PATCH v2 5/5] HID: wacom: add NULL input guards to Bamboo touch/button handlers Jinmo Yang
4 siblings, 0 replies; 36+ messages in thread
From: Jinmo Yang @ 2026-10-18 10:46 UTC (permalink / raw)
To: ping.cheng, jason.gerecke, jikos, bentiss
Cc: dmitry.torokhov, linux-input, linux-kernel, stable, jinmo44.yang,
Claude Opus 4.6
wacom_intuos_bt_irq() dereferences wacom->pen_input in every switch
branch, both directly for dev_warn/dev_dbg and indirectly through
wacom_intuos_bt_process_data() which calls input_sync(pen_input).
pad_input is also used in wacom_intuos_bt_process_data().
Both can be NULL when the corresponding setup_*_input_capabilities()
returns -ENODEV during a successful probe. For INTUOS4WL, pen and pad
are always expected together, so guard both at function entry.
Fixes: 2a6cdbdd4cc0 ("HID: wacom: Introduce new 'touch_input' device")
Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---
drivers/hid/wacom_wac.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index acf24360d547..12a632ee1cbf 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -1260,6 +1260,13 @@ static int wacom_intuos_bt_irq(struct wacom_wac *wacom, size_t len)
int i = 1;
unsigned power_raw, battery_capacity, bat_charging, ps_connected;
+ if (!wacom->pen_input || !wacom->pad_input) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: expected pen and pad input devices\n",
+ __func__);
+ return 0;
+ }
+
switch (data[0]) {
case 0x04:
if (len < 32) {
--
2.53.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v2 5/5] HID: wacom: add NULL input guards to Bamboo touch/button handlers
2026-10-18 10:46 ` [PATCH v2 0/5] HID: wacom: guard against NULL input devices on successful probe Jinmo Yang
` (3 preceding siblings ...)
2026-10-18 10:46 ` [PATCH v2 4/5] HID: wacom: add NULL input guards to wacom_intuos_bt_irq() Jinmo Yang
@ 2026-10-18 10:46 ` Jinmo Yang
4 siblings, 0 replies; 36+ messages in thread
From: Jinmo Yang @ 2026-10-18 10:46 UTC (permalink / raw)
To: ping.cheng, jason.gerecke, jikos, bentiss
Cc: dmitry.torokhov, linux-input, linux-kernel, stable, jinmo44.yang,
Claude Opus 4.6
wacom_bpt_touch() dereferences both touch_input and pad_input.
wacom_bpt3_touch_msg() dereferences touch_input.
wacom_bpt3_button_msg() dereferences pad_input.
All three can be NULL when the corresponding
wacom_setup_{touch,pad}_input_capabilities() returns -ENODEV during a
successful probe. Add per-function guards.
Fixes: 2a6cdbdd4cc0 ("HID: wacom: Introduce new 'touch_input' device")
Fixes: 862cf5535c0c ("HID: wacom: Introduce a new WACOM_DEVICETYPE_PAD device_type")
Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---
drivers/hid/wacom_wac.c | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index 12a632ee1cbf..21c2504a085a 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -3148,6 +3148,12 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
if (data[0] != 0x02)
return 0;
+ if (!input || !pad_input) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: input is NULL\n", __func__);
+ return 0;
+ }
+
for (i = 0; i < 2; i++) {
int offset = (data[1] & 0x80) ? (8 * i) : (9 * i);
bool touch = report_touch_events(wacom)
@@ -3182,8 +3188,17 @@ 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]);
+ bool touch;
+ int slot;
+
+ if (!input) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: touch_input is NULL\n", __func__);
+ return;
+ }
+
+ touch = data[1] & 0x80;
+ slot = input_mt_get_slot_by_key(input, data[0]);
if (slot < 0)
return;
@@ -3226,6 +3241,12 @@ 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) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: pad_input is NULL\n", __func__);
+ return;
+ }
+
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
^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [PATCH v2 2/5] HID: wacom: check the input devices in the legacy irq handlers
2026-10-18 10:46 ` [PATCH v2 2/5] HID: wacom: check the input devices in the legacy irq handlers Jinmo Yang
@ 2026-10-18 10:53 ` sashiko-bot
0 siblings, 0 replies; 36+ messages in thread
From: sashiko-bot @ 2026-10-18 10:53 UTC (permalink / raw)
To: Jinmo Yang; +Cc: linux-input, dmitry.torokhov
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] HID: wacom: requiring pad_input in wacom_dtus_irq() breaks DTUSX pen input
--
commit 1918eedc787a6887650a12d8f1032a28643191fc
Author: Jinmo Yang <jinmo44.yang@gmail.com>
HID: wacom: check the input devices in the legacy irq handlers
This commit adds NULL checks for wacom->pen_input and wacom->pad_input at
the entry of six legacy Wacom interrupt handlers to prevent NULL pointer
dereferences when an interface only initializes a subset of the input
devices.
> diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
> index 567b01882eb1e..aa08afb3c5ef0 100644
> --- a/drivers/hid/wacom_wac.c
> +++ b/drivers/hid/wacom_wac.c
[ ... ]
> @@ -293,6 +317,13 @@ static int wacom_dtus_irq(struct wacom_wac *wacom)
> struct input_dev *input = wacom->pen_input;
> unsigned short prox, pressure = 0;
>
> + if (!input || !wacom->pad_input) {
> + dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
> + "%s: expected pen and pad input devices\n",
> + __func__);
> + return 0;
> + }
[Severity: High]
Does requiring wacom->pad_input at the start of wacom_dtus_irq() break pen
input on Wacom DTU-1031X (DTUSX) tablets?
In drivers/hid/wacom_wac.c, wacom_wac_irq() dispatches both DTUS and DTUSX
devices to wacom_dtus_irq():
case DTUS:
case DTUSX:
sync = wacom_dtus_irq(wacom_wac);
break;
Unlike DTUS tablets, the Wacom DTU-1031X (wacom_features_0x32F, with type
DTUSX) is pen-only and has 0 numbered buttons:
static const struct wacom_features wacom_features_0x32F =
{ "Wacom DTU1031X", 22672, 12928, 511, 0,
DTUSX, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 0,
WACOM_DTU_OFFSET, WACOM_DTU_OFFSET,
WACOM_DTU_OFFSET, WACOM_DTU_OFFSET };
During probe, wacom_setup_device_quirks() only sets WACOM_DEVICETYPE_PAD
for DTUS, not DTUSX:
if (features->type == GRAPHIRE_BT || features->type == WACOM_G4 ||
features->type == DTUS ||
(features->type >= INTUOS3S && features->type <= WACOM_MO)) {
if (features->device_type & WACOM_DEVICETYPE_PEN)
features->device_type |= WACOM_DEVICETYPE_PAD;
}
And wacom_setup_pad_input_capabilities() returns -ENODEV for DTUSX, which
causes wacom_setup_inputs() to free pad_input and leave wacom->pad_input
as NULL.
When WACOM_REPORT_DTUS pen reports arrive from a DTUSX tablet, won't this
new check always trigger and drop all pen events? Should wacom->pad_input
only be required when features->type != DTUSX (with a check in the
WACOM_REPORT_DTUSPAD branch), or checked specifically when handling
WACOM_REPORT_DTUSPAD reports?
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261018104617.743771-1-jinmo44.yang@gmail.com?part=2
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 1/5] HID: wacom: check the input device in the shared report helpers
2026-10-18 10:46 ` [PATCH v2 1/5] HID: wacom: check the input device in the shared report helpers Jinmo Yang
@ 2026-10-18 11:00 ` sashiko-bot
0 siblings, 0 replies; 36+ messages in thread
From: sashiko-bot @ 2026-10-18 11:00 UTC (permalink / raw)
To: Jinmo Yang; +Cc: linux-input, dmitry.torokhov
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] hid: wacom: touch_input dereferenced before wacom_wac_finger_count_touches()
--
commit 44932063e701ad08bed9376ede6b9b3005174d4c
Author: Jinmo Yang <jinmo44.yang@gmail.com>
HID: wacom: check the input device in the shared report helpers
This commit adds NULL checks for the input device in
wacom_wac_finger_count_touches() and wacom_report_numbered_buttons() to
avoid NULL pointer dereferences when a device interface has no allocated
touch or pad input device.
> diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
> index c4cd87b781c45..567b01882eb1e 100644
> --- a/drivers/hid/wacom_wac.c
> +++ b/drivers/hid/wacom_wac.c
> @@ -1263,6 +1263,12 @@ static int wacom_wac_finger_count_touches(struct wacom_wac *wacom)
> int count = 0;
> int i;
>
> + if (!input) {
> + dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
> + "%s: touch_input is NULL\n", __func__);
> + return 0;
> + }
> +
> if (!touch_max)
> return 0;
>
[Severity: High]
Can this NULL check in wacom_wac_finger_count_touches() actually be
reached when wacom->touch_input is NULL?
Every caller of wacom_wac_finger_count_touches() in drivers/hid/wacom_wac.c
first passes wacom->touch_input to input_mt_sync_frame(), which
immediately dereferences dev->mt:
drivers/input/input-mt.c:input_mt_sync_frame() {
struct input_mt *mt = dev->mt;
bool use_count = false;
if (!mt)
return;
...
}
For example, while a later commit in this series ("HID: wacom: add NULL
input guards to Bamboo touch/button handlers") guards wacom_bpt_touch(),
wacom_24hdt_irq() remains unguarded when wacom->touch_input is NULL (such
as when a WACOM_24HDT or WACOM_27QHDT device probes with a report
descriptor that omits WACOM_FINGER_FIELD usages):
drivers/hid/wacom_wac.c:wacom_24hdt_irq() {
struct input_dev *input = wacom->touch_input;
...
for (i = 0; i < contacts_to_send; i++) {
int offset = (byte_per_packet * i) + 1;
bool touch = (data[offset] & 0x1) && report_touch_events(wacom);
int slot = input_mt_get_slot_by_key(input, data[offset + 1]);
...
}
input_mt_sync_frame(input);
wacom->num_contacts_left -= contacts_to_send;
if (wacom->num_contacts_left <= 0) {
wacom->num_contacts_left = 0;
wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom);
}
return 1;
}
Wouldn't wacom_24hdt_irq() dereference a NULL input pointer in
input_mt_get_slot_by_key() and input_mt_sync_frame() before ever reaching
wacom_wac_finger_count_touches()?
Also, when input is non-NULL and touch_max > 1, input_mt_get_slot_by_key(),
input_mt_report_slot_state(), and input_mt_sync_frame() all check for a
NULL dev->mt, whereas wacom_wac_finger_count_touches() dereferences
input->mt->num_slots directly:
drivers/hid/wacom_wac.c:wacom_wac_finger_count_touches() {
...
for (i = 0; i < input->mt->num_slots; i++) {
struct input_mt_slot *ps = &input->mt->slots[i];
...
}
Should wacom_24hdt_irq() check for a NULL input at entry, and should
wacom_wac_finger_count_touches() also guard against input->mt being NULL
(for instance if touch_max > 1 is set via HID_DG_CONTACTMAX without
input_mt_init_slots() having been called)?
[ ... ]
>
>
>
[]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261018104617.743771-1-jinmo44.yang@gmail.com?part=1
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v3 0/6] HID: wacom: guard against NULL input devices on successful probe
2026-09-27 4:11 ` [PATCH 0/5] HID: wacom: check input devices in the report handlers Jinmo Yang
` (7 preceding siblings ...)
2026-10-18 10:46 ` [PATCH v2 0/5] HID: wacom: guard against NULL input devices on successful probe Jinmo Yang
@ 2026-10-18 12:47 ` Jinmo Yang
2026-10-18 12:47 ` [PATCH v3 1/6] HID: wacom: check the input device in the shared report helpers Jinmo Yang
` (5 more replies)
8 siblings, 6 replies; 36+ messages in thread
From: Jinmo Yang @ 2026-10-18 12:47 UTC (permalink / raw)
To: ping.cheng, jason.gerecke, jikos, bentiss
Cc: dmitry.torokhov, linux-input, linux-kernel, stable, Jinmo Yang
When wacom_setup_{pen,touch,pad}_input_capabilities() returns -ENODEV,
the corresponding input pointer is set to NULL but probe still succeeds.
Subsequent irq handlers dereference those pointers unconditionally,
causing NULL-pointer dereferences reachable from a spoofed HID device.
This series adds per-function NULL guards across all affected handlers.
Changes in v3:
- wacom_dtus_irq(): DTUSX is pen-only (no pad), so the pad_input
requirement now has a type != DTUSX exception, matching the existing
GRAPHIRE exception in wacom_graphire_irq(). Also guards the DTUSPAD
branch for spoofed reports (sashiko-bot).
- New patch 6: guards wacom_24hdt_irq() (also covers WACOM_27QHDT),
wacom_intuos_pro2_bt_touch(), and wacom_bamboo_pad_touch_event(),
which were identified as unguarded during review (sashiko-bot).
Changes in v2:
- Restructured per Jason Gerecke's review: replaced per-branch checks
with per-function checks for dtus_irq, graphire_irq, and the Bamboo
handlers — simpler and matches what each function actually requires.
- wacom_intuos_pad() now returns 1 (not 0) when pad_input is NULL, so
the report is consumed and does not fall through to
wacom_intuos_inout() which would misparse a pad packet as a pen
event (sashiko-bot).
- wacom_intuos_bt_irq() now guards both pen_input and pad_input, since
INTUOS4WL always has both on a single interface.
- Added dev_warn_once at every guard (Jason).
- Dropped the cp2112 patch (Benjamin prefers Dmitry's series).
Tested with uhid across 27 Wacom device types (spoofed bus):
unpatched patched
KASAN crashes 17 0
probe failures 0 0
hidraw nodes 26 26
input registrations 25 25
Jinmo Yang (6):
HID: wacom: check the input device in the shared report helpers
HID: wacom: check the input devices in the legacy irq handlers
HID: wacom: add NULL pad_input guard to wacom_intuos_pad()
HID: wacom: add NULL input guards to wacom_intuos_bt_irq()
HID: wacom: add NULL input guards to Bamboo touch/button handlers
HID: wacom: add NULL touch_input guards to remaining touch handlers
drivers/hid/wacom_wac.c | 111 ++++++++++++++++++++++++++++++++++++++--
1 file changed, 108 insertions(+), 3 deletions(-)
base-commit: f5f84daefcd92d7a630066635ecea1433ed5eac7
--
2.53.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v3 1/6] HID: wacom: check the input device in the shared report helpers
2026-10-18 12:47 ` [PATCH v3 0/6] HID: wacom: guard against NULL input devices on successful probe Jinmo Yang
@ 2026-10-18 12:47 ` Jinmo Yang
2026-10-18 12:47 ` [PATCH v3 2/6] HID: wacom: check the input devices in the legacy irq handlers Jinmo Yang
` (4 subsequent siblings)
5 siblings, 0 replies; 36+ messages in thread
From: Jinmo Yang @ 2026-10-18 12:47 UTC (permalink / raw)
To: ping.cheng, jason.gerecke, jikos, bentiss
Cc: dmitry.torokhov, linux-input, linux-kernel, stable, Jinmo Yang
wacom_report_numbered_buttons() and wacom_wac_finger_count_touches() are
reached from several report handlers and use the input device they are
given without checking it.
Both can see a NULL input device on a fully successful probe. The report
handler is selected by features.type from the id table, while the three
input devices are allocated from what the report descriptor declares.
When wacom_setup_{pen,touch,pad}_input_capabilities() returns -ENODEV,
wacom_setup_inputs() frees that input device, sets the pointer to NULL
and still returns 0 - the "no pen in use on this interface" case.
wacom_wac_irq() then still routes reports to a handler that passes the
NULL pointer down.
Reproduced on linux-next 20260925 (x86_64, KASAN) from one /dev/uhid
device plus a single UHID_INPUT2 write:
BUG: KASAN: null-ptr-deref in range [0x290-0x297]
RIP: 0010:wacom_report_numbered_buttons+0x37/0x210
wacom_intuos_irq+0x29e/0x3300
wacom_wac_irq+0x1b59/0xb3f0
wacom_raw_event+0x68f/0xb60
__hid_input_report+0x398/0x4d0
uhid_char_write+0xa99/0xfc0
Check the pointer in both helpers, following the convention the driver
already uses in wacom_tpc_irq() and wacom_wac_pad_event(). Log a
warning on the first occurrence so the condition is not silently
swallowed.
Fixes: 10059cdc0ad0 ("Input: wacom - split out the pad device for Intuos/Cintiq")
Fixes: 2a6cdbdd4cc0 ("HID: wacom: Introduce new 'touch_input' device")
Cc: stable@vger.kernel.org
Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
---
drivers/hid/wacom_wac.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index c4cd87b781c4..567b01882eb1 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -1263,6 +1263,12 @@ static int wacom_wac_finger_count_touches(struct wacom_wac *wacom)
int count = 0;
int i;
+ if (!input) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: touch_input is NULL\n", __func__);
+ return 0;
+ }
+
if (!touch_max)
return 0;
@@ -4226,9 +4232,16 @@ static void wacom_update_led(struct wacom *wacom, int button_count, int mask,
static void wacom_report_numbered_buttons(struct input_dev *input_dev,
int button_count, int mask)
{
- struct wacom *wacom = input_get_drvdata(input_dev);
+ struct wacom *wacom;
int i;
+ if (!input_dev) {
+ pr_warn_once("%s: input_dev is NULL\n", __func__);
+ return;
+ }
+
+ wacom = input_get_drvdata(input_dev);
+
for (i = 0; i < wacom->led.count; i++)
wacom_update_led(wacom, button_count, mask, i);
--
2.53.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v3 2/6] HID: wacom: check the input devices in the legacy irq handlers
2026-10-18 12:47 ` [PATCH v3 0/6] HID: wacom: guard against NULL input devices on successful probe Jinmo Yang
2026-10-18 12:47 ` [PATCH v3 1/6] HID: wacom: check the input device in the shared report helpers Jinmo Yang
@ 2026-10-18 12:47 ` Jinmo Yang
2026-10-18 12:47 ` [PATCH v3 3/6] HID: wacom: add NULL pad_input guard to wacom_intuos_pad() Jinmo Yang
` (3 subsequent siblings)
5 siblings, 0 replies; 36+ messages in thread
From: Jinmo Yang @ 2026-10-18 12:47 UTC (permalink / raw)
To: ping.cheng, jason.gerecke, jikos, bentiss
Cc: dmitry.torokhov, linux-input, linux-kernel, stable, Jinmo Yang,
Claude Opus 4.6
wacom_penpartner_irq(), wacom_pl_irq(), wacom_ptu_irq(),
wacom_dtu_irq(), wacom_dtus_irq() and wacom_graphire_irq() dereference
pen_input and, for the latter two, pad_input without checking them.
As described in "HID: wacom: check the input device in the shared
report helpers", a partial interface leaves one or two of the three
input devices NULL on a fully successful probe, and wacom_wac_irq()
still dispatches to these handlers. Seven locations fault, each
reproduced on linux-next 20260925 (x86_64, KASAN) from one /dev/uhid
device plus a single UHID_INPUT2 write.
For wacom_dtus_irq() and wacom_graphire_irq(), all hardware served by
these handlers is expected to have both pen and pad on a single
interface, with two exceptions: GRAPHIRE (pen-only) and DTUSX (pen-only,
no pad buttons). Guard the expected input devices at function entry,
skipping the pad_input requirement for those two types. For DTUSX, also
guard the DTUSPAD branch in case a spoofed device sends a pad report
anyway.
wacom_dtu_irq() gets a check too. Its only dereference is in a
dev_dbg(), so it does not fault with CONFIG_DYNAMIC_DEBUG=n, but it is
unconditional in the source.
Fixes: 2a6cdbdd4cc0 ("HID: wacom: Introduce new 'touch_input' device")
Fixes: 862cf5535c0c ("HID: wacom: Introduce a new WACOM_DEVICETYPE_PAD device_type")
Cc: stable@vger.kernel.org
Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---
drivers/hid/wacom_wac.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index 567b01882eb1..bec8dbec5bc3 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -128,6 +128,12 @@ static int wacom_penpartner_irq(struct wacom_wac *wacom)
unsigned char *data = wacom->data;
struct input_dev *input = wacom->pen_input;
+ if (!input) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: pen_input is NULL\n", __func__);
+ return 0;
+ }
+
switch (data[0]) {
case 1:
if (data[5] & 0x80) {
@@ -174,6 +180,12 @@ static int wacom_pl_irq(struct wacom_wac *wacom)
struct input_dev *input = wacom->pen_input;
int prox, pressure;
+ if (!input) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: pen_input is NULL\n", __func__);
+ return 0;
+ }
+
if (data[0] != WACOM_REPORT_PENABLED) {
dev_dbg(input->dev.parent,
"%s: received unknown report #%d\n", __func__, data[0]);
@@ -233,6 +245,12 @@ static int wacom_ptu_irq(struct wacom_wac *wacom)
unsigned char *data = wacom->data;
struct input_dev *input = wacom->pen_input;
+ if (!input) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: pen_input is NULL\n", __func__);
+ return 0;
+ }
+
if (data[0] != WACOM_REPORT_PENABLED) {
dev_dbg(input->dev.parent,
"%s: received unknown report #%d\n", __func__, data[0]);
@@ -263,6 +281,12 @@ static int wacom_dtu_irq(struct wacom_wac *wacom)
struct input_dev *input = wacom->pen_input;
int prox = data[1] & 0x20;
+ if (!input) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: pen_input is NULL\n", __func__);
+ return 0;
+ }
+
dev_dbg(input->dev.parent,
"%s: received report #%d", __func__, data[0]);
@@ -289,16 +313,26 @@ static int wacom_dtu_irq(struct wacom_wac *wacom)
static int wacom_dtus_irq(struct wacom_wac *wacom)
{
+ struct wacom_features *features = &wacom->features;
unsigned char *data = wacom->data;
struct input_dev *input = wacom->pen_input;
unsigned short prox, pressure = 0;
+ if (!input || (!wacom->pad_input && features->type != DTUSX)) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: missing input device(s)\n",
+ __func__);
+ return 0;
+ }
+
if (data[0] != WACOM_REPORT_DTUS && data[0] != WACOM_REPORT_DTUSPAD) {
dev_dbg(input->dev.parent,
"%s: received unknown report #%d", __func__, data[0]);
return 0;
} else if (data[0] == WACOM_REPORT_DTUSPAD) {
input = wacom->pad_input;
+ if (!input)
+ return 0;
input_report_key(input, BTN_0, (data[1] & 0x01));
input_report_key(input, BTN_1, (data[1] & 0x02));
input_report_key(input, BTN_2, (data[1] & 0x04));
@@ -349,6 +383,12 @@ static int wacom_graphire_irq(struct wacom_wac *wacom)
int rw = 0;
int retval = 0;
+ if (!input || (!pad_input && features->type != GRAPHIRE)) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: missing input device(s)\n", __func__);
+ return 0;
+ }
+
if (features->type == GRAPHIRE_BT) {
if (data[0] != WACOM_REPORT_PENABLED_BT) {
dev_dbg(input->dev.parent,
--
2.53.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v3 3/6] HID: wacom: add NULL pad_input guard to wacom_intuos_pad()
2026-10-18 12:47 ` [PATCH v3 0/6] HID: wacom: guard against NULL input devices on successful probe Jinmo Yang
2026-10-18 12:47 ` [PATCH v3 1/6] HID: wacom: check the input device in the shared report helpers Jinmo Yang
2026-10-18 12:47 ` [PATCH v3 2/6] HID: wacom: check the input devices in the legacy irq handlers Jinmo Yang
@ 2026-10-18 12:47 ` Jinmo Yang
2026-10-18 12:47 ` [PATCH v3 4/6] HID: wacom: add NULL input guards to wacom_intuos_bt_irq() Jinmo Yang
` (2 subsequent siblings)
5 siblings, 0 replies; 36+ messages in thread
From: Jinmo Yang @ 2026-10-18 12:47 UTC (permalink / raw)
To: ping.cheng, jason.gerecke, jikos, bentiss
Cc: dmitry.torokhov, linux-input, linux-kernel, stable, Jinmo Yang,
Claude Opus 4.6
wacom_intuos_pad() uses wacom->pad_input throughout, but pad_input can
be NULL when wacom_setup_pad_input_capabilities() returns -ENODEV during
a successful probe.
Place the guard after the data[0] report-ID check and return 1 so the
report is consumed. Returning 0 would let the caller fall through to
wacom_intuos_inout(), which would misparse the pad packet as a pen
event.
Fixes: 10059cdc0ad0 ("Input: wacom - split out the pad device for Intuos/Cintiq")
Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---
drivers/hid/wacom_wac.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index bec8dbec5bc3..65829de86363 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -581,6 +581,12 @@ static int wacom_intuos_pad(struct wacom_wac *wacom)
data[0] == WACOM_REPORT_CINTIQPAD))
return 0;
+ if (!input) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: pad_input is NULL\n", __func__);
+ return 1; /* consume the report to prevent fall-through */
+ }
+
if (features->type >= INTUOS4S && features->type <= INTUOS4L) {
buttons = (data[3] << 1) | (data[2] & 0x01);
ring1 = data[1];
--
2.53.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v3 4/6] HID: wacom: add NULL input guards to wacom_intuos_bt_irq()
2026-10-18 12:47 ` [PATCH v3 0/6] HID: wacom: guard against NULL input devices on successful probe Jinmo Yang
` (2 preceding siblings ...)
2026-10-18 12:47 ` [PATCH v3 3/6] HID: wacom: add NULL pad_input guard to wacom_intuos_pad() Jinmo Yang
@ 2026-10-18 12:47 ` Jinmo Yang
2026-10-18 12:47 ` [PATCH v3 5/6] HID: wacom: add NULL input guards to Bamboo touch/button handlers Jinmo Yang
2026-10-18 12:47 ` [PATCH v3 6/6] HID: wacom: add NULL touch_input guards to remaining touch handlers Jinmo Yang
5 siblings, 0 replies; 36+ messages in thread
From: Jinmo Yang @ 2026-10-18 12:47 UTC (permalink / raw)
To: ping.cheng, jason.gerecke, jikos, bentiss
Cc: dmitry.torokhov, linux-input, linux-kernel, stable, Jinmo Yang,
Claude Opus 4.6
wacom_intuos_bt_irq() dereferences wacom->pen_input in every switch
branch, both directly for dev_warn/dev_dbg and indirectly through
wacom_intuos_bt_process_data() which calls input_sync(pen_input).
pad_input is also used in wacom_intuos_bt_process_data().
Both can be NULL when the corresponding setup_*_input_capabilities()
returns -ENODEV during a successful probe. For INTUOS4WL, pen and pad
are always expected together, so guard both at function entry.
Fixes: 2a6cdbdd4cc0 ("HID: wacom: Introduce new 'touch_input' device")
Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---
drivers/hid/wacom_wac.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index 65829de86363..e0bf03123cf9 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -1263,6 +1263,13 @@ static int wacom_intuos_bt_irq(struct wacom_wac *wacom, size_t len)
int i = 1;
unsigned power_raw, battery_capacity, bat_charging, ps_connected;
+ if (!wacom->pen_input || !wacom->pad_input) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: expected pen and pad input devices\n",
+ __func__);
+ return 0;
+ }
+
switch (data[0]) {
case 0x04:
if (len < 32) {
--
2.53.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v3 5/6] HID: wacom: add NULL input guards to Bamboo touch/button handlers
2026-10-18 12:47 ` [PATCH v3 0/6] HID: wacom: guard against NULL input devices on successful probe Jinmo Yang
` (3 preceding siblings ...)
2026-10-18 12:47 ` [PATCH v3 4/6] HID: wacom: add NULL input guards to wacom_intuos_bt_irq() Jinmo Yang
@ 2026-10-18 12:47 ` Jinmo Yang
2026-10-18 12:47 ` [PATCH v3 6/6] HID: wacom: add NULL touch_input guards to remaining touch handlers Jinmo Yang
5 siblings, 0 replies; 36+ messages in thread
From: Jinmo Yang @ 2026-10-18 12:47 UTC (permalink / raw)
To: ping.cheng, jason.gerecke, jikos, bentiss
Cc: dmitry.torokhov, linux-input, linux-kernel, stable, Jinmo Yang,
Claude Opus 4.6
wacom_bpt_touch() dereferences both touch_input and pad_input.
wacom_bpt3_touch_msg() dereferences touch_input.
wacom_bpt3_button_msg() dereferences pad_input.
All three can be NULL when the corresponding
wacom_setup_{touch,pad}_input_capabilities() returns -ENODEV during a
successful probe. Add per-function guards.
Fixes: 2a6cdbdd4cc0 ("HID: wacom: Introduce new 'touch_input' device")
Fixes: 862cf5535c0c ("HID: wacom: Introduce a new WACOM_DEVICETYPE_PAD device_type")
Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---
drivers/hid/wacom_wac.c | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index e0bf03123cf9..a34db1505625 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -3151,6 +3151,12 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
if (data[0] != 0x02)
return 0;
+ if (!input || !pad_input) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: input is NULL\n", __func__);
+ return 0;
+ }
+
for (i = 0; i < 2; i++) {
int offset = (data[1] & 0x80) ? (8 * i) : (9 * i);
bool touch = report_touch_events(wacom)
@@ -3185,8 +3191,17 @@ 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]);
+ bool touch;
+ int slot;
+
+ if (!input) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: touch_input is NULL\n", __func__);
+ return;
+ }
+
+ touch = data[1] & 0x80;
+ slot = input_mt_get_slot_by_key(input, data[0]);
if (slot < 0)
return;
@@ -3229,6 +3244,12 @@ 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) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: pad_input is NULL\n", __func__);
+ return;
+ }
+
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
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v3 6/6] HID: wacom: add NULL touch_input guards to remaining touch handlers
2026-10-18 12:47 ` [PATCH v3 0/6] HID: wacom: guard against NULL input devices on successful probe Jinmo Yang
` (4 preceding siblings ...)
2026-10-18 12:47 ` [PATCH v3 5/6] HID: wacom: add NULL input guards to Bamboo touch/button handlers Jinmo Yang
@ 2026-10-18 12:47 ` Jinmo Yang
5 siblings, 0 replies; 36+ messages in thread
From: Jinmo Yang @ 2026-10-18 12:47 UTC (permalink / raw)
To: ping.cheng, jason.gerecke, jikos, bentiss
Cc: dmitry.torokhov, linux-input, linux-kernel, stable, Jinmo Yang,
Claude Opus 4.6
wacom_24hdt_irq() (also handles WACOM_27QHDT), wacom_intuos_pro2_bt_touch(),
and wacom_bamboo_pad_touch_event() dereference wacom->touch_input without
checking it.
As with the other handlers in this series, touch_input can be NULL when
wacom_setup_touch_input_capabilities() returns -ENODEV during an
otherwise successful probe.
Fixes: 2a6cdbdd4cc0 ("HID: wacom: Introduce new 'touch_input' device")
Cc: stable@vger.kernel.org
Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---
drivers/hid/wacom_wac.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index a34db1505625..e3fff2471d43 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -1483,6 +1483,12 @@ static void wacom_intuos_pro2_bt_touch(struct wacom_wac *wacom)
int num_contacts_left = 5;
int i, j;
+ if (!touch_input) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: touch_input is NULL\n", __func__);
+ return;
+ }
+
for (i = 0; i < finger_frames; i++) {
unsigned char *frame = &data[i*finger_frame_len + 109];
int current_num_contacts = frame[0] & 0x7F;
@@ -1654,6 +1660,12 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom)
int byte_per_packet = WACOM_BYTES_PER_24HDT_PACKET;
int y_offset = 2;
+ if (!input) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: touch_input is NULL\n", __func__);
+ return 0;
+ }
+
if (touch_is_muted(wacom) && !wacom->shared->touch_down)
return 0;
@@ -3418,6 +3430,12 @@ static int wacom_bamboo_pad_touch_event(struct wacom_wac *wacom,
int x, y;
bool valid;
+ if (!input) {
+ dev_warn_once(&container_of(wacom, struct wacom, wacom_wac)->hdev->dev,
+ "%s: touch_input is NULL\n", __func__);
+ return 0;
+ }
+
prefix = data[0];
for (id = 0; id < wacom->features.touch_max; id++) {
--
2.53.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
end of thread, other threads:[~2026-10-18 12:48 UTC | newest]
Thread overview: 36+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-23 15:01 [PATCH] HID: wacom: fix NULL pointer dereference in wacom_intuos_pad() Jinmo Yang
2026-05-23 15:06 ` [PATCH v2] " Jinmo Yang
2026-05-23 15:50 ` sashiko-bot
2026-05-29 21:44 ` Dmitry Torokhov
2026-06-10 15:48 ` Jiri Kosina
2026-09-26 18:37 ` Jinmo Yang
2026-09-27 4:11 ` [PATCH 0/5] HID: wacom: check input devices in the report handlers Jinmo Yang
2026-09-27 4:11 ` [PATCH 1/5] HID: wacom: check the input device in the shared report helpers Jinmo Yang
2026-10-17 0:05 ` Jason Gerecke
2026-09-27 4:11 ` [PATCH 2/5] HID: wacom: check the input devices in the legacy irq handlers Jinmo Yang
2026-10-17 0:05 ` Jason Gerecke
2026-09-27 4:11 ` [PATCH 3/5] HID: wacom: check the input device in wacom_intuos_pad() Jinmo Yang
2026-09-27 4:24 ` sashiko-bot
2026-10-17 0:05 ` Jason Gerecke
2026-09-27 4:11 ` [PATCH 4/5] HID: wacom: check the input device in wacom_intuos_bt_irq() Jinmo Yang
2026-10-17 0:05 ` Jason Gerecke
2026-09-27 4:11 ` [PATCH 5/5] HID: wacom: check the input devices in the Bamboo handlers Jinmo Yang
2026-10-17 0:05 ` Jason Gerecke
2026-10-16 9:27 ` [PATCH 0/5] HID: wacom: check input devices in the report handlers Jiri Kosina
2026-10-17 0:05 ` Jason Gerecke
2026-10-18 10:46 ` [PATCH v2 0/5] HID: wacom: guard against NULL input devices on successful probe Jinmo Yang
2026-10-18 10:46 ` [PATCH v2 1/5] HID: wacom: check the input device in the shared report helpers Jinmo Yang
2026-10-18 11:00 ` sashiko-bot
2026-10-18 10:46 ` [PATCH v2 2/5] HID: wacom: check the input devices in the legacy irq handlers Jinmo Yang
2026-10-18 10:53 ` sashiko-bot
2026-10-18 10:46 ` [PATCH v2 3/5] HID: wacom: add NULL pad_input guard to wacom_intuos_pad() Jinmo Yang
2026-10-18 10:46 ` [PATCH v2 4/5] HID: wacom: add NULL input guards to wacom_intuos_bt_irq() Jinmo Yang
2026-10-18 10:46 ` [PATCH v2 5/5] HID: wacom: add NULL input guards to Bamboo touch/button handlers Jinmo Yang
2026-10-18 12:47 ` [PATCH v3 0/6] HID: wacom: guard against NULL input devices on successful probe Jinmo Yang
2026-10-18 12:47 ` [PATCH v3 1/6] HID: wacom: check the input device in the shared report helpers Jinmo Yang
2026-10-18 12:47 ` [PATCH v3 2/6] HID: wacom: check the input devices in the legacy irq handlers Jinmo Yang
2026-10-18 12:47 ` [PATCH v3 3/6] HID: wacom: add NULL pad_input guard to wacom_intuos_pad() Jinmo Yang
2026-10-18 12:47 ` [PATCH v3 4/6] HID: wacom: add NULL input guards to wacom_intuos_bt_irq() Jinmo Yang
2026-10-18 12:47 ` [PATCH v3 5/6] HID: wacom: add NULL input guards to Bamboo touch/button handlers Jinmo Yang
2026-10-18 12:47 ` [PATCH v3 6/6] HID: wacom: add NULL touch_input guards to remaining touch handlers Jinmo Yang
2026-05-23 15:45 ` [PATCH] HID: wacom: fix NULL pointer dereference in wacom_intuos_pad() sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox