Commit Graph

6464 Commits

Author SHA1 Message Date
Derek J. Clark
f27e2e3c80 HID: hid-msi: Add RGB control interface
Adds RGB control interface for MSI Claw devices. The MSI Claw uses a
fairly unique RGB interface. It has 9 total zones (4 per joystick ring
and 1 for the ABXY buttons), and supports up to 8 sequential frames of
RGB zone data. Each frame is written to a specific area of MCU memory by
the profile command, the value of which changes based on the firmware of
the device. Unlike other devices (such as the Legion Go or the OneXPlayer
devices), there are no hard coded effects built into the MCU. Instead,
the basic effects are provided as a series of frame data. I have
mirrored the effects available in Windows in this driver, while keeping
the effect names consistent with the Lenovo drivers for the effects that
are similar.

Initial reverse-engineering and implementation of this feature was done
by Zhouwang Huang. I refactored the overall format to conform to kernel
driver best practices and style guides. Claude was used as an initial
reviewer of this patch.

Assisted-by: Claude:claude-sonnet-4-6
Co-developed-by: Zhouwang Huang <honjow311@gmail.com>
Signed-off-by: Zhouwang Huang <honjow311@gmail.com>
Link: https://patch.msgid.link/20260529072111.7565-4-derekjohn.clark@gmail.com
Signed-off-by: Derek J. Clark <derekjohn.clark@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:41:51 +02:00
Derek J. Clark
93ff13ed1c HID: hid-msi: Add M-key mapping attributes
Adds attributes that allow for remapping the M-keys with up to 5 values
when in macro mode. There are 2 mappable buttons on the rear of the
device, M1 on the right and M2 on the left. When mapped, the events will
fire from one of three event devices: gamepad buttons will fire from the
device handled by xpad, while keyboard and mouse events will fire from
respectively typed evdevs provided by the input core. Names of each
mapping have been kept as close to the event that will fire from the evdev
as possible, with context added to the ABS_ events on the direction of the
movement.

Initial reverse-engineering and implementation of this feature was done
by Zhouwang Huang. I refactored the overall format to conform to kernel
driver best practices and style guides. Claude was used as an initial
reviewer of this patch.

Assisted-by: Claude:claude-sonnet-4-6
Co-developed-by: Zhouwang Huang <honjow311@gmail.com>
Signed-off-by: Zhouwang Huang <honjow311@gmail.com>
Link: https://patch.msgid.link/20260529072111.7565-3-derekjohn.clark@gmail.com
Signed-off-by: Derek J. Clark <derekjohn.clark@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:41:51 +02:00
Derek J. Clark
a9517958e8 HID: hid-msi: Add MSI Claw configuration driver
Adds configuration HID driver for the MSI Claw series of handheld PC's.
In this initial patch add the initial driver outline and attributes for
changing the gamepad mode, M-key behavior, and add a WO reset function.

Sending the SWITCH_MODE and RESET commands causes a USB disconnect in
the device. The completion will therefore never get hit and would trigger
an -EIO. To avoid showing the user an error for every write to these
attrs a bypass for the completion handling is introduced when timeout ==
0.

The initial version of this patch was written by Denis Benato, which
contained the initial reverse-engineering and implementation for the
gamepad mode switching. This work was later expanded by Zhouwang Huang
to include more gamepad modes. Finally, I refactored the drivers data
in/out flow and overall format to conform to kernel driver best
practices and style guides. Claude was used as an initial reviewer of
this patch.

Assisted-by: Claude:claude-sonnet-4-6
Co-developed-by: Denis Benato <denis.benato@linux.dev>
Signed-off-by: Denis Benato <denis.benato@linux.dev>
Co-developed-by: Zhouwang Huang <honjow311@gmail.com>
Signed-off-by: Zhouwang Huang <honjow311@gmail.com>
Signed-off-by: Derek J. Clark <derekjohn.clark@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:41:51 +02:00
Pan Chuang
99e9bd1168 HID: Intel-thc-hid: Remove redundant dev_err()
Since commit 55b48e23f5 ("genirq/devres: Add error handling in
devm_request_*_irq()"), devm_request_threaded_irq() automatically logs
detailed error messages on failure. Remove the now-redundant
driver-specific dev_err() calls.

Signed-off-by: Pan Chuang <panchuang@vivo.com>
Reviewed-by: Even Xu <even.xu@intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:40:44 +02:00
Pan Chuang
978307d016 HID: intel-ish-hid: ipc: Remove redundant dev_err()
Since commit 55b48e23f5 ("genirq/devres: Add error handling in
devm_request_*_irq()"), devm_request_irq() automatically logs
detailed error messages on failure. Remove the now-redundant
driver-specific dev_err() calls.

Signed-off-by: Pan Chuang <panchuang@vivo.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:40:43 +02:00
Pan Chuang
3aeac99bf4 HID: hid-goodix: Remove redundant dev_err()
Since commit 55b48e23f5 ("genirq/devres: Add error handling in
devm_request_*_irq()"), devm_request_threaded_irq() automatically logs
detailed error messages on failure. Remove the now-redundant
driver-specific dev_err() calls.

Signed-off-by: Pan Chuang <panchuang@vivo.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:40:43 +02:00
Pan Chuang
4a3ada659c HID: amd_sfh: Remove redundant dev_err()
Since commit 55b48e23f5 ("genirq/devres: Add error handling in
devm_request_*_irq()"), devm_request_irq() automatically logs
detailed error messages on failure. Remove the now-redundant
driver-specific dev_err() calls.

Signed-off-by: Pan Chuang <panchuang@vivo.com>
Acked-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:40:43 +02:00
Benjamin Blume
663870a84c HID: hyperx: add driver for the HyperX QuadCast 2 mute button
The tap-to-mute button of the HyperX QuadCast 2 (03f0:07b4) is handled
entirely in the device firmware.  The firmware gates the audio internally
but never sends the Telephony "Phone Mute" usage (0x2f) that its own report
descriptor advertises, and it does not touch the UAC feature unit either.
Consequently neither an evdev key event nor an ALSA mixer change is ever
generated, and userspace has no way to learn that the microphone was muted:
desktops keep showing the microphone as live, and conferencing applications
keep displaying an unmuted microphone while transmitting silence.

The mute state is reported through a vendor-defined collection instead:

  06 c0 ff        Usage Page (Vendor-Defined 0xFFC0)
  a1 01           Collection (Application)
  06 c1 ff          Usage Page (Vendor-Defined 0xFFC1)
  85 77             Report ID (0x77)
  09 f0             Usage (0xF0)
  75 08  95 3f      Report Size (8), Report Count (63)
  81 02             Input (Data,Var,Abs)

Pressing the button emits a 64-byte report on that collection:

  77 06 00 00 ...   microphone unmuted
  77 06 01 00 ...   microphone muted

where byte 1 identifies the mute event and byte 2 carries the resulting
state.  As the payload is an opaque vendor blob carrying no HID usages,
hid-input cannot map it and a hwdb entry cannot express it either.

Add a driver that decodes the report and emits KEY_MICMUTE, which makes the
button behave like any other microphone mute key.

Note that the device reports the resulting absolute state, whereas
KEY_MICMUTE is a momentary key that userspace acts on as a toggle, so the
driver emits one keypress per state change.

Tested on a HyperX QuadCast 2 (03f0:07b4).

Signed-off-by: Benjamin Blume <benjaminblume@posteo.de>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:38:55 +02:00
Sriman Achanta
83e70ced0d HID: steelseries: Add support for Arctis Nova 5X and Nova 7 families
The Arctis Nova 5X, Nova 7 Gen2, and Nova 7 2026 refresh headsets answer
status polls, but also send unsolicited battery and connection updates
on a second HID interface (interface 5). Use that interface through
async_interface so the driver does not have to poll. Add request and
parse helpers for the Nova status format (0xb0/0xb7/0xb9/0xbb opcodes).

The original (pre-Gen2) Arctis Nova 7 family answers the same status
opcodes on the same interfaces, but reports battery capacity as a
discrete 0-4 level instead of a raw percentage. Add a second parse
function that maps that level through steelseries_map_capacity(), and a
separate device_info so the two capacity encodings cannot get mixed up.

Add the fourteen USB product IDs that share these protocols:

  0x2253  Arctis Nova 5X
  0x2202  Arctis Nova 7
  0x2206  Arctis Nova 7X
  0x22a4  Arctis Nova 7X (alternate PID)
  0x223a  Arctis Nova 7 Diablo
  0x227a  Arctis Nova 7 World of Warcraft Edition
  0x22a1  Arctis Nova 7 2026
  0x22a7  Arctis Nova 7P 2026
  0x22a5  Arctis Nova 7X 2026
  0x22a9  Arctis Nova 7 Diablo 2026
  0x227e  Arctis Nova 7 Gen 2
  0x2258  Arctis Nova 7X Gen 2
  0x229e  Arctis Nova 7X Gen 2 (alternate PID)
  0x22ad  Arctis Nova 7X Gen 2 (alternate PID)

Signed-off-by: Sriman Achanta <srimanachanta@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:31:55 +02:00
Sriman Achanta
bebeca20ab HID: steelseries: Add async status interface support
Some headsets expose a second HID interface that sends battery and
connection updates on its own. Watching that interface lets the driver
stop polling the sync interface. Add a
steelseries_device_info::async_interface field and the code to handle
it:

  - The driver binds both the sync and async interfaces. The async
    interface shares the steelseries_device created by the sync
    interface. It finds the sibling with usb_ifnum_to_if(), and before
    trusting its intfdata it rejects non-HID siblings by descriptor
    class and holds the sibling's device lock across the lookup, so a
    crafted device cannot cause a type-confused read and a concurrent
    unbind cannot free the hid_device from under it. It then takes a
    reference and returns -EPROBE_DEFER until the sync interface has
    probed. If the sync interface never binds, the async interface
    defers forever, which is fine here.
  - raw_event() now holds sd->lock and re-checks sd->removed so events
    on either interface are serialised against removal.
  - status_work runs once for async devices instead of rearming. A
    single status request is sent when the headset connects to get the
    initial battery level.

No device sets async_interface yet. This is the infrastructure for the
next commit.

Signed-off-by: Sriman Achanta <srimanachanta@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:31:55 +02:00
Sriman Achanta
9bc171302f HID: steelseries: Manage battery lifetime with refcounting
The next change shares one steelseries_device between two HID
interfaces, so the state can outlive either interface. Stop using devm
for it. Reference count the struct with a kref and free it from
steelseries_device_release(). Register and unregister the power supply
explicitly, and clear sd->battery under sd->lock in remove() so it is
not touched after it is unregistered.

Drop the global atomic battery counter and name the power supply after
the device (hdev->uniq, or dev_name() when empty), as hid-input and the
other HID battery drivers do.

No functional change for the current single-interface devices.

Signed-off-by: Sriman Achanta <srimanachanta@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:31:55 +02:00
Sriman Achanta
b8ae111432 HID: steelseries: Correct Arctis 9 battery calibration range
Map the Arctis 9 raw battery value over 0x64 (empty) to 0x9a (full)
instead of 0x68 to 0x9d. These values match the HeadsetControl project
[1] and fit the calibration points from an independent reverse
engineering of the battery tray (about 25% at raw 112, 50% at raw 125)
[2].

I do not have this headset. The values come from those references and
were not measured directly.

[1] https://github.com/Sapd/HeadsetControl/blob/master/lib/devices/steelseries_arctis_9.hpp
[2] https://magnier.io/reverse-engineering-arctis-9-battery-tray/

Signed-off-by: Sriman Achanta <srimanachanta@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:31:55 +02:00
Sriman Achanta
06529560b0 HID: steelseries: Report POWER_SUPPLY_STATUS_FULL when full
Report POWER_SUPPLY_STATUS_FULL when the headset is connected, charging,
and at 100% capacity. It reported CHARGING in that case before.

The charging flag doubles as a power-present signal: the headset keeps
reporting charging while it sits docked at 100%, and clears the flag as
soon as it runs on battery. Gating FULL on the charging flag therefore
avoids reporting FULL for an unplugged headset that merely happens to be
at 100%, which would otherwise hide the discharge state from userspace.

Signed-off-by: Sriman Achanta <srimanachanta@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:31:55 +02:00
Sriman Achanta
49ef6ed1bb HID: steelseries: Refactor Arctis driver to use device_info framework
Replace the per-product if/else quirk bitmap with a
steelseries_device_info struct. Each model provides its capabilities,
sync_interface, and request_status/parse_status callbacks. Report
sending is folded into steelseries_send_report() and the feature and
output wrappers, and the battery identifiers lose their per-model names.

This is mostly a refactor, but it changes two things:

  - Battery status is polled from a periodic delayed work (status_work)
    instead of being requested from raw_event(). The interval stays at
    3s.
  - Arctis 1 no longer clamps the reported capacity to 100% while
    disconnected. The connection state already controls how this is
    shown to userspace.

ARCTIS_1_X and ARCTIS_9 keep working. No new devices are added.

Signed-off-by: Sriman Achanta <srimanachanta@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:31:55 +02:00
Sriman Achanta
3d569aafe3 HID: steelseries: Split Arctis headset driver into separate module
Move all Arctis headset code (battery monitoring, wireless status,
power supply registration, raw event handling) from hid-steelseries.c
into the new hid-steelseries-arctis.c driver module.

hid-steelseries.c keeps the SRWS1 racing wheel and the MSI RGB LED
devices, while hid-steelseries-arctis.c handles the Arctis 1 (Xbox) and
Arctis 9 wireless headsets with their own device table, probe, remove,
and raw_event implementations.

Signed-off-by: Sriman Achanta <srimanachanta@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:31:55 +02:00
Sriman Achanta
44300576b5 HID: steelseries: Fix ARCTIS_1_X device mislabeling
The SteelSeries Arctis 1 Wireless for Xbox (0x12b6) was labelled as the
plain Arctis 1 Wireless. Rename USB_DEVICE_ID_STEELSERIES_ARCTIS_1 to
USB_DEVICE_ID_STEELSERIES_ARCTIS_1_X, along with the matching quirk flag
and device table entry. The device ID value is unchanged.

Signed-off-by: Sriman Achanta <srimanachanta@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:31:55 +02:00
Christopher Kodama
4253fe22b1 HID: magicmouse: re-enable multitouch after reset-resume
When the Apple Magic Trackpad 2 (USB) is reset across a power transition
(e.g. resume from hibernation) it drops out of multitouch mode: it keeps
sending report ID 0x02 on its HID_TYPE_USBMOUSE interface, but the packet
shrinks from 21 to 8 bytes and the trackpad2 handler drops it (size < 12).
Clicks still work but pointer motion is lost until the device is re-plugged
or the driver reloaded.

Re-enable multitouch from .reset_resume via the workqueue.  Only
.reset_resume is needed; suspend-to-idle keeps the device powered and
retains multitouch.

Fixes: 87a2f10395 ("HID: magicmouse: Apple Magic Trackpad 2 USB-C driver support")
Cc: stable@vger.kernel.org
Assisted-by: Claude-Code:claude-opus-4-8
Signed-off-by: Christopher Kodama <ckhordiasma@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:27:06 +02:00
Jiancheng Huang
be00988cce HID: lg4ff: validate report length before fixed offsets
lg4ff_raw_event() rewrites fixed report offsets when combined pedals are
enabled. It currently assumes that each product report contains every
source and destination byte used by the rewrite.

Return without rewriting a short report before each product-specific
access. Apply the same bound to the computed offset path.

Fixes: c832f86eff ("HID: hid-logitech: Add combined pedal support Logitech wheels")
Signed-off-by: Jiancheng Huang <jchuang@seu.edu.cn>
Assisted-by: Codex:gpt-5.6-luna
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:24:06 +02:00
Chen Changcheng
eb51c9f8cb HID: corsair: cancel worker before unregistering LED to fix use-after-free
The cleanup functions k90_cleanup_backlight() and
k90_cleanup_macro_functions() call led_classdev_unregister() before
cancel_work_sync():

    led_classdev_unregister()     <-- may free led->cdev.dev
    cancel_work_sync()            <-- wait for worker

If the LED worker (k90_backlight_work / k90_record_led_work) is
already running on another CPU, the following race can occur:

    CPU 1 (worker)               CPU 2 (remove)
    ---------------------         --------------------
    if (led->removed) -> false
    (passed the guard, about to read led->cdev.dev)
    * preempted
                                   removed = true
                                   led_classdev_unregister()
                                     -> led->cdev.dev freed
                                   cancel_work_sync()
                                     -> waits for worker
    * resumes
    dev = led->cdev.dev->parent   <-- UAF!

Fix by swapping the order so that the worker is cancelled first:

    cancel_work_sync()            <-- wait for worker first
    led_classdev_unregister()     <-- then safe to unregister

The removed flag is set before cancel_work_sync() so that if
led_classdev_unregister() internally triggers another brightness
update (which re-schedules the work), the worker will see the flag
and return immediately.

Signed-off-by: Chen Changcheng <chenchangcheng@kylinos.cn>
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:22:08 +02:00
Chen Changcheng
9405601fb7 HID: corsair: fix use-after-free by reordering remove sequence
The corsair_remove() function currently frees the k90 driver data before
calling hid_hw_stop().  Since hid_hw_stop() stops HID I/O, the event
callback corsair_event() can still be invoked between the kfree() and
hid_hw_stop(), and will dereference the freed drvdata->k90 pointer to
write record_led.brightness.

Reorder the remove sequence so that hid_hw_stop() is called first.
Once hid_hw_stop() completes, the HID device is disconnected and no
URBs are active, so corsair_event() cannot fire anymore.  The driver
data is freed only afterwards.

Additionally, set drvdata->k90 to NULL after kfree() as a defensive
measure, matching the existing pattern in the error path of
k90_init_macro_functions().

Signed-off-by: Chen Changcheng <chenchangcheng@kylinos.cn>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:22:08 +02:00
Yuxiang Lin
2884e21b18 HID: quirks: add ALWAYS_POLL quirk for AULA Mini 60 HE Pro Dongle
The AULA Mini 60 HE Pro wireless keyboard dongle (USB ID
0c45:fefe) becomes unresponsive after roughly one minute of idle.
No error appears in dmesg; the only recovery is physically
replugging the dongle.

This has been reproduced across kernels 6.8, 6.14 and 7.1.3.

Testing shows HID_QUIRK_ALWAYS_POLL alone resolves the issue,
verified via usbhid.quirks=0x0c45:0xfefe:0x400.

Signed-off-by: Yuxiang Lin <mclyxfdw@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:20:51 +02:00
Chao Huang
8e2c560fae HID: i2c-hid: goodix: Disable VDD on VDDIO enable failure
If enabling VDDIO fails after VDD has been enabled, the power-up
path returns without disabling VDD. This leaves the regulator enabled
and its enable count unbalanced.

Disable VDD before returning the VDDIO error.

Fixes: eb16f59e8e ("HID: i2c-hid: goodix: Add mainboard-vddio-supply")
Signed-off-by: Chao Huang <huangchao@kylinos.cn>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:19:28 +02:00
Konrad Dybcio
2061075360 HID: asus: support the Zenbook A16 (UX3607OA) keyboard
The ASUS Zenbook A16 (UX3607OA), a Qualcomm Snapdragon X2 Elite Extreme
(Glymur)-based laptop, carries its main keyboard on an I2C-HID device
with the ID 0B05:4B42. Its Fn/media hotkeys are emitted as vendor-page
(HID_UP_ASUSVENDOR) usages on report 0x5A.

Match the device in hid-asus with the standard I2C keyboard quirks and
add the three usage mappings observed on the hardware:

  0x85 -> KEY_CAMERA  (Fn+F11, camera toggle)
  0x86 -> KEY_PROG1   (Fn+F12, MyASUS key)
  0x5f -> KEY_PROG2   (extra programmable key)

The camera-toggle key reports its usage (0x85) together with a companion
state byte in the same array report ("5a 85 01" / "5a 85 10"). The 0x10
companion aliases the brightness-down vendor usage and spuriously dims
the panel, so add QUIRK_FILTER_CAMERA_COMPANION to zero the companion
slots for this device before input mapping. The quirk is device-gated so
no other ASUS model is affected.

Assisted-by: Claude Code:claude-opus-4-8
Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:17:36 +02:00
Aaron Ma
bfff246b3a HID: quirks: Add ALWAYS_POLL quirk for Beitong BTP-KP20D dongle
The BTP-KP20D dongle in Direct/HID mode (20dd:5159) re-enumerates every
few seconds because usbhid never submits its interrupt-IN URB: no HID
driver binds to the vendor-specific report descriptor, so the device is
never opened, and the firmware treats the idle endpoint as a lost link.

Add HID_QUIRK_ALWAYS_POLL to keep the interrupt-IN URB submitted from
probe time.

Signed-off-by: Aaron Ma <mapengyu@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:16:20 +02:00
Michael Bommarito
83df7b5fa6 HID: hyperv: add KUnit coverage for device info bounds
Add KUnit coverage for Hyper-V synthetic HID initial device-info parsing.
The tests cover zero bLength, a valid descriptor plus report descriptor,
and a malformed report descriptor length that exceeds the received
message.

The same-translation-unit test uses a KUnit-only ACK bypass so parser
coverage does not require a live VMBus channel.

Assisted-by: Codex:gpt-5-5-xhigh
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:09:48 +02:00
Michael Bommarito
934b7778aa HID: hyperv: validate initial device info bounds
The Hyper-V synthetic HID host supplies SYNTH_HID_INITIAL_DEVICE_INFO
messages that contain a HID descriptor followed by the report descriptor
bytes. mousevsc_on_receive_device_info() trusts bLength and
wDescriptorLength without checking that the received packet contains both
byte ranges.

A malformed host or backend message can therefore make the guest read
past the received VMBus packet while copying the report descriptor. Pass
the received initial-device-info size into the parser and reject
descriptor lengths that exceed the packet.

Impact: A malicious Hyper-V host or backend can crash a guest by sending
a short initial device-info message with an oversized HID report
descriptor length.

Fixes: b95f5bcb81 ("HID: Move the hid-hyperv driver out of staging")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5-5-xhigh
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:09:48 +02:00
Rosalie Wanders
091c05c184 HID: sony: add missing __packed to struct with static_assert()
Fixes: 4b9c410e7d ("HID: sony: fix style issues")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202607091026.R9Pxd3PG-lkp@intel.com/
Signed-off-by: Rosalie Wanders <rosalie@mailbox.org>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:07:20 +02:00
Marco Crivellari
26829c0aea HID: appletb-kdb: Replace system_wq with system_dfl_wq
Currently the code enqueue work items using mod_delayed_work(), using
system_wq, the old per-CPU Workqueue.

The function end up calling __queue_delayed_work(), which set a global
timer that could fire anywhere, enqueuing the work where the timer fired.

Unbound works could benefit from scheduler task placement, to optimize
performance and power consumption.

Since the workqueue work doesn't rely on per-cpu variables, there is no
obvious reason that justify the use of a per-cpu workqueue. So change the
workqueue with the new unbound version, system_dfl_wq.

Signed-off-by: Marco Crivellari <marco.crivellari@suse.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:04:10 +02:00
Marco Crivellari
8bb7c0fdfc HID: hid-oxp: Replace system_wq with system_dfl_wq
The function end up calling __queue_delayed_work(), which set a global
timer that could fire anywhere, enqueuing the work where the timer fired.

Unbound works could benefit from scheduler task placement, to optimize
performance and power consumption.

Since the workqueue work doesn't rely on per-cpu variables, there is no
obvious reason that justify the use of a per-cpu workqueue. So change the
workqueue with the new unbound version, system_dfl_wq.

Cc: Derek J. Clark <derekjohn.clark@gmail.com>
Signed-off-by: Marco Crivellari <marco.crivellari@suse.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:04:10 +02:00
Andrei Fed
a1556b48ef HID: magicmouse: fix battery reporting for Bluetooth Magic Trackpad USB-C
The Apple Magic Trackpad 2 (USB-C) reports a wildly wrong battery
capacity over Bluetooth, for example a constant 4% for a pack that is
actually at 74%.

The device's battery input report (0x90) is laid out as
[report-id][status][charge]. hid-input's synchronous capacity query,
hidinput_query_battery_capacity(), assumes the common
[report-id][capacity] layout and returns buf[1], which for this device
is the status byte rather than the charge (buf[2]).

magicmouse_fetch_battery(), which requests the battery report through
hid_hw_request() so the reply is decoded via the report descriptor at
the correct field offset, is gated to the USB models and never runs
over Bluetooth. The device does not push battery reports on its own
either, except a single one at connect time, which is delivered while
probe holds driver_input_lock and is silently dropped. All userspace
reads therefore go through the misparsing query, and the device is
stuck reporting its status byte as the capacity.

Enabling the fetch for Bluetooth is not sufficient on its own: user
space reacts to the power_supply registration immediately, so a query
is typically already in flight when the fetch reply is parsed.
hidinput_get_battery_property() stores the query result and marks the
battery as queried without rechecking whether a report arrived while
it was waiting, clobbering the just-reported correct value with the
misparsed one.

Fix this by adding HID_BATTERY_QUIRK_AVOID_QUERY for the Bluetooth
Magic Trackpad USB-C so the misparsing query path is never used, and
by fetching the battery at the end of probe for this device. hidp has
no asynchronous request() callback, so the fetch is serviced
synchronously via __hid_request() while probe still holds
driver_input_lock; call hid_device_io_start() first so the reply is
processed instead of being discarded.

Tested with a Magic Trackpad USB-C (004c:0324) over Bluetooth on
6.18.37: the reported capacity now matches the device (verified against
a raw GET_REPORT of report 0x90) and updates on reconnect.

Fixes: 87a2f10395 ("HID: magicmouse: Apple Magic Trackpad 2 USB-C driver support")
Cc: stable@vger.kernel.org
Signed-off-by: Andrei Fed <andfed.net@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:02:55 +02:00
Vicki Pfau
fcfa7db89f HID: steam: Retry send/recv reports if stale
Sometimes recv report will reply with a stale result from a previous send
report. Instead of failing out, we should retry them, as they generally
reply correctly after three tries, give or take.

Signed-off-by: Vicki Pfau <vi@endrift.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:00:27 +02:00
Vicki Pfau
33ff7b49c3 HID: steam: Reject short reads
Steam Controller FEATURE reports encode the size of the message in the
message itself. Previously we were trusting that the size reported matched
the size we actually read, leading to a potential issue with short reads.
Instead, we should actually verify the length of the read.

Fixes: c164d6abf3 ("HID: add driver for Valve Steam Controller")
Reported-by: syzbot+75f3f9bff8c510602d36@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=75f3f9bff8c510602d36

Signed-off-by: Vicki Pfau <vi@endrift.com>
Link: https://syzkaller.appspot.com/bug?extid=75f3f9bff8c510602d36
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:00:27 +02:00
Vicki Pfau
9f8ee99f83 HID: steam: Zero-initialize reply in serial lookup
When requesting the serial number from a controller, the function will do
some basic bounds checking to make sure the reply is valid, as well as
capping off the reply with a null byte before copying. However, the error
logging can leak uninitialized memory in some cases. We can simplify and
solve this by just zero-initalizing the reply memory eagerly instead.

Signed-off-by: Vicki Pfau <vi@endrift.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:00:27 +02:00
Vicki Pfau
de435b770c HID: steam: Improve logging and other cleanup
Adds more logging as appropriate, reindents an enum to match surrounding
style, as well as cleaning up some places where we can use guard() instead
of doing locking and unlocking manually.

Signed-off-by: Vicki Pfau <vi@endrift.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:00:27 +02:00
Vicki Pfau
ddce9641ce HID: steam: Rearrange teardown sequence
This fixes a narrow window during the teardown sequence where callbacks
could still be scheduled during cleanup that would then have a dangling
pointer to the now-freed steam struct.

This also puts work canceling for rumble and mode switch in
steam_unregister, as that shouldn't persist while the client hdev is open.

Signed-off-by: Vicki Pfau <vi@endrift.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:00:27 +02:00
Vicki Pfau
cd33a91d37 HID: steam: Fully unregister controller when hidraw is opened
To avoid conflicts between anything touching the hidraw and the driver we
had previously detached the evdev nodes when the hidraw is opened. However,
this isn't sufficient to avoid FEATURE reports from conflicting, so we
change to fully unregistering the controller internally, leaving only the
hidraw active until it's closed.

This also unifies the unregister and connect callbacks, as now the logic
between these two callbacks is identical.

Signed-off-by: Vicki Pfau <vi@endrift.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:00:27 +02:00
Vicki Pfau
1d4549fd11 HID: steam: Coalesce rumble packets
The Steam Deck resets the haptic pattern every time it receives a rumble
packet, leading to weird discontinuities or sometimes cutting out entirely.
Instead of overloading the interface, Steam interally rate-limits sending
these packets, so we should too.

Signed-off-by: Vicki Pfau <vi@endrift.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:00:26 +02:00
Vicki Pfau
2eb7cf02b5 HID: steam: Add support for sensor events on the Steam Controller (2015)
Sensor support was added for the Steam Deck previously, but Steam
Controller sensor events were never added. This adds that missing support,
bringing Steam Controller support much closer to feature parity with things
like SDL and Steam itself.

Signed-off-by: Vicki Pfau <vi@endrift.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:00:26 +02:00
Vicki Pfau
6afec3c8ff HID: steam: Rename some constants that got renamed upstream
SETTING_MOUSE_POINTER_ENABLED was renamed to SETTING_LIZARD_MODE upstream.
SETTING_GYRO_MODE was renamed to SETTING_IMU_MODE in an older commit, but
the associated enum was overlooked.

Signed-off-by: Vicki Pfau <vi@endrift.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:00:26 +02:00
Vicki Pfau
3d3c6ab5b0 HID: steam: Refactor and clean up report parsing
This switches from a parsing style where each button or axis is parsed
individually out of a report using !!(byte & BIT(x)) style. This commit
switches it to a mostly unified approach of defining a list of individual
mappings in an array and passing it to a function that handles all of the
extraction. Theoretically this is more lines, but in practice it results in
(subjectively) cleaner code. Some exceptions still need to be made for
things like handling the lizard mode toggle key, but in general there's a
lot less manual code.

Signed-off-by: Vicki Pfau <vi@endrift.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:00:26 +02:00
Vicki Pfau
749111cf5c HID: steam: Update documentation
Mark myself as the maintainer, as well as adding myself as an author.

It also makes some minor updates to comments, such as correcly calling the
left menu key view and retroactively renaming the original Steam Controller
as Steam Controller (2015), in preparation for support for the 2026 model.

Signed-off-by: Vicki Pfau <vi@endrift.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 21:00:26 +02:00
Xu Rao
bbff0ccbff HID: roccat: free buffered reports when destroying device
roccat_report_event() duplicates each report with kmemdup() and stores
the allocation in a circular-buffer slot. The allocation is released only
when that slot is reused.

The device destruction paths free struct roccat_device without releasing
reports still stored in cbuf[]. This makes those allocations unreachable
and leaks up to ROCCAT_CBUF_SIZE report buffers per device.

Add a small destructor that frees every buffered report before freeing the
device, and use it in both paths that can destroy a registered device.

Fixes: 206f5f2fcb ("HID: roccat: propagate special events of roccat hardware to userspace")
Cc: stable@vger.kernel.org
Signed-off-by: Xu Rao <raoxu@uniontech.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 20:54:50 +02:00
Even Xu
b6fc74d818 HID: Intel-thc-hid: Intel-quickspi: Refine recover callback
Refine recover flow:
1. Use workqueue to handle recover flow instead of processing in irq
   handler.
2. Call thc_rxdma_reset() API to simplify the recover operation.
3. Disable interrupt during whole recover flow.
4. If recover fails, disable interrupt to avoid interrupt storm.

Signed-off-by: Even Xu <even.xu@intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 20:53:29 +02:00
Even Xu
2e045a140c HID: Intel-thc-hid: Intel-quicki2c: Refine recover callback
Refine recover flow:
1. Use workqueue to handle recover flow instead of processing in irq
   handler.
2. Call thc_rxdma_reset() API to simplify the recover operation.
3. Disable interrupt during whole recover flow.
4. If recover fails, disable interrupt to avoid interrupt storm.

Signed-off-by: Even Xu <even.xu@intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 20:53:29 +02:00
Even Xu
1d46b8d406 HID: Intel-thc-hid: Intel-thc: Add API to reset read DMA
Add a helper function thc_rxdma_reset() to do read DMA reset, it can be
called when fatal DMA error happens.

Signed-off-by: Even Xu <even.xu@intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 20:53:29 +02:00
Ai Chao
8da0f0951d HID: i2c-hid: Fix "(null)" output when reading report descriptor fails
When i2c-hid fails to read the HID report descriptor during device
initialization, the error message prints as:

  hid (null): reading report descriptor failed

The HID device name is set in hid_add_device() after calling
hdev->ll_driver->parse(), so when i2c_hid_parse() fails and calls
hid_err(), the device name has not been set yet, resulting in "(null)"
output.

Use dev_err(&client->dev, ...) instead of hid_err(hid, ...) because
the I2C client device is fully initialized with a proper name, providing
meaningful error messages for debugging.

Before: hid (null): reading report descriptor failed
After:  i2c_hid i2c-TPD0001:00: reading report descriptor failed

Fixes: 4a200c3b9a ("HID: i2c-hid: introduce HID over i2c specification implementation")

Signed-off-by: Ai Chao <aichao@kylinos.cn>
Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 20:52:06 +02:00
Colin Blower
f70a82e20d HID: logitech-dj: Add support for G915 TKL receiver 0xc545
The Logitech G915 TKL has a lightspeed receiver with a product id of
0xc545. This receiver seems to behave like 0xc547 receiver.

Add a definition for this new receiver id and a mapping for the
recvr_type_gaming_hidpp_ls_1_3 type, the receiver now reports battery
status of the connected keyboard.

Signed-off-by: Colin Blower <colin@1101b.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 20:46:07 +02:00
Michal Slustik
d1637ff784 HID: apple: Add Endorfy Thock TKL Wireless to the non-apple keyboard list
The Endorfy Thock TKL Wireless uses the same device ID as an
Apple keyboard (05ac:024f), but its F1-F12 function keys do
not work correctly by default.

Adding two entries to the non-apple keyboard list:
one for Bluetooth mode, identified as "Thock TKL Wireless"
one for 2.4GHz wireless mode, identified as "USB Dongle"

Signed-off-by: Michal Slustik <michal.slustik@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 20:43:53 +02:00
Jann Horn
28abce9513 HID: core: fix number/pointer type confusion on long items
When fetch_item() is called by hid_scan_report() on an item with
HID_ITEM_TAG_LONG, it stores a pointer to the item data in
item->data.longdata instead of storing a value directly in
item->data.{u8/u16/u32}.

When item_udata() or item_sdata() encounters such an item, it incorrectly
assumes that the item is in short format, and therefore returns the lower
part of a kernel pointer reinterpreted as a number.

When a HID device is connected whose descriptor contains a
HID_GLOBAL_ITEM_TAG_REPORT_SIZE encoded in long format with size=4, this
causes the lower half of a kernel pointer to be printed into dmesg as a
number, like this:

    hid (null): invalid report_size 107953555

To fix it, let item_udata() and item_sdata() verify that the item is in
short format.

Note that this bug only affects hid_scan_report(), while the main parsing
pass hid_parse_collections() will always bail out when encountering a long
item.

Sidenote: There are currently no users of data.longdata; maybe we should
just remove any parsing of long-format descriptors as a follow-up.

Fixes: 3dc8fc083d ("HID: Use hid_parser for pre-scanning the report descriptors")
Cc: stable@vger.kernel.org
Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 20:42:47 +02:00
Jann Horn
b57af24482 HID: rapoo: fix missing hid_is_usb() check
to_usb_interface() can only be used on a hid_device whose parent is really
USB; uhid can create devices that identify as being on BUS_USB, but don't
actually have a USB parent.
Fix the use of to_usb_interface() without a hid_is_usb() check.

Add a dependency on USB_HID for hid_is_usb(), as other HID drivers do; the
alternative would be to provide a simple stub implementation on !USB_HID
builds.

I have verified that it is currently possible to trigger a kernel splat due
to this bug in an ASAN build, and that this commit fixes the issue.

Fixes: b3b1c68fb7 ("HID: rapoo: Add support for side buttons on RAPOO 0x2015 mouse")
Cc: stable@vger.kernel.org
Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 20:42:08 +02:00
Jann Horn
4cdb6b4b34 HID: huawei: fix missing hid_is_usb() check
to_usb_interface() can only be used on a hid_device whose parent is really
USB; uhid can create devices that identify as being on BUS_USB, but don't
actually have a USB parent.
Fix the use of to_usb_interface() without a hid_is_usb() check.

I have verified that it is currently possible to trigger a kernel splat due
to this bug in an ASAN build, and that this commit fixes the issue.

Fixes: e93faaca84 ("HID: huawei: fix CD30 keyboard report descriptor issue")
Cc: stable@vger.kernel.org
Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 20:42:08 +02:00
Jann Horn
02bf61dfb4 HID: asus: fix missing hid_is_usb() check
to_usb_interface() can only be used on a hid_device whose parent is really
USB; uhid can create devices that identify as being on BUS_USB, but don't
actually have a USB parent.
Fix the use of to_usb_interface() without a hid_is_usb() check.

I have verified that it is currently possible to trigger a kernel splat due
to this bug in an ASAN build, and that this commit fixes the issue.

Fixes: 00e005c952 ("hid-asus: check ROG Ally MCU version and warn")
Cc: stable@vger.kernel.org
Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 20:42:07 +02:00
Jose Villaseñor Montfort
d07644524b HID: input: read battery capacity from its actual report offset
hidinput_query_battery_capacity() assumes the state-of-charge value is
the first byte following the report ID (buf[1]) and ignores where the
battery field actually sits within the report.

An Apple Magic Trackpad 2 precedes the AbsoluteStateOfCharge byte with a
byte of status flags in its battery reports, so this query returns the
flags byte instead of the charge level.

The device happens to make that easy to observe, because it exposes the
same cell twice: its report descriptor declares AbsoluteStateOfCharge in
two reports (0x90 and 0x9b), so hidinput_setup_battery() registers two
power supplies. Only the first one is refreshed by hid-magicmouse -- it
uses hid_get_battery(), which returns the first battery of the list --
and that refresh goes through the report event path, which parses the
field correctly. Nothing ever reports the second one, so every read of
its capacity takes the query path above. On a USB-C Magic Trackpad over
USB, on an unpatched 7.1.5:

  hid-<serial>-battery-144 = 100%  (Charging)      <- report event path
  hid-<serial>-battery-155 =   3%  (Discharging)   <- query path

Both are the same physical battery. A raw HIDIOCGINPUT of the two
reports at that same moment:

  report 0x90 -> [90 03 64]
  report 0x9b -> [9b 03 64 64 00 00 10 00 00 00 00 00 00 00]
                     ^flags ^SoC = 0x64 = 100%

The device answers correctly in both cases; only the offset the kernel
reads the capacity from is wrong. 0x03 is the flags byte (present,
charging), reported as "3%".

Bluetooth takes the same query path for its capacity, where the trackpad
reported a bogus near-constant ~4% -- 0b100, the FullyCharged flag --
regardless of the real charge.

Store the battery field's offset within the report at setup time and use
it when querying, so the capacity is read from its real position. The
report event path already parses the field correctly through the HID
core; only the explicit GET_REPORT query was wrong.

Devices whose capacity field is the first field in the report have a
report_offset of 0 and are unaffected (buf[1 + 0] == buf[1]).

Fixes: 581c448476 ("HID: input: map digitizer battery usage")
Cc: stable@vger.kernel.org
Signed-off-by: Jose Villaseñor Montfort <pepemontfort@gmail.com>
Reviewed-by: Alec Hall <signshop.alec@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 20:38:09 +02:00
Elliot Douglas
81a2f7801c HID: logitech-hidpp: enable reprogrammable buttons on Signature M650
The Bluetooth Signature M650 exposes its side buttons through the normal
mouse report, but the observed events are short click-like events emitted
around release rather than physical press/release state.

The device appears to use the held side-button state for its built-in
gesture and side-button + wheel horizontal-scroll mode. As a result,
holding a side button long enough can prevent the normal mouse report from
emitting a usable button event at all.

HID++ REPROG_CONTROLS_V4 diversion for control IDs 0x0053 and 0x0056
provides real press and release timing for those same controls. Logitech
documents the Signature M650 side buttons as Back/Forward buttons, so
report the diverted controls as BTN_BACK and BTN_FORWARD.

The HID++ 0x1b04 documentation lists those control IDs as Back and
Forward. The driver still verifies that the controls are present in the
device control table and advertised as divertable before changing their
reporting mode.

Link: https://support.logi.com/hc/en-nz/articles/4414473810583-Getting-Started-Signature-M650
Signed-off-by: Elliot Douglas <edouglas7358@gmail.com>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 20:36:20 +02:00
Elliot Douglas
5e21032ac9 HID: logitech-hidpp: add HID++ 2.0 reprogrammable button support
Some Logitech HID++ 2.0 mice can report diverted reprogrammable controls
through HID++ feature 0x1b04, SpecialKeysMseButtons / REPROG_CONTROLS_V4,
instead of the normal HID mouse report.

Add a quirk-gated event path for those controls. The handler temporarily
diverts verified per-product controls, parses divertedButtonsEvent as the
current pressed-control list, and reports the corresponding evdev key state
for every mapped control.

Keep the control mappings in per-product arrays so adding support for
another mouse does not change the evdev capabilities advertised by
already-supported devices.

Documentation for feature 0x1b04 describes divertedButtonsEvent as a list
of currently pressed diverted buttons, which is the event format handled
here.

Link: https://lekensteyn.nl/files/logitech/x1b04_specialkeysmsebuttons.html
Signed-off-by: Elliot Douglas <edouglas7358@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 20:36:20 +02:00
Jiangshan Yi
d723bc1fe2 HID: nintendo: register input device after capabilities are set
input_register_device() exposes the device to userspace immediately.
In joycon_input_create() it was called before joycon_config_rumble()
configures the FF_RUMBLE capability and the memless force-feedback
device, so a concurrent EVIOCSFF could dereference a NULL dev->ff.

Registering early also means the initial udev event lacks button and
axis information, which can make input managers ignore the device.

Move input_register_device() to the end of joycon_input_create(), after
all capabilities, the IMU input device and the force-feedback callbacks
have been configured.

Fixes: 2af16c1f84 ("HID: nintendo: add nintendo switch controller driver")
Reported-by: sashiko-bot@kernel.org
Closes: https://sashiko.dev/#/patchset/20260730031927.25444-1-yijiangshan@kylinos.cn?part=1
Cc: stable@vger.kernel.org
Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn>
Link: https://sashiko.dev/#/patchset/20260730031927.25444-1-yijiangshan@kylinos.cn?part=1
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 20:33:47 +02:00
Even Xu
447c7737ab HID: Intel-thc-hid: Intel-quicki2c: Support full I2C BUS config parameters
Read complete I2C bus configuration parameters from ACPI and passes them
to thc_i2c_subip_init() to properly initialize the THC I2C subip with
platform-specific settings.

This change enhances hardware compatibility by allowing full
platform-specific I2C bus configurations.

Signed-off-by: Even Xu <even.xu@intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 20:32:34 +02:00
Even Xu
c4ff554a72 HID: Intel-thc-hid: Intel-thc: Refactor I2C bus configuration with unified config structure
Introduce a new struct thc_i2c_config to consolidate all configurable
I2C bus parameters into a single structure for better maintainability
and extensibility.

Changes include:
- Add struct thc_i2c_config to encapsulate I2C bus parameters
- Rename thc_i2c_subip_set_speed() to thc_i2c_subip_bus_config() to
  better reflect its expanded functionality
- Update thc_i2c_subip_bus_config() to accept struct thc_i2c_config
  parameter for comprehensive I2C parameter configuration
- Modify thc_i2c_subip_init() to use struct thc_i2c_config and call
  thc_i2c_subip_bus_config() for complete bus initialization

This refactoring improves code organization and unifies I2C configuration
parameters.

Signed-off-by: Even Xu <even.xu@intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 20:32:34 +02:00
Doruk Tan Ozturk
7c65699a3a HID: sony: clean up device list on probe failure
sony_input_configured() adds some controllers to sony_device_list before
HID core registers their input devices. input_register_device() can fail
after the callback returns successfully. sony_probe() then observes that
HID_CLAIMED_INPUT is clear and unwinds, but only stops the HID hardware.
The devres-managed sony_sc is freed while its list node remains linked, so
the next matching controller traverses freed memory.

Initialize the list node and device ID to inactive states. Make list
removal idempotent and run the driver-private cleanup on every probe
failure path. This also makes a second cleanup safe when
sony_input_configured() already unwound a partial initialization before
sony_probe() handles the missing input claim.

Found by 0sec (https://0sec.ai) using automated source analysis;
verified against the HID input registration and probe unwind paths.

Fixes: 4f967f6d73 ("HID: sony: Fix memory issue when connecting device using both Bluetooth and USB")
Cc: stable@vger.kernel.org
Reported-by: Doruk Tan Ozturk <doruk@0sec.ai>
Link: https://lore.kernel.org/linux-input/20260724143925.007D61F00A3A@smtp.kernel.org/
Assisted-by: 0sec:multi-model
Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 20:31:30 +02:00
Baul Lee
a13cdb19fc HID: core: fix OOB read of field->usage in hid_set_field()
hid_set_field() hands field->usage + offset to hid_dump_input() before
the guard that bounds offset:

	hid_dump_input(field->report->device, field->usage + offset, value);

	if (offset >= field->report_count) {
		hid_err(...);
		return -1;
	}

Under CONFIG_DEBUG_FS hid_dump_input() dereferences that pointer, with
buf = hid_resolv_usage(usage->hid, NULL).  The usage[] array is
allocated inline with the hid_field in hid_register_field() and holds
field->maxusage entries, so an offset past it reads off the end of the
kvzalloc()ed allocation and into a neighbouring object.  Had the guard
run first, offset < report_count <= maxusage would already have confined
the pointer to the array.

A caller supplies such an offset today.  picolcd_fb_send_tile()
validates only report->maxfield before issuing
hid_set_field(report->field[0], 11 + i, ...) for i = 0..31, so its
offsets are fixed at 11..42 and are never checked against the bound
field.  When the device registers that field with fewer usages, the
framebuffer deferred-io work drives the read on every tile.  KASAN
reports a 4-byte slab-out-of-bounds read in hid_dump_input() below
hid_set_field(), and the same boot logs "offset (1) exceeds
report_count (1)" from the guard that runs only afterwards.

Move the hid_dump_input() call below the guard.  Because
field->maxusage >= field->report_count, the guard then establishes that
field->usage + offset lies inside the array before it is dereferenced,
for every caller and without changing behaviour on the valid path.

Discovered by XBOW, triaged by Baul Lee <baul.lee@xbow.com>

Fixes: 1da177e4c3 ("Linux-2.6.12-rc2")
Reported-by: Federico Kirschbaum <federico.kirschbaum@xbow.com>
Reported-by: Baul Lee <baul.lee@xbow.com>
Cc: stable@vger.kernel.org
Signed-off-by: Baul Lee <baul.lee@xbow.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 20:28:55 +02:00
Baul Lee
67bb1074e3 HID: pidff: fix OOB write when hid->inputs is empty
hid_pidff_init_with_quirks() derives its input_dev from

	list_entry(hid->inputs.next, struct hid_input, list)

without first checking that hid->inputs is non-empty.  The list member
of struct hid_input is at offset 0, so on an empty list list_entry()
yields &hid->inputs itself and the following hidinput->input load reads
an unrelated member of struct hid_device.  dev is then a type-confused
pointer, and force-feedback init writes through it: each
set_bit(FF_*, dev->ffbit) stores 8 bytes at dev + 192, past the end of
the object dev actually aliases, and input_ff_create() adds further
writes of a heap pointer and two function pointers.

Until hid-universal-pidff the only caller was hid_pidff_init() from
usbhid, which runs under HID_CLAIMED_INPUT and therefore always has at
least one hid_input.  universal_pidff_probe() starts the device with
HID_CONNECT_DEFAULT & ~HID_CONNECT_FF and then calls
hid_pidff_init_with_quirks() directly whenever the descriptor carries a
PID usage page, bypassing that gate.  A report descriptor whose only
application collection is on HID_UP_PID leaves hid->inputs empty while
hid_connect() still succeeds through the hidraw claim, so probe reaches
the unguarded list_entry().

The write happens in the USB probe path, on the hotplug workqueue, so
plugging in a malicious device is enough to trigger it; no attacker
software and no logged-in user are required.  KASAN reports an 8-byte
out-of-bounds write in hid_pidff_init_with_quirks() reached from
universal_pidff_probe().

Check for an empty list before deriving dev and return -ENODEV, as the
other HID force-feedback drivers already do.  universal_pidff_probe()
propagates the error and unwinds.

Discovered by XBOW, triaged by Baul Lee <baul.lee@xbow.com>

Fixes: f06bf8d94f ("HID: Add hid-universal-pidff driver and supported device ids")
Reported-by: Federico Kirschbaum <federico.kirschbaum@xbow.com>
Reported-by: Baul Lee <baul.lee@xbow.com>
Cc: stable@vger.kernel.org
Signed-off-by: Baul Lee <baul.lee@xbow.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 20:27:41 +02:00
Stuart Hayhurst
456d506b60 HID: logitech-hidpp: Remove duplicate ID for the G703 Hero over USB
The ID appears to be given twice, remove the duplicate

Signed-off-by: Stuart Hayhurst <stuart.a.hayhurst@gmail.com>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 20:25:15 +02:00
Stuart Hayhurst
6f4b44abe4 HID: logitech-hidpp: Add support for G502 X Plus USB mouse
The wireless dongle is already supported, this adds detection for
the mouse in wired mode. Supports battery reporting.

Signed-off-by: Stuart Hayhurst <stuart.a.hayhurst@gmail.com>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 20:24:43 +02:00
Alexandre Derumier
781f8e020a HID: nintendo: fix rumble starved by the input report cadence gate
Rumble on third-party controllers speaking the Switch protocol is weak
and intermittent over bluetooth, and absent on some units.

Since commit d750d14803 ("HID: nintendo: fix rumble rate limiter"),
joycon_enforce_subcmd_rate() requires JC_SUBCMD_VALID_DELTA_REQ (3)
consecutive input reports spaced 8-17ms apart before releasing a
subcommand. That window is the official Pro Controller's bluetooth
cadence, and controllers that do not report on it cannot pass the gate,
so their rumble is starved.

Measured over bluetooth on one host, reading the controller directly,
fraction of reports at which the requirement is met:

  official Pro Controller     95%
  Datafrog clone              46-52%
  8BitDo Pro 2                2.5-4%

The Pro 2 delivers reports in pairs, so 11-19% of its deltas are 0ms and
reset the counter. Affected controllers report Nintendo's USB IDs, and
the MAC is no better: the Datafrog clone reports an OUI registered to
Nintendo, so identifying them by vendor would misclassify it.

Instead, notice when the requirement cannot be met: after
JC_SUBCMD_RATE_MAX_FAILURES exhaustions of the limiter, fall back to the
pre-d750d1480362 throttle, which keeps the 25ms spacing and the
transmit-after-receive synchronisation from commit e93363f716 ("HID:
nintendo: ratelimit subcommands and rumble") and drops only the cadence
requirement. Exhaustions are counted cumulatively, as an affected
controller meets the requirement occasionally and a consecutive count
would never be reached.

Signed-off-by: Alexandre Derumier <aderumier@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 20:04:10 +02:00
Jose Villaseñor Montfort
0af3b89705 HID: magicmouse: do not keep a stale msc->input if no input is claimed
magicmouse_input_mapping() caches the first hid_input's input_dev in
msc->input while the report descriptor is parsed, and the rest of the
driver treats a non-NULL msc->input as proof that an input device was
registered.

That does not hold on the hid-input error path. If hidinput_connect()
fails -- for instance because input_register_device() returns an error --
it unwinds through hidinput_disconnect(), which frees every input_dev it
created, including the one cached in msc->input.

The failure does not abort the probe. hid_connect() only skips the claim:

	if ((connect_mask & HID_CONNECT_HIDINPUT) && !hidinput_connect(hdev,
				connect_mask & HID_CONNECT_HIDINPUT_FORCE))
		hdev->claimed |= HID_CLAIMED_INPUT;

and the "device has no listeners" bailout below it does not fire for this
driver, which sets ->raw_event; on the USB Magic Mouse 2 / Magic Trackpad
2 paths hidraw and hiddev are claimed as well. hid_hw_start() therefore
returns 0 and magicmouse_probe() continues with msc->input pointing at
freed memory. Being non-NULL, it passes the "input not registered" check
in probe and the NULL checks in ->raw_event and ->event, so the next
input report dereferences freed memory.

Clear msc->input when the HID core did not claim an input device, so the
existing NULL checks cover this case as well.

Fixes: f1a9a149ab ("HID: magicmouse: fix race between input_register() and probe()")
Link: https://lore.kernel.org/linux-input/20260728185542.65F091F000E9@smtp.kernel.org/
Cc: stable@vger.kernel.org
Signed-off-by: Jose Villaseñor Montfort <pepemontfort@gmail.com>
Reviewed-by: Alec Hall <signshop.alec@gmail.com>
Tested-by: Alec Hall <signshop.alec@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 19:55:19 +02:00
Ibrahim Hashimov
27b376b945 HID: nintendo: fix out-of-bounds read in joycon_ctlr_read_handler()
joycon_ctlr_read_handler() casts an incoming HID input report to
struct joycon_input_report and parses it, guarding the cast only with a
12-byte length check:

	if (size >= 12) /* make sure it contains the input report */
		joycon_parse_report(ctlr, (struct joycon_input_report *)data);

struct joycon_input_report is 49 bytes: a 13-byte header followed by a
union whose IMU arm is 36 bytes. For an IMU report joycon_parse_report()
-> joycon_parse_imu_report() walks that union (struct offsets 13..48),
so a report of exactly 12 bytes with data[0] == JC_INPUT_IMU_DATA passes
the guard yet is read up to 37 bytes past its declared length. The
over-read bytes are decoded into accelerometer/gyroscope values and
forwarded to userspace through the "(IMU)" input device, leaking
driver-internal memory. data[0] and size are fully controlled by a
malicious or spoofed Joy-Con/Pro Controller.

Receive buffers are sized to the maximum report length, so this is an
over-read within the allocation rather than a slab OOB, but the decoded
bytes still reach userspace.

The sibling subcmd path in joycon_ctlr_handle_event() already bounds the
same cast correctly:

	if (size < sizeof(struct joycon_input_report) ||
	    data[0] != JC_INPUT_SUBCMD_REPLY)
		break;

Use the same sizeof(struct joycon_input_report) bound here.

Fixes: 2af16c1f84 ("HID: nintendo: add nintendo switch controller driver")
Cc: stable@vger.kernel.org
Signed-off-by: Ibrahim Hashimov <security@auditcode.ai>
Assisted-by: AuditCode-AI:2026.07
Reviewed-by: Silvan Jegen <s.jegen@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 19:53:09 +02:00
Chen Changcheng
2f4e7624ae HID: amd_sfh: clear hid_sensor_hubs entry on probe failure
In amdtp_hid_probe(), the newly allocated HID device is stored in
cli_data->hid_sensor_hubs[cur_hid_dev] before calling hid_add_device().
If hid_add_device() fails, the error path frees the HID device and its
driver_data but does not clear the array entry, leaving a dangling
pointer.

When the caller (amd_sfh_hid_client_init or
amd_sfh1_1_hid_client_init) detects the probe failure, it jumps to its
cleanup label, which unconditionally calls amd_sfh_hid_client_deinit()
and subsequently amdtp_hid_remove(). The latter iterates over all
hid_sensor_hubs[] entries and, upon encountering the non-NULL but freed
pointer, performs a use-after-free read followed by double-free of both
the HID device and its driver_data.

Clear the array entry in the error path of amdtp_hid_probe() so that
amdtp_hid_remove() skips the failed entry.

Signed-off-by: Chen Changcheng <chenchangcheng@kylinos.cn>
Acked-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 19:52:07 +02:00
Jose Villaseñor Montfort
db8d634128 HID: magicmouse: prevent unbounded recursion in magicmouse_raw_event()
magicmouse_raw_event() handles DOUBLE_REPORT_ID (0xf7) packets, which pack
two touch reports into one, by splitting the packet and calling itself on
each half. The only guard against runaway recursion is a "size < 1" check,
which stops zero-sized calls but does not bound the recursion depth.

A malicious HID device that matches this driver can send a report starting
with DOUBLE_REPORT_ID and filled with the sequence [0xf7, 0x00]. Each level
consumes two bytes and recurses on the remainder, so an incoming report of
up to HID_MAX_BUFFER_SIZE (16 KiB) drives roughly 8000 nested calls. That
easily exhausts the 16 KiB kernel stack, leading to a stack overflow: a
panic with CONFIG_VMAP_STACK, or memory corruption without it.

A double report only ever wraps two normal reports; it is never
legitimately nested. Refuse to re-enter the DOUBLE_REPORT_ID case from a
recursive call so the recursion depth is bounded to two, while all valid
packets keep being parsed exactly as before.

Fixes: a462230e16 ("HID: magicmouse: enable Magic Trackpad support")
Link: https://lore.kernel.org/linux-input/20260706181347.700DB1F00A3F@smtp.kernel.org/
Cc: stable@vger.kernel.org
Signed-off-by: Jose Villaseñor Montfort <pepemontfort@gmail.com>
Reviewed-by: Alec Hall <signshop.alec@gmail.com>
Tested-by: Alec Hall <signshop.alec@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 19:51:26 +02:00
Pengpeng Hou
28a3e326fa HID: rmi: check report length before trimming sentinel bytes
rmi_check_sanity() trims trailing 0xff sentinel bytes, but its loop
reads data[valid_size - 1] before checking that valid_size is non-zero.

Reverse the condition so the length is proved before the last byte is
inspected.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 19:47:35 +02:00
Stuart Hayhurst
08d8814521 HID: corsair-void: Check size of status and firmware events before reading them
Malformed status and firmware events could cause an out-of-bounds read since
the size wasn't being checked. Check the size and warn on unexpected values to
avoid this.

Fixes: 6ea2a6fd38 ("HID: corsair-void: Add Corsair Void headset family driver")
Cc: stable@vger.kernel.org
Signed-off-by: Stuart Hayhurst <stuart.a.hayhurst@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 19:46:03 +02:00
HyeongJun An
a59cf84441 HID: intel-thc-hid: intel-quickspi: validate report size before copy
write_cmd_to_txdma() builds an output report in qsdev->report_buf, a heap
buffer allocated in quickspi_alloc_report_buf() to the device-descriptor
derived max_report_len (a few hundred bytes for a touch controller).  It
copies the caller-supplied report into that buffer:

    memcpy(write_buf->content, report_buf, report_buf_len);

The HID core caps a report at HID_MAX_BUFFER_SIZE (16384) by default, and
quickspi_hid_ll_driver does not set max_buffer_size, so the length reaches
the driver unbounded.  A hidraw SET_REPORT/SET_FEATURE ioctl carrying a
report larger than max_report_len therefore overflows report_buf with
attacker-controlled length and content.

Record the report_buf allocation size and reject reports that do not fit
before copying, matching the equivalent guard in the intel-quicki2c
sibling (quicki2c_init_write_buf()) and the hid-goodix-spi fix.

write_cmd_to_txdma() writes the output report header ahead of the content
in the same buffer, so size the allocation to cover the header as well.
That keeps the added bound from rejecting a maximum-sized report.

Fixes: 9d8d51735a ("HID: intel-thc-hid: intel-quickspi: Add HIDSPI protocol implementation")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
Reviewed-by: Even Xu <even.xu@intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 19:45:00 +02:00
Yousef Alhouseen
207853d46f HID: synchronize input before cleaning up a failed probe
hid_device_io_start() allows reports to run concurrently with probe. If
the probe subsequently fails, __hid_device_probe() releases driver
resources and clears hdev->driver without first excluding those report
callbacks.

For example, a report may enter hidraw_report_event() while the failure
path frees the associated hidraw object, leading to a use-after-free when
the report takes the object's list lock.

Stop input before performing failed-probe cleanup. This reacquires
driver_input_lock and waits for any report callback already in progress.

Fixes: c849a6143b ("HID: Separate struct hid_device's driver_lock into two locks.")
Reported-by: syzbot+9eebf5f6544c5e873858@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=9eebf5f6544c5e873858
Signed-off-by: Yousef Alhouseen <alhouseenyousef@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 19:42:07 +02:00
Pengpeng Hou
336af689d5 HID: amd_sfh: return an error when response wait times out
amdtp_wait_for_response() waits for request_done before completing a
report request. wait_event_interruptible_timeout() returns 0 when the
wait expires, but the current code treats only negative values as errors
and returns success on timeout.

Return -ETIMEDOUT when the response wait expires while preserving the
existing success path when the response has already been observed.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Acked-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 19:37:52 +02:00
Denis Benato
9dc6fdaaa7 HID: asus: add i2c entry for FA808UM and other TUFs
On newer TUF laptops the keyboard HID device uses the same PID/VID of a
USB device that was found in ROG laptops: add it to hid-asus as i2c too.

Signed-off-by: Denis Benato <denis.benato@linux.dev>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 19:35:21 +02:00
谢致邦 (XIE Zhibang)
fd7c67d05f HID: i2c-hid: Refactor _DSM helper and add i2c-hid-acpi-prp0001 driver
Move the _DSM call that gets the HID descriptor address from
i2c-hid-acpi.c into i2c-hid-acpi.h as a static inline so both the ACPI
and the new PRP0001 driver can use it. While refactoring, move the
blacklist check and the _DSM call to the top of probe() to avoid a
pointless alloc when the device is blacklisted or does not implement the
_DSM.

Some devices, for example the Lenovo KaiTian N60d and Inspur CP300L3,
are declared with _HID "PRP0001" and _DSD compatible "hid-over-i2c" but
lack "hid-descr-addr" from the _DSD and provide the HID descriptor
address only through an ACPI _DSM. The OF driver fails to probe them
because it requires hid-descr-addr. Add a new driver that handles these
devices by calling the shared _DSM helper.

Link: https://lore.kernel.org/tencent_F6FC553D1BB737FC00062AD0FEF43C580F0A@qq.com
Fixes: b33752c300 ("HID: i2c-hid: Reorganize so ACPI and OF are separate modules")
Signed-off-by: 谢致邦 (XIE Zhibang) <Yeking@Red54.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 19:31:14 +02:00
Vicki Pfau
cdf826a94e HID: core: Expose id attributes in sysfs
udev rules for handling input devices generally match on idVendor and
idProduct for USB hidraw or id/vendor and id/product for evdev nodes.
However, hidraw nodes that aren't created by the USB subsystem will only
expose this information to udev via the kernel path itself. This leads to
doing substring matching, which can be error-prone or overzealous. Instead,
since the HID subsystem already has this information, we can expose it
directly in the same format that evdev exposes it.

Signed-off-by: Vicki Pfau <vi@endrift.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 19:28:13 +02:00
Haoxiang Li
dd5be4d9ce HID: logitech-hidpp: Fix FF device cleanup on init failure
hidpp_ff_init() creates the input force-feedback device with
input_ff_create(), then allocates the HID++ FF private data,
effect ID array, and workqueue.

If any of those allocations fail after input_ff_create() succeeds,
the function returns an error without destroying the FF device.
Add an unwind path that frees the private allocations made by
hidpp_ff_init() and calls input_ff_destroy() for failures after
input_ff_create() succeeds.

Fixes: ff21a635dd ("HID: logitech-hidpp: Force feedback support for the Logitech G920")
Signed-off-by: Haoxiang Li <haoxiang_li2024@163.com>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 19:26:36 +02:00
Denis Benato
2a767bd3e0 HID: asus: fix a off-by-one in mcu_parse_version_string() validation
In mcu_parse_version_string() a size validation for response is stricter
that it needs to be: relax the check by one byte.

The device always answer with a greater byte count so this does
not introduce visible changes.

Fixes: ("hid-asus: check ROG Ally MCU version and warn")
Signed-off-by: Denis Benato <denis.benato@linux.dev>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 19:25:35 +02:00
Denis Benato
fb572e2f23 HID: asus: remove extraneous OOM error
If devm_kzalloc fails an allocation error is already being reported:
no need to repeat it. For new code this behavior is disincentivized
and checkpatch.pl reports a warning.

Reviewed-by: Antheas Kapenekakis <lkml@antheas.dev>
Signed-off-by: Denis Benato <denis.benato@linux.dev>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 19:25:32 +02:00
Denis Benato
47669bec44 HID: asus: refactor the two workqueues and init sequence
Multiple issues have been found within the hid-asus driver:
- unchecked size in asus_raw_event()
- unclean teardown of asus_probe on failure
- possible use-after-free in asus_probe
- multiple workqueue used for jobs where one was enough
- sleeping calls in atomic context
- packets of incorrect size being sent to the keyboard controller

Join the two workqueues into one reusing the stopping mechanism
of the brightness workqueue, use the joined workqueue to also
move the asus_wmi_send_event() sleeping call away from atomic
context and add a size check in asus_raw_event().

Fixes: f631011e36 ("HID: hid-asus: Implement fn lock for Asus ProArt P16")
Fixes: 1489a34e97 ("HID: asus: Implement Fn+F5 fan control key handler")
Fixes: b34b5945a7 ("HID: asus: listen to the asus-wmi brightness device instead of creating one")
Reported-by: sahiko-bot@kernel.org
Closes: https://lore.kernel.org/all/20260613154732.60A4B1F000E9@smtp.kernel.org/
Signed-off-by: Denis Benato <denis.benato@linux.dev>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 19:24:52 +02:00
Jiangshan Yi
2c9a6998c1 HID: mcp2221: validate report size in mcp2221_raw_event()
mcp2221_raw_event() never validates the size of incoming HID reports.
In the MCP2221_I2C_GET_DATA path it trusts the device-supplied data[3]
as the copy length without checking that 4 + data[3] bytes actually
exist in the received report. A malicious or misbehaving USB device can
send a short report with a large data[3], causing the memcpy to read
past the valid report data in the HID transfer buffer and leak
uninitialized kernel memory back to userspace through the I2C/SMBus
read path.

Add a minimum size check at entry and validate that the source range
fits within the received report before the copy.

Fixes: 67a95c2146 ("HID: mcp2221: add usb to i2c-smbus host bridge")
Cc: stable@vger.kernel.org
Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 19:20:55 +02:00
Jiangshan Yi
db2333f887 HID: mcp2221: clear rxbuf after I2C/SMBus transfer completes
mcp_i2c_smbus_read() stores the caller-supplied buffer pointer in
mcp->rxbuf for the duration of a transfer but never clears it when the
transfer finishes or times out. Once the caller frees or reuses the
buffer, mcp->rxbuf becomes a dangling pointer. A delayed or spurious
MCP2221_I2C_GET_DATA report can then drive mcp2221_raw_event() to
memcpy device data into the freed memory, causing a write
use-after-free.

Route all return paths through a single exit point that clears
mcp->rxbuf and mcp->rxbuf_size, so that the existing !mcp->rxbuf guard
in the raw_event handler can reject any report arriving after the
transfer has ended.

Fixes: 67a95c2146 ("HID: mcp2221: add usb to i2c-smbus host bridge")
Cc: stable@vger.kernel.org
Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 19:20:55 +02:00
Jiangshan Yi
dca151633c HID: mcp2221: stop device IO before hid_hw_stop
Quiesce device IO at the start of the devm cleanup callback
mcp2221_hid_unregister() so that incoming HID reports cannot race with
hardware teardown during probe failure or device removal, addressing a
potential use-after-free.

Guard the call to hid_device_io_stop() with io_started. On normal
removal hid_device_remove() has already cleared io_started before the
devres group is released, so an unconditional call would otherwise hit
the !io_started path and emit a spurious "io already stopped" warning
on every removal. The guard preserves the probe-failure balancing,
where io_started is still set after hid_device_io_start(), while
staying silent on the normal removal path.

Fixes: d4b50ac06e ("HID: mcp2221: Allow IO to start during probe")
Cc: stable@vger.kernel.org
Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 19:20:55 +02:00
Jiangshan Yi
1f74d3bff6 HID: nintendo: stop device IO before hid_hw_stop on probe failure
nintendo_hid_probe() calls hid_device_io_start() before joycon_init()
and joycon_leds_create().  If either fails, the error path jumps to
err_close which calls hid_hw_close()/hid_hw_stop() without first calling
hid_device_io_stop().

hid_hw_stop() does not stop device IO, so hid_input_report() may still
run and access driver data that is being torn down, resulting in a
use-after-free.

Add an err_io_stop label that calls hid_device_io_stop() before
hid_hw_close(), and point the two post-io_start error paths at it.

Fixes: 2af16c1f84 ("HID: nintendo: add nintendo switch controller driver")
Cc: stable@vger.kernel.org
Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 19:20:13 +02:00
Raman Varabets
bf3e39df3a HID: ft260: fix stack-use-after-return write in I2C read race
ft260_i2c_read() points dev->read_buf at a caller-supplied buffer
(often an on-stack variable), arms a completion and waits up to five
seconds for the device to return the data. The HID input callback
ft260_raw_event() runs in the input/IRQ path, independent of the
dev->lock mutex held by the read path, and copies the device-supplied
payload into dev->read_buf after a plain NULL check.

These two paths share read_buf, read_idx and read_len with no
serialization. If the device delays its response until the read
times out, ft260_i2c_read() resets the controller, clears read_buf
and returns, unwinding the stack frame the buffer lived in. A
response that arrives at that moment lets ft260_raw_event() pass the
NULL check and then memcpy() the device-controlled payload into the
now-freed stack location, a bounded but attacker-influenced
stack-use-after-return write triggerable by malicious or
malfunctioning hardware.

Add a dedicated spinlock that serializes every access to read_buf,
read_idx and read_len. ft260_raw_event() now holds it across the
NULL check, the memcpy and the index update, while the read path
takes it when arming and when clearing the buffer, so the teardown
can no longer slip between the check and the copy.

Fixes: 6a82582d9f ("HID: ft260: add usb hid to i2c host bridge driver")
Cc: stable@vger.kernel.org
Signed-off-by: Raman Varabets <kernel-linux-20260610-80b7ab08@raman.v1.sg>
Reviewed-by: Michael Zaidman <michael.zaidman@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 19:17:40 +02:00
Raman Varabets
2d68d67151 HID: ft260: fix SMBus block read protocol handling
For I2C_SMBUS_BLOCK_DATA reads, ft260_smbus_xfer() passed
data->block[0] + 1 as the read length. But on a block read the byte
count is supplied by the slave as the first byte of the response;
data->block[0] is not initialized by the caller, so the transfer
length was taken from stale buffer contents, and the count byte the
slave did return was stored without any validation.

Implement the SMBus 2.0 block read protocol properly: read the count
byte first with a repeated START and no STOP, validate it against
I2C_SMBUS_BLOCK_MAX (resetting the bus and returning -EPROTO on a
bogus count), then read exactly that many data bytes and finish the
transaction with STOP. This keeps the whole sequence within a single
I2C transaction:

  S Addr+Wr A Reg A Sr Addr+Rd A Count A Data... P

To support issuing the two reads as one transaction, teach
ft260_i2c_read() to honor the caller's flags instead of always
forcing a START and unconditionally appending STOP to the last
chunk: START is only emitted if requested, and STOP is appended to
the final chunk only when the caller asked for it.

Signed-off-by: Raman Varabets <kernel-linux-20260610-80b7ab08@raman.v1.sg>
Reviewed-by: Michael Zaidman <michaelz@xsightlabs.com>
Reviewed-by: Michael Zaidman <michael.zaidman@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03 19:15:48 +02:00
Ihor Solodrai
5c4923172d HID: bpf: Make syscall kfunc flags match the struct_ops set
Update kfunc flags for hid_bpf_syscall_kfunc_ids set to exactly match
hid_bpf_kfunc_ids set by adding KF_SLEEPABLE flag.

The syscall set omitted the flag because syscall programs are always
sleepable (the verifier rejects a non-sleepable syscall program).

However the upcoming resolve_btfids change enforces per-kfunc flag
consistency across BTF ID sets at build time, which is why this change
is necessary.

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Reviewed-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/bpf/20260722233518.778854-7-ihor.solodrai@linux.dev
2026-07-30 12:48:09 -07:00
Linus Torvalds
bffa972b3f Android/IIO bugfixes for 7.2-rc3
Here is a set of bugfixes for 7.2-rc3 that resolve a bunch of reported
 issues in just the binder and iio codebases.  Included in here are:
   - binder driver bugfixes for both the rust and c versions for reported
     problems
   - lots and lots of iio driver bugfixes for lots of reported issues
     (including a hid sensor driver bugfix)
 
 Full details are in the shortlog, all of these have been in linux-next
 with no reported issues.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCalNPWw8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+yltzACdFC2/ouvc1ea1jGFBP1ZN4lKU6gAAn1ak5lRK
 30pEMSmJwYteOj8AlpuE
 =ZIWT
 -----END PGP SIGNATURE-----

Merge tag 'char-misc-7.2-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc

Pull Android/IIO fixes from Greg KH:
 "Here is a set of bugfixes for 7.2-rc3 that resolve a bunch of reported
  issues in just the binder and iio codebases. Included in here are:

   - binder driver bugfixes for both the rust and c versions for
     reported problems

   - lots and lots of iio driver bugfixes for lots of reported issues
     (including a hid sensor driver bugfix)

  Full details are in the shortlog, all of these have been in linux-next
  with no reported issues"

* tag 'char-misc-7.2-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (36 commits)
  iio: event: Fix event FIFO reset race
  iio: imu: inv_icm42600: fix timestamp clock period by using lower value
  iio: light: al3010: fix incorrect scale for the highest gain range
  iio: adc: nxp-sar-adc: Fix the delay calculation in nxp_sar_adc_wait_for()
  iio: light: tsl2591: return actual error from probe IRQ failure
  iio: imu: inv_icm42600: fix timestamping by limiting FIFO reading
  iio: imu: st_lsm6dsx: deselect shub page before reading whoami
  rust_binder: clear freeze listener on node removal
  rust_binder: reject context manager self-transaction
  rust_binder: use a u64 stride when cleaning up the offsets array
  binder: fix UAF in binder_free_transaction()
  binder: fix UAF in binder_thread_release()
  rust_binder: synchronize Rust Binder stats with freeze commands
  binder: cache secctx size before release zeroes it
  rust_binder: fix BINDER_GET_EXTENDED_ERROR
  iio: adc: ad7779: add missing 'select IIO_TRIGGERED_BUFFER' to Kconfig
  iio: adc: ad4130: add missing `select IIO_TRIGGERED_BUFFER` to Kconfig
  iio: adc: ti-ads124s08: Return reset GPIO lookup errors
  iio: temperature: Build mlx90635 with CONFIG_MLX90635
  iio: light: al3320a: add missing REGMAP_I2C to Kconfig
  ...
2026-07-12 12:37:28 -07:00
Shyam Sundar S K
08f3df928f
platform/x86/amd/pmf: Store commonly used enums in the header file
Relocate commonly used enums from multiple source files into a shared
header file to simplify code structure, improve readability, and
enhance maintainability. Also, remove the initialization of the first
enum member, since it is not needed.

Add the AMD_PMF_ prefix to the laptop_placement and platform_type enums
since these names are overly generic for inclusion in a UAPI header

Co-developed-by: Sanket Goswami <Sanket.Goswami@amd.com>
Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
Link: https://patch.msgid.link/20260609081044.2416731-4-Shyam-sundar.S-k@amd.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
2026-07-10 15:13:46 +03:00
Linus Torvalds
6bad2e38fe hid-for-linus-2026070801
-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEL65usyKPHcrRDEicpmLzj2vtYEkFAmpOMQcACgkQpmLzj2vt
 YEkneQ//bIgxybg8BTRoMXFJ4bXmiKDhXg1bxQLESMr5dGLU8O5MeMYyWEupxMSa
 IFg6uvc6PhwvowjzZhtysAOswZGqmzSGP/bvAZoXlDbps3JJ61RdP6foUz40eraP
 dxEf8uWuHoO7gOsHkWDQlPiYdWEsNElf9RBjysAouOLi8eCContxiiDaWH2DDYAM
 M+GLgditVyrVpjmAluQyvlnV6zpAbpsAkMyNx64V/0ccgUniwEh0LycW6oEy4FR7
 EOtFXZg9V/h78uH3sLCTTUPHq6WhsLtwjSKkK4vusoibCi9j+N38dckgwE1kOwUC
 XWQVYhfJhgytPIG1YGVdW88KDHP1VjM2otNiOVzxV0fJJ6+kF6Lk5/Tl4eTtSttg
 SmKIMtFVxdyoNswBmOkICp/yMC3nx9YjTfkWl2IYfAqq9EbQr6R2oafvEUllqcRY
 +1Ew79t2ry3e3ReJlS+PND5/xfct/oh/Z8Qww5ysAvsJbAnwjdXOuno/43OZimDF
 YyD+651HhwwgvMJUGgcTntuzycGR4i2tzp3UrFD1dxD7v+vG3MFb9i8foNF4SkqG
 aDcd/0mnXJHnwRynv4nAXM4+7B3BnSMsqSmTm4IiQTIvTDTNHAqeKfLBkKg1XxgI
 mFTl6MKYVuCCDqj6d2LmtCCiii7/ZvFZUzpsWDua2eUc/+wQxoU=
 =3BLb
 -----END PGP SIGNATURE-----

Merge tag 'hid-for-linus-2026070801' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid

Pull HID fixes from Jiri Kosina:

 - OOB, UAF, NULL-deref fixes in core and picolcd, logitech, letsketch,
   appleir and multitouch drivers (Georgiy Osokin, HyeongJun An, Lee
   Jones, Manish Khadka, Maoyi Xie and Trung Nguyen)

 - fix for integer wraparound (and corresponding regression selftest) in
   hid-bpf (Yiyang Chen)

* tag 'hid-for-linus-2026070801' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid:
  selftests/hid: multitouch: test a large ContactCountMaximum
  HID: multitouch: fix out-of-bounds bit access on mt_io_flags
  selftests/hid: Cover hid_bpf_get_data() size overflow
  selftests/hid: Load only requested struct_ops maps
  HID: bpf: Fix hid_bpf_get_data() range check
  HID: lg-g15: cancel pending work on remove to fix a use-after-free
  HID: logitech-dj: Fix maxfield check in DJ short report validation
  HID: core: Fix OOB read in hid_get_report for numbered reports
  HID: picolcd: prevent NULL pointer dereference in picolcd_send_and_wait()
  HID: appleir: fix UAF on pending key_up_timer in remove()
  HID: letsketch: fix UAF on inrange_timer at driver unbind
2026-07-08 08:43:44 -07:00
Uwe Kleine-König (The Capable Hub)
995832b2ce Replace <linux/mod_devicetable.h> by more specific <linux/device-id/*.h> (c files)
Replace the #include of <linux/mod_devicetable.h> by the more specific
<linux/device-id/*.h> where applicable. For most cases the include
can be dropped completely, only a few drivers need one or two headers
added.

Acked-by: Danilo Krummrich <dakr@kernel.org>
Acked-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://patch.msgid.link/1a3f2007c5c5dcf555c09a4035ce3ae8ef1b6c49.1782808461.git.u.kleine-koenig@baylibre.com
Signed-off-by: Uwe Kleine-König (The Capable Hub) <u.kleine-koenig@baylibre.com>
2026-07-03 07:38:17 +02:00
Uwe Kleine-König (The Capable Hub)
ecca1d63c1 Replace <linux/mod_devicetable.h> by more specific <linux/device-id/*.h> (headers)
<linux/mod_devicetable.h> is included in a many files:

	$ git grep '<linux/mod_devicetable.h>' ef0c9f75a1 | wc -l
	1598

; some of them are widely used headers. To stop mixing up different and
unrelated driver( type)s let the subsystem headers only use the subset
of the recently split <linux/mod_devicetable.h> that are relevant for
them.

The fallout (I hope) is addressed in the previous commits that handle
sources relying on e.g. <linux/i2c.h> pulling in the full legacy header
and thus providing pci_device_id.

Acked-by: Danilo Krummrich <dakr@kernel.org>
Acked-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Link: https://patch.msgid.link/199fe46b624ba07fb9bd3e0cd6ff13757932cb5f.1782808461.git.u.kleine-koenig@baylibre.com
Signed-off-by: Uwe Kleine-König (The Capable Hub) <u.kleine-koenig@baylibre.com>
2026-07-03 07:38:16 +02:00
Trung Nguyen
8813b06122 HID: multitouch: fix out-of-bounds bit access on mt_io_flags
mt_io_flags is a single unsigned long, but mt_process_slot(),
mt_release_pending_palms() and mt_release_contacts() use it as a
per-slot bitmap indexed by the slot number. That slot number is only
bounded by td->maxcontacts, which is taken from the device's
ContactCountMaximum feature report and can be up to 255, not by
BITS_PER_LONG.

As a result, a multitouch device that advertises a large contact count
makes set_bit()/clear_bit() operate past the mt_io_flags word and
corrupt the adjacent members of struct mt_device. The sticky-fingers
release timer is the easiest way to reach this. mt_release_contacts()
runs

	for (i = 0; i < mt->num_slots; i++)
		clear_bit(i, &td->mt_io_flags);

with num_slots == maxcontacts. For maxcontacts around 250 the loop
clears the bits that overlap td->applications.next, zeroing that list
head, and the list_for_each_entry() that immediately follows then
dereferences NULL. The kernel panics from timer (softirq) context. On a
KASAN build this shows up as a general protection fault in
mt_release_contacts() with a null-ptr-deref at offset 0x58, which is
offsetof(struct mt_application, num_received).

The state is reachable from an untrusted USB or Bluetooth HID
multitouch device; no local privileges are required.

Store the per-slot active state in a separately allocated bitmap sized
for maxcontacts, the same pattern already used for pending_palm_slots,
and keep only MT_IO_FLAGS_RUNNING in mt_io_flags. The two
"mt_io_flags & MT_IO_SLOTS_MASK" arming checks become
bitmap_empty(td->active_slots, td->maxcontacts).

Move MT_IO_FLAGS_RUNNING back to bit 0. It was bumped to bit 32 by the
same commit to leave the low byte for the slot bits; with the slot bits
gone it fits in bit 0 again, which also keeps it within the unsigned
long on 32-bit.

Fixes: 46f781e0d1 ("HID: multitouch: fix sticky fingers")
Cc: stable@vger.kernel.org
Signed-off-by: Trung Nguyen <trungnh@cystack.net>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2026-07-01 20:36:12 +02:00
Yiyang Chen
2d04404942 HID: bpf: Fix hid_bpf_get_data() range check
hid_bpf_get_data() returns a pointer into the HID-BPF context data when
the caller-provided offset and size fit inside ctx->allocated_size.

The current check adds rdwr_buf_size and offset before comparing the
result against ctx->allocated_size. Since both values are unsigned, a
very large size can wrap the sum below ctx->allocated_size and make the
helper return a pointer even though the requested range is not contained
in the backing buffer.

Use check_add_overflow() to reject wrapped range ends before comparing
the requested range end against ctx->allocated_size.

Fixes: 658ee5a64f ("HID: bpf: allocate data memory for device_event BPF programs")
Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2026-07-01 09:55:35 +02:00
Srinivas Pandruvada
f784fcea45 HID: sensor-hub: Add sensor_hub_input_attr_read_values() for multi-byte reads
sensor_hub_input_attr_get_raw_value() is limited to returning a single
32-bit value, which is insufficient for sensors that report data larger
than 32 bits, such as a quaternion with four s16 elements.

Add sensor_hub_input_attr_read_values() that accepts a caller-provided
buffer and accumulates incoming data until the buffer is full. The two
paths are distinguished in sensor_hub_raw_event() by pending.max_raw_size
being non-zero, preserving backward compatibility.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Co-developed-by: Zhang Lixu <lixu.zhang@intel.com>
Signed-off-by: Zhang Lixu <lixu.zhang@intel.com>
Acked-by: Jiri Kosina <jkosina@suse.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Cc: <Stable@vger.kernel.org>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
2026-06-29 23:24:46 +01:00
Maoyi Xie
7705b4140d HID: lg-g15: cancel pending work on remove to fix a use-after-free
lg_g15_data is allocated with devm and holds a work item. The report
handlers schedule that work straight from device input.
lg_g15_event() and lg_g15_v2_event() do it on the backlight cycle key,
and lg_g510_leds_event() does it too. The worker dereferences the
lg_g15_data back through container_of.

The driver had no remove callback and never cancelled the work. So if a
report scheduled the work and the keyboard was then unplugged, devres
freed lg_g15_data while the work was still pending or running, and the
worker touched freed memory. This is a use-after-free. It is reachable
as a race on device unplug.

Add a remove callback that cancels the work before devres frees the
state. g15->work is only initialized for the models that schedule it
(G15, G15 v2, G510). The G13 and Z-10 leave it zeroed, so guard the
cancel on g15->work.func to avoid cancelling a work that was never set
up. The g15 NULL test mirrors the one already in lg_g15_raw_event().

Fixes: 97b741aba9 ("HID: lg-g15: Add keyboard and LCD backlight control")
Cc: stable@vger.kernel.org
Suggested-by: Hans de Goede <hansg@kernel.org>
Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com>
Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-29 11:18:44 +02:00
HyeongJun An
590cc4d782 HID: logitech-dj: Fix maxfield check in DJ short report validation
Commit b6a5791285 ("HID: logitech-dj: Prevent REPORT_ID_DJ_SHORT
related user initiated OOB write") added validation for the DJ short
output report, but the error path dereferences rep->field[0] even when
rep->maxfield is zero.

Commit 8b9a097eb2 ("HID: logitech-dj: fix wrong detection of bad
DJ_SHORT output report") made the check conditional on rep being present,
but a crafted descriptor can still create report ID 0x20 with only padding
output items. hid-core registers the report, ignores the padding field,
and leaves rep->maxfield as zero.

In that case the validation enters the rep->maxfield < 1 branch and then
dereferences rep->field[0]->report_count while printing the error message,
causing a NULL pointer dereference during probe. This is reproducible with
uhid by emulating a Logitech receiver with a padding-only DJ short output
report:

  BUG: KASAN: null-ptr-deref in logi_dj_probe+0xb1/0x754 [hid_logitech_dj]
  Read of size 4 at addr 0000000000000028 by task kworker/4:1/129
  ...
  Call Trace:
   logi_dj_probe+0xb1/0x754 [hid_logitech_dj]
   hid_device_probe+0x329/0x3f0 [hid]
   really_probe+0x162/0x570
   __device_attach+0x137/0x2c0
   bus_probe_device+0x38/0xc0
   device_add+0xa56/0xce0
   hid_add_device+0x19c/0x280 [hid]
   uhid_device_add_worker+0x2c/0xb0 [uhid]

Reject the zero-field report before printing the field report_count.

Fixes: b6a5791285 ("HID: logitech-dj: Prevent REPORT_ID_DJ_SHORT related user initiated OOB write")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-29 11:18:07 +02:00
Michael Bommarito
7a5f1acd06 HID: roccat: add KUnit test for kone profile-index bounds
Drive kone_keep_values_up_to_date() with a crafted switch-profile event;
an out-of-range value reads past profiles[] (KASAN slab-out-of-bounds on
an unpatched tree). A benign control with an in-range value exercises the
same path. The test object is sized to end at profiles[] so the over-read
lands in the KASAN redzone.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-29 11:16:26 +02:00
Michael Bommarito
43fae42628 HID: roccat: bound device-supplied profile index
kone_keep_values_up_to_date() and kone_profile_activated() use an
8-bit, device-supplied profile value as an index into the 5-element
kone->profiles[] array without a range check. A malicious USB device
claiming the Roccat Kone id can send a switch-profile event (or a
startup_profile read at probe) with an out-of-range value and make the
driver read out of bounds; the result is exposed via the actual_dpi
sysfs attribute.

Reject out-of-range indices in both paths.

This was found with static analysis and confirmed with the KUnit test
added in the following patch (KASAN: slab-out-of-bounds).

Fixes: 14bf62cde7 ("HID: add driver for Roccat Kone gaming mouse")
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-29 11:16:26 +02:00
Rosalie Wanders
a74d24ce26 HID: sony: use devm_kasprintf()
Using devm_kasprintf() makes the code less error-prone.

Signed-off-by: Rosalie Wanders <rosalie@mailbox.org>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-29 11:11:21 +02:00
Rosalie Wanders
6762e104eb HID: sony: remove unneeded which argument from sony_schedule_work()
The sony_worker enum only had a single member, so removing it simplifies
sony_schedule_work().

Signed-off-by: Rosalie Wanders <rosalie@mailbox.org>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-29 11:11:21 +02:00
Rosalie Wanders
da4f817ad2 HID: sony: use guard() and scoped_guard()
This replaces the spin_lock_irqsave() and spin_unlock_irqrestore() calls
with the RAII guard() and scoped_guard().

Signed-off-by: Rosalie Wanders <rosalie@mailbox.org>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-29 11:11:21 +02:00
Rosalie Wanders
5acb364edd HID: sony: use dedicated raw_event() handlers in sony_raw_event()
This commit changes the way sony_raw_event() works by adding a function
pointer to a raw_event() handler in the sc struct instead of manually
checking the quirk in order to call the right function, this simplifies
the sony_raw_event() function alongside making the raw_event() handlers
more self-contained, thus making the code more readable.

The raw_event() handler should be configured using the new
sony_init_raw_event_handler() function in sony_input_configured(), where
we already check for quirks and apply device specific workarounds.

Signed-off-by: Rosalie Wanders <rosalie@mailbox.org>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-29 11:11:21 +02:00
Lee Jones
af1a9b65eb HID: core: Fix OOB read in hid_get_report for numbered reports
When a caller passes a size of 0 to hid_report_raw_event() for a
numbered report, the function originally called hid_get_report() before
performing any size validation.

Inside hid_get_report(), if the report is numbered (report_enum->numbered
is true), it unconditionally dereferences data[0] to extract the report ID.
With a size of 0, this results in an out-of-bounds read or kernel panic.

Fix this by moving the numbered report size validation check before the
call to hid_get_report(), ensuring that size is at least 1 before
dereferencing the data pointer.

Fixes: 2c85c61d13 ("HID: pass the buffer size to hid_report_raw_event")
Signed-off-by: Lee Jones <lee@kernel.org>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-29 11:10:23 +02:00
Christos Maragkos
1f9b25d3fb HID: nintendo: Fix imu_timestamp_us double increment per report
Previously, the imu_timestamp_us variable was incremented twice per
report, causing it to advance by two times the desired amount.

This resulted in incorrect jumps in IMU timestamps reported using
MSC_TIMESTAMP, so userspace applications saw corrupted timing on
functions such as gyroscope-based aim and motion controls.

This is fixed by removing the redundant increment at the start of the
report handling so the remaining can account for the full report
interval.

Fixes: 4ff5b10840 ("HID: nintendo: add IMU support")
Signed-off-by: Christos Maragkos <whitetowersoftware@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-29 10:57:37 +02:00
Ruoyu Wang
8310cdeefc HID: wacom: avoid copying Bluetooth input reports
wacom_intuos_bt_irq() duplicates the received Bluetooth report with
kmemdup() so that it can pass 10-byte input report payloads to the
common Intuos parser. The helper then copies each payload back into
wacom->data before calling wacom_intuos_irq().

Avoid the allocation and copy by temporarily pointing wacom->data at the
current 10-byte payload while the common parser runs, then restoring the
original report pointer. The Bluetooth report parser keeps using the
original report buffer for dispatch and battery parsing, while the common
parser sees the same payload bytes as before.

This also removes the unchecked kmemdup() result from the Bluetooth IRQ
path.

Suggested-by: Jason Gerecke <jason.gerecke@wacom.com>
Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
Reviewed-by: Jason Gerecke <jason.gerecke@wacom.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-29 10:54:04 +02:00
David Glushkov
2346d6997b HID: steelseries: Add MSI Raider A18 HX A9WJG RGB support
The MSI Raider A18 HX A9WJG exposes two internal SteelSeries USB HID
devices for RGB lighting: KLC (1038:1122) for the keyboard and ALC
(1038:1161) for the lightbar/logo zones.

Add DMI-gated support for these devices and expose them as multicolor
LED class devices. The driver sends the same HID class SET_REPORT
control transfer as the tested userspace implementation for this
machine and writes a uniform RGB value to all known keyboard keys or
ALC zones.

The ALC payload uses sparse LED IDs on this chassis: 0x00, 0x01,
0x02 and 0x03 are physical zones, while 0x04 and 0x05 do not appear
to map to physical LEDs. Unused payload LED ID slots are initialized
to 0xff so they are ignored by the controller instead of defaulting
to LED ID 0x00.

Limit RGB support to USB interface 0 and the tested DMI system because
the KLC product ID is shared across MSI laptop designs and the key
layout mapping is model-specific. If the DMI or interface check does
not match, keep the device bound as a regular HID device instead of
failing probe.

Also make the existing Arctis 9 vendor usage-page check defensive by
returning false for report descriptors shorter than three bytes before
inspecting hdev->rdesc[0..2].

Tested on MSI Raider A18 HX A9WJG. Both internal SteelSeries ALC
(1038:1161) and KLC (1038:1122) HID devices bind on interface 0 and
create steelseries::lightbar and steelseries::kbd_backlight. Setting
multi_intensity and brightness changes the keyboard and lightbar
colors.

Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202606010709.X0QYNjFZ-lkp@intel.com/
Signed-off-by: David Glushkov <david.glushkov@sntiq.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-29 10:52:45 +02:00
Philipp Weber
a4bc415046 HID: core: quiesce input in hid_hw_stop() to prevent use-after-free
A driver's probe calls hid_device_io_start() to enable input delivery,
then fails at a later initialization step and unwinds via hid_hw_stop().
The unwind frees struct hidraw via hidraw_disconnect() while in-flight
HID reports may still be running on another CPU, dereferencing the
freed object through hidraw_report_event(). syzbot reports the
resulting use-after-free for the corsair-psu HID driver.

Edward Adam Davis posted a per-driver fix for corsair-psu that adds
an explicit hid_device_io_stop() before hid_hw_stop() in the probe
error path ("hwmon: prevent packets from going to driver for probe",
2026-04-28). Auditing the tree shows 15 drivers call
hid_device_io_start(); 7 also call hid_device_io_stop() and 8 do not:

  drivers calling hid_device_io_start() without a matching
  hid_device_io_stop() before hid_hw_stop():
    drivers/hwmon/corsair-psu.c       (fix posted by Edward)
    drivers/hwmon/corsair-cpro.c
    drivers/hwmon/nzxt-kraken3.c
    drivers/hwmon/nzxt-smart2.c
    drivers/hwmon/gigabyte_waterforce.c
    drivers/hid/hid-logitech-dj.c
    drivers/hid/hid-nintendo.c
    drivers/hid/hid-mcp2221.c

Roughly half of all callers of the API are exposed. Centralize the
quiesce in hid_hw_stop() so callers do not have to remember the
matching stop: if a driver has left hdev->io_started true on entry,
call hid_device_io_stop() before hid_disconnect().

For the 7 drivers that already call hid_device_io_stop() correctly,
hdev->io_started is false on entry, the guard short-circuits, and
behavior is unchanged.

No Fixes: tag because the affected drivers gained their
hid_device_io_start() calls independently over years; the bug is a
class-wide API misuse rather than a regression from one commit.

Reported-by: syzbot+9eebf5f6544c5e873858@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=9eebf5f6544c5e873858
Signed-off-by: Philipp Weber <kernel@phwe.de>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-29 10:48:21 +02:00
Georgiy Osokin
0021eb0904 HID: picolcd: prevent NULL pointer dereference in picolcd_send_and_wait()
In picolcd_send_and_wait(), an integer overflow of the signed loop counter
'k' can theoretically lead to a NULL pointer dereference of 'raw_data'.
If the loop executes more than INT_MAX times, 'k' becomes negative,
making the condition 'k < size' true even when 'size' is 0.

Change the type of 'k' to 'unsigned int' to prevent the overflow and
eliminate the out-of-bounds access.

Found by Linux Verification Center (linuxtesting.org) with the Svace static
analysis tool.

[jkosina@suse.com: extended hash length]
Fixes: fabdbf2fd2 ("HID: picoLCD: split driver code")
Signed-off-by: Georgiy Osokin <g.osokin@auroraos.dev>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-29 10:46:13 +02:00
Manish Khadka
75fe87e19d HID: appleir: fix UAF on pending key_up_timer in remove()
appleir_remove() runs hid_hw_stop() before timer_delete_sync().
hid_hw_stop() synchronously unregisters the HID input device via
hid_disconnect() -> hidinput_disconnect() -> input_unregister_device(),
which drops the last reference and frees the underlying input_dev when
no userspace handle holds it open.

key_up_tick() reads appleir->input_dev and calls input_report_key() /
input_sync() on it.  The timer is armed from appleir_raw_event() with
a HZ/8 (~125 ms) timeout on every keydown and key-repeat report.  If a
key was pressed shortly before the device is disconnected, the timer
can fire after hid_hw_stop() has freed input_dev but before the
teardown drains it.

A simple reorder is not sufficient.  Putting the timer drain first
still leaves a window where a USB URB completion (raw_event) running
during hid_hw_stop() can call mod_timer() and re-arm the timer, which
then fires after hidinput_disconnect() has freed input_dev.  The same
URB-completion window also lets raw_event() reach key_up(), key_down()
and battery_flat() directly, all of which dereference
appleir->input_dev.

Introduce a 'removing' flag on struct appleir, gated by the existing
spinlock.  appleir_remove() sets the flag under the lock and then
shuts down the timer with timer_shutdown_sync(), which both drains any
in-flight callback and permanently disables further mod_timer() calls.
appleir_raw_event() and key_up_tick() bail out early if the flag is
set, so no path can arm or run the timer, or dereference
appleir->input_dev, after remove() has started tearing down.

The keyrepeat and flatbattery branches of appleir_raw_event()
previously called into the input layer without holding the spinlock;
take it now so the flag check is well-defined.  This incidentally
closes a pre-existing read-side race on appleir->current_key in the
keyrepeat branch.

This bug is structurally a sibling of commit 4db2af9292 ("HID:
appletb-kbd: fix UAF in inactivity-timer cleanup path") and has been
present since the driver was introduced.

Fixes: 9a4a5574ce ("HID: appleir: add support for Apple ir devices")
Cc: stable@vger.kernel.org
Signed-off-by: Manish Khadka <maskmemanish@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-29 10:44:12 +02:00
Manish Khadka
46c8beeccd HID: letsketch: fix UAF on inrange_timer at driver unbind
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: 33a5c27934 ("HID: Add new Letsketch tablet driver")
Cc: stable@vger.kernel.org
Signed-off-by: Manish Khadka <maskmemanish@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-29 10:43:23 +02:00
Linus Torvalds
23b5d045ae tracing: Updates for v7.2:
- Remove a redundant IS_ERR() check
 
   trace_pipe_open() already checks for IS_ERR() and does it again in the
   return path. Remove the return check.
 
 - Export seq_buf_putmem_hex() to allow kunit tests against them
 
   To add Kunit tests on seq_buf_putmem_hex(), it needs to be exported.
 
 - Replace strcat() and strcpy() with seq_buf() logic
 
   The code for synthetic events uses a series of strcat() and strcpy() which
   can be error prone. Replace them with seq_buf() logic that does all the
   necessary bound checking.
 
 - Add a lockdep rcu_is_watching() to trace_##event##_enabled() call
 
   The trace_##event##_enabled() is a static branch that is true if the
   "event" is enabled. But this can hide bugs if this logic is in a location
   where RCU is disabled and not "watching". It would only trigger if lockdep
   is enabled and the event is enabled.
 
   Add a "rcu_is_watching()" warning if lockdep is enabled in that helper
   function to trigger regardless if the event is enabled or not.
 
 - Remove the local variable in the trace_printk() macro
 
   For name space integrity, remove the _______STR variable in the
   trace_printk() macro for using the sizeof() macro directly.
 
 - Use guard()s for the trace_recursion_record.c file
 
 - Fix typo in a comment of eventfs_callback() kerneldoc
 
 - Use trace_call__##event() in events called within trace_##event##_enabled()
 
   A couple of events are called within an if block guarded by
   trace_##event##_enabled(). That is a static key that is only enabled when
   the event is enabled. The trace_call_##event() calls the tracepoint code
   directly without adding a redundant static key for that check.
 
 - Allow perf to read synthetic events
 
   Currently, perf does not have the ability to enable a synthetic event. If
   it does, it will either cause a kernel warning or error with "No such
   device". Synthetic events are not much different than kprobes and perf can
   handle fine with a few modifications.
 
 - Replace printk(KERN_WARNING ...) with pr_warn()
 
 - Replace krealloc() on an array with krealloc_array()
 
 - Fix README file path name for synthetic events
 
 - Change tracing_map tracing_map_array to use a flexible array
 
   Instead of allocating a separate pointer to hold the pages field of
   tracing_map_array, allocate the pages field as a flexible array when
   allocating the structure.
 
 - Fold trace_iterator_increment() into trace_find_next_entry_inc()
 
   The function trace_iterator_increment() was only used by
   trace_find_next_entry_inc(). It's not big enough to be a helper function
   for one user. Fold it into its caller.
 
 - Make field_var_str field a flexible array of hist_elt_data
 
   Instead of allocating a separate pointer for the field_var_str array of
   the hist_elt_data structure, allocate it as a flexible array when
   allocating the structure.
 
 - Disable KCOV for trace_irqsoff.c
 
   Like trace_preemptirq.c, trace_irqsoff.c has code that will crash when
   KCOV is enabled on ARM. The irqsoff tracing can be called on ARM because
   the irqsoff tracing code can be run from early interrupt code and produce
   coverage unrelated to syscall inputs.
 
 - Fix warning in __unregister_ftrace_function() called by perf
 
   Perf calls unregister_ftrace_function() without checking if its ftrace_ops
   has already been unregistered. There's an error path where on clean up it
   will unregister the ftrace_ops even if it wasn't registered and causes a
   warning.
 -----BEGIN PGP SIGNATURE-----
 
 iIoEABYKADIWIQRRSw7ePDh/lE+zeZMp5XQQmuv6qgUCajHGbRQccm9zdGVkdEBn
 b29kbWlzLm9yZwAKCRAp5XQQmuv6qqP/AP4nv/Tmv6T7vxMzL7dY/WJ0xT2xkW7Z
 tlejy1AM/RBaTAEAkkgdDNhIAJwxCxsmY6/Zr1mRWzaF7O4kX94KYFcBHww=
 =7nyZ
 -----END PGP SIGNATURE-----

Merge tag 'trace-v7.2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace

Pull tracing updates from Steven Rostedt:

 - Remove a redundant IS_ERR() check

   trace_pipe_open() already checks for IS_ERR() and does it again in
   the return path. Remove the return check.

 - Export seq_buf_putmem_hex() to allow kunit tests against them

   To add Kunit tests on seq_buf_putmem_hex(), it needs to be exported.

 - Replace strcat() and strcpy() with seq_buf() logic

   The code for synthetic events uses a series of strcat() and strcpy()
   which can be error prone. Replace them with seq_buf() logic that does
   all the necessary bound checking.

 - Add a lockdep rcu_is_watching() to trace_##event##_enabled() call

   The trace_##event##_enabled() is a static branch that is true if the
   "event" is enabled. But this can hide bugs if this logic is in a
   location where RCU is disabled and not "watching". It would only
   trigger if lockdep is enabled and the event is enabled.

   Add a "rcu_is_watching()" warning if lockdep is enabled in that
   helper function to trigger regardless if the event is enabled or not.

 - Remove the local variable in the trace_printk() macro

   For name space integrity, remove the _______STR variable in the
   trace_printk() macro for using the sizeof() macro directly.

 - Use guard()s for the trace_recursion_record.c file

 - Fix typo in a comment of eventfs_callback() kerneldoc

 - Use trace_call__##event() in events within trace_##event##_enabled()

   A couple of events are called within an if block guarded by
   trace_##event##_enabled(). That is a static key that is only enabled
   when the event is enabled. The trace_call_##event() calls the
   tracepoint code directly without adding a redundant static key for
   that check.

 - Allow perf to read synthetic events

   Currently, perf does not have the ability to enable a synthetic
   event. If it does, it will either cause a kernel warning or error
   with "No such device". Synthetic events are not much different than
   kprobes and perf can handle fine with a few modifications.

 - Replace printk(KERN_WARNING ...) with pr_warn()

 - Replace krealloc() on an array with krealloc_array()

 - Fix README file path name for synthetic events

 - Change tracing_map tracing_map_array to use a flexible array

   Instead of allocating a separate pointer to hold the pages field of
   tracing_map_array, allocate the pages field as a flexible array when
   allocating the structure.

 - Fold trace_iterator_increment() into trace_find_next_entry_inc()

   The function trace_iterator_increment() was only used by
   trace_find_next_entry_inc(). It's not big enough to be a helper
   function for one user. Fold it into its caller.

 - Make field_var_str field a flexible array of hist_elt_data

   Instead of allocating a separate pointer for the field_var_str array
   of the hist_elt_data structure, allocate it as a flexible array when
   allocating the structure.

 - Disable KCOV for trace_irqsoff.c

   Like trace_preemptirq.c, trace_irqsoff.c has code that will crash
   when KCOV is enabled on ARM. The irqsoff tracing can be called on ARM
   because the irqsoff tracing code can be run from early interrupt code
   and produce coverage unrelated to syscall inputs.

 - Fix warning in __unregister_ftrace_function() called by perf

   Perf calls unregister_ftrace_function() without checking if its
   ftrace_ops has already been unregistered. There's an error path where
   on clean up it will unregister the ftrace_ops even if it wasn't
   registered and causes a warning.

* tag 'trace-v7.2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
  perf/ftrace: Fix WARNING in __unregister_ftrace_function
  tracing: Disable KCOV instrumentation for trace_irqsoff.o
  tracing: Turn hist_elt_data field_var_str into a flexible array
  tracing: Move trace_iterator_increment() into trace_find_next_entry_inc()
  tracing: Simplify pages allocation for tracing_map logic
  tracing: Fix README path for synthetic_events
  tracing: Use krealloc_array() for trace option array growth
  tracing/branch: Use pr_warn() instead of printk(KERN_WARNING)
  tracing: Allow perf to read synthetic events
  HID: Use trace_call__##name() at guarded tracepoint call sites
  cpufreq: amd-pstate: Use trace_call__##name() at guarded tracepoint call site
  tracefs: Fix typo in a comment of eventfs_callback() kerneldoc
  tracing: Switch trace_recursion_record.c code over to use guard()
  tracing: Remove local variable for argument detection from trace_printk()
  tracepoint: Add lockdep rcu_is_watching() check to trace_##name##_enabled()
  tracing: Bound synthetic-field strings with seq_buf
  seq_buf: Export seq_buf_putmem_hex() and add KUnit tests
  tracing: Remove redundant IS_ERR() check in trace_pipe_open()
2026-06-18 20:53:00 -07:00
Linus Torvalds
b7556c8e71 hid-for-linus-2026061601
-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEL65usyKPHcrRDEicpmLzj2vtYEkFAmoxq94ACgkQpmLzj2vt
 YElr1A//RPXn3om4Sm5QeIcbIFHrdVx6Un8QcXVaNSqL8XUB7yMCbsH+zD7NmWSP
 U4wX9bDZ0F8/1gkQh80HuGDEEErSmzAQk8+iE3mhUTXmLmyPn7bgHClMXVmKD1UO
 74f6+57RV7Y0Uo/cgna9hLr3kuSCR5+y81f9esWoXSz8j6BNzml6KyCNcNbbnYlk
 RmS6c5MJ15KxnY593HKr04jWqC1zs++pdcAOmZF3gnwTf7X+Pl3hgP53jCQeAJqH
 AGbXc8N09Nc+JBEJ9zUIgwpU0DwnJRe+/LptIWNGebpSW2/jqfXWabrHjpaXekuX
 6hf+/bnkeoIKDQGIAXSFuqEBsP0WofEbAvCix0+QVEz3MBDtsR6/3h3q+/hbNEgJ
 KrAO7rEHTEEOKPvYiIwQ6cMPAlNRF178k4Havy2EZaaT8w0v9/eovYRIR1J2H/34
 0D7pRb+pyxV0vzuHosa7EKRTTga+8LOwWxLB5lJnG5UhSBUYghihGM6T8pCjBCw5
 BuhcVPpGRT6kreOAIR82sUxfOZHcq6g8rj64iHofPNiPlAr/qkehhHGJ2sBLzeMm
 CPSmYrI0hwULldRunR9/JBMBC44fzfhoRhcQZE1QaJbRu7KYPMWhRPRR8nNR6oEc
 xDnbllexgSya9yAjKZ8mJKb4ywIFUrqpC0xacQmJbZmaXkTX8mI=
 =O/MI
 -----END PGP SIGNATURE-----

Merge tag 'hid-for-linus-2026061601' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid

Pull HID updates from Jiri Kosina:
 "Core:
   - semantic cleanup fixes for 'hid_device_id::driver_data' (Pawel
     Zalewski)

  Multitouch:
   - UX improvement fixes for Yoga Book 9 (Dave Carey)

  Logitech:
   - fix for high resolution scrolling for Logitech HID++ 2.0 devices
     (Lauri Saurus)

  CP2112:
   - fix for cp2112 firmware-based speed configuration, if available
     (Danny Kaehn)

  Wacom:
   - memory corruption and scheduling while atomic and error fixes and
     error handling fixes (Jinmo Yang, Myeonghun Pak)

  New device support:
   - OneXPlayer (Derek J. Clark)
   - HORI Wireless Switch Pad (Hector Zelaya)
   - Rakk Dasig X (Karl Cayme)

  And other assorted small fixes and device ID additions"

* tag 'hid-for-linus-2026061601' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: (39 commits)
  HID: hidpp: fix potential UAF in hidpp_connect_event()
  HID: logitech-hidpp: sync wheel multiplier on wheel mode changes
  HID: intel-thc-hid: intel-quickspi: reset touch IC on system resume
  HID: uhid: convert to hid_safe_input_report()
  HID: hid-goodix-spi: validate report size to prevent stack buffer overflow
  HID: nintendo: add support for HORI Wireless Switch Pad
  HID: multitouch: Honor ContactCount for Yoga Book 9 to suppress ghost contacts
  HID: pidff: Use correct effect type in effect update
  HID: wacom: stop hardware after post-start probe failures
  HID: core: demote warning to debug level
  HID: lenovo: Use KEY_PERFORMANCE capability for ThinkPad X12 Tab Gen 2
  HID: lenovo: Add support for ThinkPad X13 Folio keyboard
  HID: cp2112: Configure I2C bus speed from firmware
  HID: cp2112: Add fwnode support
  HID: hid-lenovo-go: cancel cfg_setup work in hid_go_cfg_remove()
  HID: Input: Add battery list cleanup with devm action
  HID: logitech-hidpp: remove excess kernel-doc member in hidpp_scroll_counter
  HID: wacom: use cleanup.h for wacom_wac_queue_flush() buffer management
  HID: wacom: use GFP_ATOMIC in wacom_wac_queue_flush()
  HID: wacom: fix slab-out-of-bounds write in wacom_wac_queue_insert
  ...
2026-06-18 14:20:39 -07:00
Linus Torvalds
0db1496dcb printk changes for 7.2
-----BEGIN PGP SIGNATURE-----
 
 iQJPBAABCAA5FiEESH4wyp42V4tXvYsjUqAMR0iAlPIFAmoyRfwbFIAAAAAABAAO
 bWFudTIsMi41KzEuMTIsMiwyAAoJEFKgDEdIgJTycTcP/iiyiE+mkR5ruuPNwPsb
 3JH6xKVmwcdC+EeyoNLDcR5aNAiY3GSuwXWo9oVX9HAbA9fC68od7ITuPmQn2j6l
 Rbl9ITtx+mmfhDFrYNIhUXjLlhddojRBPPzfNG68lOzlG7JG75DiIAt30BRuXlbJ
 njn+eeOuRsL2Y5JJn8Vvv9GnV7NyGb5lvrJzAeOv5zc7qngcu3RSUjt6NryfauRn
 ZDBqrhQcDpFJ8cZoLq1D9p83tDStzjHBn9VkpXX7Y4dl5fTowI85CWCgFiXLg1KQ
 KGPq0XXDI1Yw4UNABCxffhxa8nyQyaA35DAllpUNB6hY9QlMZLOGxZjmTtqxeQtP
 SA01c3RpxQAvyiuja1zzvso+Km3o9doHk7gLDq6z++YfO0u0wjh2wS4IVOKfvyIk
 LpK6vNQb0gjNqQmn1EYvBPpinnypSeffGGdkmkEZosr4ACAwEE+wg84422NS4gji
 1erRecvHnlYIF5wIjCkzLeqGwQLSn4TblHf9/4ImaZrjf8uWaxSsBZam5OfjJpsU
 LP3//oeIbEnwBNgPE8bIRw5s4L+cenTeAmS8vl7qR5InshSo1FmtYWFbrmw3/Gfy
 ajV/f67J807XN03p220aRFm1x48aA5eye3VGI7wYnWVwRLIPjEh8nISEa/pV3jxW
 4b/N7+xze8zYV9zTPPRGh1u5
 =yXoT
 -----END PGP SIGNATURE-----

Merge tag 'printk-for-7.2' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux

Pull printk updates from Petr Mladek:

 - Add upper case flavor for printing MAC addresses (%p[mM][U]) and use
   it in the nintendo driver

 - Fix matching of hash_pointers= parameter modes

 - Fix size check of vsprintf() field_width and precision values

 - Add check of size returned by vsprintf()

 - Add KUnit test for restricted pointer printing (%pK)

 - Some code cleanup

* tag 'printk-for-7.2' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux:
  HID: nintendo: Use %pM format specifier for MAC addresses
  vsprintf: Add upper case flavour to %p[mM]
  lib/vsprintf: replace min_t/max_t with min/max
  printk: fix typos in comments
  lib/vsprintf: Require exact hash_pointers mode matches
  vsprintf: Add test for restricted kernel pointers
  vsprintf: Only export no_hash_pointers to test module
  lib/vsprintf: Limit the returning size to INT_MAX
  lib/vsprintf: Fix to check field_width and precision
2026-06-17 12:05:20 -07:00
Jiri Kosina
4baef95dcd Merge branch 'for-7.2/bpf' into for-linus 2026-06-16 22:00:35 +02:00
Jiri Kosina
9b704a7e71 Merge branch 'for-7.2/cleanup_driver_data' into for-linus
- semantic cleanup fixes for 'hid_device_id::driver_data' (Pawel Zalewski)
2026-06-16 21:59:50 +02:00
Jiri Kosina
b0e0c86927 Merge branch 'for-7.2/core' into for-linus 2026-06-16 21:57:57 +02:00
Jiri Kosina
50d9413e70 Merge branch 'for-7.2/cp2112' into for-linus
- fwnode support for cp2112 (Danny Kaehn)
- fix for cp2112 firmware-based speed configuration, if available (Danny Kaehn)
2026-06-16 21:56:57 +02:00
Jiri Kosina
2f67fc4003 Merge branch 'for-7.2/i2c-hid' into for-linus 2026-06-16 21:53:34 +02:00
Jiri Kosina
5a59f62cc0 Merge branch 'for-7.2/logitech' into for-linus
- fix for high resolution scrolling for Logitech HID++ 2.0 devices (Lauri Saurus)
2026-06-16 21:52:56 +02:00
Jiri Kosina
df1d6781b2 Merge branch 'for-7.2/multitouch' into for-linus
- UX improvement fixes for Yoga Book 9 (Dave Carey)
2026-06-16 21:52:21 +02:00
Jiri Kosina
0e15286441 Merge branch 'for-7.2/nintendo' into for-linus
- support for HORI Wireless Switch Pad (Hector Zelaya)
2026-06-16 21:51:31 +02:00
Jiri Kosina
714c861554 Merge branch 'for-7.2/oxp' into for-linus
- suport for OneXPlayer (Derek J. Clark)
2026-06-16 21:50:58 +02:00
Jiri Kosina
cd4f494ba5 Merge branch 'for-7.2/playstation' into for-linus 2026-06-16 21:50:20 +02:00
Jiri Kosina
b81d1b68a9 Merge branch 'for-7.2/rakk' into for-linus
- support for Rakk Dasig X (Karl Cayme)
2026-06-16 21:49:42 +02:00
Jiri Kosina
a78ff6ed8c Merge branch 'for-7.2/sony' into for-linus 2026-06-16 21:49:20 +02:00
Jiri Kosina
8f41a4f927 Merge branch 'for-7.2/wacom' into for-linus
- memory corruption and scheduling while atomic and error fixes (Jinmo Yang)
- error handling fix (Myeonghun Pak)
2026-06-16 21:47:55 +02:00
Jiri Kosina
aa776949fb Merge branch 'for-7.2/wiimote' into for-linus 2026-06-16 21:47:16 +02:00
Jiri Kosina
6df6b1f2c4 HID: hidpp: fix potential UAF in hidpp_connect_event()
If input_register_device() fails, we call input_free_device(), but keep
stale pointer to the old device in hidpp->input, which could potentially
lead to UAF. Fix that by resetting it to NULL before returning from
hidpp_connect_event().

Reported-by: zdi-disclosures@trendmicro.com
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-15 14:57:04 +02:00
Andy Shevchenko
7cde561300 HID: nintendo: Use %pM format specifier for MAC addresses
Convert to %pM instead of using custom code.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Benjamin Tissoires <bentiss@kernel.org>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Link: https://patch.msgid.link/20260603104351.152085-3-andriy.shevchenko@linux.intel.com
Signed-off-by: Petr Mladek <pmladek@suse.com>
2026-06-12 14:20:26 +02:00
Lauri Saurus
f0866517be HID: logitech-hidpp: sync wheel multiplier on wheel mode changes
The hid-logitech-hidpp driver enables high resolution scrolling on
device connect for capable HID++ 2.0 devices. Driver also reads the
wheel capability and caches the returned high resolution wheel scroll
multiplier, that is used for scroll scaling when handling wheel scroll
events.

Wheel mode can also be set externally through HID++ requests, which
can leave the cached multiplier stale and cause incorrect scroll
scaling. If external SetWheelMode HID++ request sets the mode to
low resolution, the cached multiplier is not updated accordingly. This
causes extremely slow scrolling since driver expects multiple wheel
scroll events per detent but is only getting one.

The fix listens for HID++ SetWheelMode request responses and updates
the wheel scroll multiplier based on the set high resolution scroll
mode. The fix has been tested with Logitech G502X lightspeed mouse.

Signed-off-by: Lauri Saurus <saurla@saurla.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-11 15:56:09 +02:00
Danny D.
b7799c3b6a HID: intel-thc-hid: intel-quickspi: reset touch IC on system resume
On the Surface Pro 10 (Meteor Lake) the touchscreen stops working after a
suspend/resume cycle and only recovers after a reboot. The driver logs
"GET_DEVICE_INFO: recv failed: -11" on resume.

This platform suspends through s2idle: /sys/power/mem_sleep exposes
"[s2idle]" as the only state, there is no "deep"/S3 entry at all. The
touch IC nonetheless loses power across that s2idle suspend, the same
way it does across hibernation. quickspi_resume() only re-selects the
THC port, restores interrupts and DMA and sends a HIDSPI_ON command,
assuming the touch IC kept its power and state. When it has actually
lost power the HIDSPI_ON command is never acknowledged and the
descriptor read fails, leaving the touchscreen dead until the module is
reloaded.

quickspi_restore() already handles this for hibernation by
reconfiguring the THC SPI/LTR settings and running reset_tic() to
re-enumerate the device. Make quickspi_resume() do the same when the
device is not a wake source. A wake-enabled device keeps its power and
state across suspend, so it stays on the light restore path: resetting
it would discard a pending wake touch event and break wake-on-touch.

The non-wake path mirrors the existing quickspi_restore() sequence,
including enabling interrupts before reset_tic(), so it introduces no
new ordering relative to code already in the driver.

This change has been validated on a Surface Pro 10 running the
linux-surface kernel across multiple s2idle suspend/resume cycles; it
has not been tested on a mainline build.

Closes: https://github.com/linux-surface/linux-surface/issues/1799
Signed-off-by: Danny D. <d3z.the.dev@gmail.com>
Reviewed-by: Even Xu <even.xu@intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-10 22:07:19 +02:00
Carlos Llamas
63a694c51b HID: uhid: convert to hid_safe_input_report()
Commit 0a3fe972a7 ("HID: core: Mitigate potential OOB by removing
bogus memset()"), added a check in hid_report_raw_event() to reject
reports if the received data size is smaller than expected. This was
intended to prevent OOB errors by no longer allowing zeroing-out of
shorter reports due to the lack of buffer size information.

However, this leads to regressions in hid_report_raw_event(), where
shorter than expected reports are rejected, even though their buffers
are sufficiently large to be zero-padded.

To solve this issue, Benjamin introduced a safer alternative in commit
206342541f ("HID: core: introduce hid_safe_input_report()"), which
forwards the buffer size and allows hid_report_raw_event() to safely
zero-pad the data.

Convert uhid to use hid_safe_input_report() and pass UHID_DATA_MAX as
the buffer size. This prevents the reported regressions [1], allowing
hid core to zero-pad the shorter reports safely as expected.

Cc: stable@vger.kernel.org
Fixes: 0a3fe972a7 ("HID: core: Mitigate potential OOB by removing bogus memset()")
Closes: https://lore.kernel.org/all/ahsh0UtTX6e0ZeHa@google.com/ [1]
Signed-off-by: Carlos Llamas <cmllamas@google.com>
Reviewed-by: Lee Jones <lee@kernel.org>
Closes: https://lore.kernel.org/all/ahsh0UtTX6e0ZeHa@google.com/
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-10 20:32:07 +02:00
Tianchu Chen
db0a0768d0 HID: hid-goodix-spi: validate report size to prevent stack buffer overflow
goodix_hid_set_raw_report() builds a protocol frame in a 128-byte stack
buffer (tmp_buf), writing an 11-12 byte header followed by the
caller-supplied report data.  The HID core caps report size at
HID_MAX_BUFFER_SIZE (16384) by default, while the driver does not set
hid_ll_driver.max_buffer_size and performs no bounds checking before
copying the payload:

    memcpy(tmp_buf + tx_len, buf, len);

A hidraw SET_REPORT ioctl with a report larger than ~116 bytes
overflows the stack buffer.

Add a size check after constructing the header, rejecting reports that
would exceed the buffer capacity.

Discovered by Atuin - Automated Vulnerability Discovery Engine.

Fixes: 75e16c8ce2 ("HID: hid-goodix: Add Goodix HID-over-SPI driver")
Cc: stable@vger.kernel.org
Signed-off-by: Tianchu Chen <flynnnchen@tencent.com>
Reviewed-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-10 18:34:56 +02:00
Hector Zelaya
9146038120 HID: nintendo: add support for HORI Wireless Switch Pad
Add support for the HORI Wireless Switch Pad (vendor 0x0f0d, product
0x00f6), a licensed third-party Nintendo Switch Pro Controller.

The controller reports controller type 0x06 (vs 0x03 for first-party
Pro Controllers) and has the following quirks:

 - SPI flash calibration data is incompatible; use default stick
   calibration values instead.
 - X and Y button bits are swapped compared to first-party controllers;
   add a dedicated button mapping table.
 - Rumble and IMU enable may timeout (no vibration motor in hardware);
   treat as non-fatal for licensed controllers.

Tested over Bluetooth on NixOS with kernel 7.0.5 and 7.0.10:
 - All 14 buttons map correctly
 - Player LED sets on connect
 - Sticks report correctly with default calibration
 - IMU/gyro data streams at 60Hz
 - D-pad reports on ABS_HAT0X/HAT0Y

Device information:
  Bluetooth name: Lic Pro Controller
  Bluetooth HID:  0005:0F0D:00F6

Assisted-by: Kiro:Auto [Amazon Kiro IDE]
Signed-off-by: Hector Zelaya <hector@hectorzelaya.dev>
Reviewed-by: Joshua Peisach <jpeisach@ubuntu.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-10 18:31:33 +02:00
Dave Carey
ef257b8be9 HID: multitouch: Honor ContactCount for Yoga Book 9 to suppress ghost contacts
The INGENIC 17EF:6161 firmware on the Lenovo Yoga Book 9 14IAH10
does not clear stale contact slots when fingers are lifted.  Each
HID report contains up to 10 finger slots, but only the first
ContactCount slots represent valid contacts; the remaining slots
retain TipSwitch=1 with positions from previous touches.

Raw HID capture confirms this: across a 60-second capture with
repeated multi-finger gestures, 90% of frames had more TipSwitch=1
slots than the reported ContactCount.  The ContactCount field itself
is always accurate.

Add MT_QUIRK_CONTACT_CNT_ACCURATE to the MT_CLS_YOGABOOK9I class so
the driver stops processing slots once ContactCount valid contacts
have been consumed, discarding the stale ghost entries per HID
specification section 17.  MT_QUIRK_NOT_SEEN_MEANS_UP (already in
the class) ensures that any slot skipped by this guard is released
via INPUT_MT_DROP_UNUSED at frame sync.

Signed-off-by: Dave Carey <carvsdriver@gmail.com>
Tested-by: Dave Carey <carvsdriver@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-10 18:28:19 +02:00
Oleg Makarenko
b251598b8b HID: pidff: Use correct effect type in effect update
When updating an existing effect, the effect type from the last created
effect was sent to the device instead of the updated one.
This caused incorrect reports when a game creates multiple different
effects and updates only one that is not the last created.

Fixes FFB in multiple games that create multiple simultaneous effects
(Forza Horizon 5/6).

Fixes: 224ee88fe3 ("Input: add force feedback driver for PID devices")
Cc: stable@vger.kernel.org
Tested-by: Oliver Roundtree <oroundtree1@gmail.com>
Co-developed-by: Ryno Kotzé <lemon.xah@gmail.com>
Signed-off-by: Ryno Kotzé <lemon.xah@gmail.com>
Signed-off-by: Oleg Makarenko <oleg@makarenk.ooo>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-10 18:00:28 +02:00
Myeonghun Pak
ec2612b8ad HID: wacom: stop hardware after post-start probe failures
wacom_parse_and_register() starts HID hardware before registering inputs
and initializing pad LEDs/remotes. Those later steps can fail, but their
error paths currently release Wacom resources without stopping the HID
hardware.

Route post-hid_hw_start() failures through hid_hw_stop() before
releasing driver resources.

This issue was identified during our ongoing static-analysis research while
reviewing kernel code.

Fixes: c1d6708bf0 ("HID: wacom: Do not register input devices until after hid_hw_start")
Cc: stable@vger.kernel.org
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Reviewed-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-10 17:48:55 +02:00
Matteo Croce
d0ff08d946 HID: core: demote warning to debug level
The log level for short  messages was changed from debug to warning,
flooding syslog on systems with devices that regularly send
short reports, in my case an UPS:

    $ dmesg |grep -c 'Event data for report .* was too short'
    35

Demote it back to debug level.

Fixes: 0a3fe972a7 ("HID: core: Mitigate potential OOB by removing bogus memset()")
Signed-off-by: Matteo Croce <teknoraver@meta.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-10 17:43:19 +02:00
Vishnu Sankar
4b0f556deb HID: lenovo: Use KEY_PERFORMANCE capability for ThinkPad X12 Tab Gen 2
The X12 Tab Gen 2 emits KEY_PERFORMANCE via Fn+F8 through the raw
event handler but never declared the capability via
input_set_capability(). This prevents userspace tools from
discovering the key through evdev capability bits.

Signed-off-by: Vishnu Sankar <vishnuocv@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-10 17:38:39 +02:00
Vishnu Sankar
df72cacda3 HID: lenovo: Add support for ThinkPad X13 Folio keyboard
Add USB ID support for the ThinkPad X13 detachable keyboard.
The Keyboard uses the same HID raw event protocol as the ThinkPad
X12 Gen 2. The functionality stays the same with X12 Gen 2 Keyboards.

Also declare KEY_PERFORMANCE capability in lenovo_input_configured()
for X13 detachable, allowing userspace to discover the key via evdev
capability bits.

Signed-off-by: Vishnu Sankar <vishnuocv@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-10 17:38:30 +02:00
Danny Kaehn
efab84c398 HID: cp2112: Configure I2C bus speed from firmware
Now that the I2C adapter on the CP2112 can have an associated firmware
node, set the bus speed based on firmware configuration

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Danny Kaehn <danny.kaehn@plexus.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-10 17:34:39 +02:00
Danny Kaehn
c0be05f68a HID: cp2112: Add fwnode support
Support describing the CP2112's I2C and GPIO interfaces in firmware.

Bindings between the firmware nodes and the functions of the device
are distinct between ACPI and DeviceTree.

For ACPI, the i2c_adapter will use the child with _ADR equal to Zero
and the gpio_chip will use the child with _ADR equal to One.

For DeviceTree, the i2c_adapter will use the child with name "i2c",
but the gpio_chip will share a firmware node with the CP2112.

Signed-off-by: Danny Kaehn <danny.kaehn@plexus.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Tested-by: Jacky Huang <jackyhuang@nvidia.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-10 17:34:39 +02:00
Manish Khadka
73fde0cbff HID: hid-lenovo-go: cancel cfg_setup work in hid_go_cfg_remove()
hid_go_cfg_probe() initialises drvdata.go_cfg_setup and schedules it
to run 2 ms later:

    INIT_DELAYED_WORK(&drvdata.go_cfg_setup, &cfg_setup);
    schedule_delayed_work(&drvdata.go_cfg_setup, msecs_to_jiffies(2));

cfg_setup() dereferences drvdata.hdev to issue MCU command requests.
hid_go_cfg_remove() tears down sysfs and stops the HID device, but
never drains the delayed work.  If the device is unbound within the
2 ms scheduling delay (a probe failure rolling back via remove, or a
fast rmmod after probe), the work fires after hid_destroy_device()
has dropped its reference and released the underlying hdev struct,
leaving cfg_setup() with a stale drvdata.hdev pointer.

Mirror the sibling driver hid-lenovo-go-s.c, whose hid_gos_cfg_remove()
already calls cancel_delayed_work_sync() on its analogous work, and
drain go_cfg_setup at the top of hid_go_cfg_remove().  The cancel
must come before guard(mutex)(&drvdata.cfg_mutex) because cfg_setup()
acquires that mutex; reversing the order would deadlock.

Fixes: d69ccfcbc9 ("HID: hid-lenovo-go: Add Lenovo Legion Go Series HID Driver")
Cc: stable@vger.kernel.org
Signed-off-by: Manish Khadka <maskmemanish@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-03 14:18:18 +02:00
Rafael Passos
426e5846eb HID: Input: Add battery list cleanup with devm action
The batteries list (hdev->batteries) is not cleaned up during
hidinput_disconnect(), but struct hid_battery entries are allocated
with devm_kzalloc.
When a driver is unbound (e.g. during devicereprobe), devm frees those
entries while their list_head nodesremain dangling in hdev->batteries,
which persists across rebinds.

Link: https://lore.kernel.org/all/20260602011949.2825852-1-rafael@rcpassos.me/
Fixes: 4a58ae85c3 ("HID: input: Add support for multiple batteries per device")
Signed-off-by: Rafael Passos <rafael@rcpassos.me>
Acked-by: Lucas Zampieri <lcasmz54@gmail.com>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2026-06-02 10:28:39 +02:00
Rosen Penev
f22a5db8a7 HID: logitech-hidpp: remove excess kernel-doc member in hidpp_scroll_counter
The @dev member described in the kernel-doc does not exist in the
struct. Remove the stale entry.

Fixes: 0610430e3d ("HID: logitech-hidpp: add input_device ptr to struct hidpp_device")
Assisted-by: opencode:big-pickle

Signed-off-by: Rosen Penev <rosenp@gmail.com>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2026-06-01 18:41:14 +02:00
Jinmo Yang
cb605d48da HID: wacom: use cleanup.h for wacom_wac_queue_flush() buffer management
Use __free(kfree) cleanup facility for the temporary buffer in
wacom_wac_queue_flush() to simplify error paths and ensure the buffer
is freed automatically when it goes out of scope.

Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2026-06-01 18:39:07 +02:00
Jinmo Yang
55f1ad573e HID: wacom: use GFP_ATOMIC in wacom_wac_queue_flush()
wacom_wac_queue_flush() is called via the .raw_event callback
(wacom_raw_event → wacom_wac_pen_serial_enforce → wacom_wac_queue_flush).
For USB HID devices, this callback is invoked from hid_irq_in(), which
is a URB completion handler running in atomic context. Using GFP_KERNEL
in this path can sleep, leading to a "scheduling while atomic" bug.

Use GFP_ATOMIC instead. The existing code already handles allocation
failure by skipping the fifo entry and continuing.

Reported-by: Sashiko-bot <sashiko-bot@kernel.org>
Fixes: 5e013ad206 ("HID: wacom: Remove static WACOM_PKGLEN_MAX limit")
Cc: stable@vger.kernel.org
Reviewed-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2026-06-01 18:39:07 +02:00
Jinmo Yang
6b3014ec0e HID: wacom: fix slab-out-of-bounds write in wacom_wac_queue_insert
wacom_wac_queue_insert() calls kfifo_skip() in a loop when the kfifo
doesn't have enough space for the incoming report. If the kfifo is
empty, kfifo_skip() reads stale data left in the kmalloc'd buffer
via __kfifo_peek_n() and interprets it as a record length, advancing
fifo->out by that garbage value. This corrupts the internal kfifo
state, causing kfifo_unused() to return a value much larger than the
actual buffer size, which bypasses __kfifo_in_r()'s guard:

  if (len + recsize > kfifo_unused(fifo))
      return 0;

kfifo_copy_in() then performs an out-of-bounds memcpy, writing up to
3842 bytes past the 256-byte buffer.

Add a !kfifo_is_empty() condition to the while loop so kfifo_skip()
is never called on an empty fifo, and check the return value of
kfifo_in() to reject reports that are too large for the fifo.

Suggested-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Fixes: 5e013ad206 ("HID: wacom: Remove static WACOM_PKGLEN_MAX limit")
Cc: stable@vger.kernel.org
Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
Reviewed-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2026-06-01 18:37:23 +02:00
Harrison Vanderbyl
3a1e4e77e3 hid: Pen battery quirk for Surface Pro 12in
The pen setup for this device uses bluetooth for
communicating battery levels and status instead of
reporting it over i2c.

Without this quirk, the device either reports an
extra, broken phantom battery, or hangs.

Signed-off-by: Harrison Vanderbyl <harrison.vanderbyl@gmail.com>
Acked-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2026-06-01 18:36:22 +02:00