Re: [PATCH v2] HID: letsketch: fix UAF on inrange_timer at driver unbind
From: Jiri Kosina
Date: Mon Jun 29 2026 - 04:43:43 EST
On Fri, 15 May 2026, Manish Khadka wrote:
> letsketch_driver does not provide a .remove callback, but
> letsketch_probe() arms a per-device timer:
>
> timer_setup(&data->inrange_timer, letsketch_inrange_timeout, 0);
>
> The timer is re-armed from letsketch_raw_event() with a 100 ms
> timeout on every pen-in-range report, and its callback dereferences
> data->input_tablet to deliver a synthetic BTN_TOOL_PEN release.
>
> letsketch_data is allocated with devm_kzalloc(), and its input_dev
> fields are devm-allocated via letsketch_setup_input_tablet(). On
> device unbind (USB unplug or rmmod), the HID core runs its default
> teardown and devm cleanup frees both letsketch_data and the input
> devices. Because no .remove callback exists, nothing drains the
> timer first: if raw_event armed it within ~100 ms of the unbind,
> the pending timer fires on freed memory. This is a UAF read of
> data and of data->input_tablet, followed by input_report_key() /
> input_sync() into the freed input_dev.
>
> The same problem can occur on the probe error path: if
> hid_hw_start() enabled I/O on an always-poll-quirk device and then
> failed, raw_event may have armed the timer before devm releases
> data.
>
> Fix by adding a .remove callback that calls hid_hw_stop() first.
> hid_hw_stop() synchronously kills the URBs that deliver raw_event(),
> so once it returns no path can re-arm the timer. timer_shutdown_sync()
> then drains any in-flight callback and permanently disables further
> mod_timer() calls. Apply the same timer_shutdown_sync() in the probe
> error path so the timer is guaranteed not to outlive data.
>
> Fixes: 33a5c2793451 ("HID: Add new Letsketch tablet driver")
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Manish Khadka <maskmemanish@xxxxxxxxx>
Applied, thanks.
--
Jiri Kosina
SUSE Labs