Linux Input/HID development
 help / color / mirror / Atom feed
* [REGRESSION] Sino Wealth 258a:002a keyboard enters stuck shift state on USB disconnect
@ 2026-06-04 15:43 Orlando Ulises Aguilar Rojas
  2026-06-05  7:03 ` Benjamin Tissoires
  0 siblings, 1 reply; 3+ messages in thread
From: Orlando Ulises Aguilar Rojas @ 2026-06-04 15:43 UTC (permalink / raw)
  To: linux-input; +Cc: linux-usb, benjamin.tissoires

Hi everyone,

I am reporting a regression that I first observed in linux-zen
7.0.8-zen1. The zen-kernel maintainer (heftig) confirmed that the
responsible commits also landed in upstream stable 7.0.10, so this is
not zen-specific:
  - HID: pass the buffer size to hid_report_raw_event
  - HID: core: introduce hid_safe_input_report()


--- Summary ---

A Sino Wealth 258a:002a generic mechanical keyboard (Machenike K500)
enters a permanent "stuck shift" / modifier ghosting state when any
other USB device disconnects from the host. This worked flawlessly on
7.0.7.

--- Root cause ---

Before these commits, a report where csize < rsize returned -EINVAL
and was discarded in hid_report_raw_event().

After the commits, the same condition is silently zero-padded and
processed. Additionally, drivers/hid/usbhid/hid-core.c was updated to
call hid_safe_input_report() passing urb->transfer_buffer_length as
bufsize instead of urb->actual_length. Since the USB transfer
buffer (typically 64 bytes) is always larger than rsize for this
device, the new bsize < rsize early-exit guard never fires. The code
reaches the zero-fill path unconditionally.

This produces no kernel warnings — dbg_hid is not visible in normal
dmesg — which is why the fault leaves no trace in the logs.


--- Affected device ---

Bus 001 Device XXX: ID 258a:002a Sino Wealth (Machenike K500)
USB Host: Intel xHCI 0000:00:14.0, port 1-2.2

This keyboard uses a non-compliant NKRO implementation. It registers a
spurious mouse interface alongside its real keyboard interfaces:

  SINO WEALTH Gaming Keyboard        -> input0 (interface 0)
  SINO WEALTH Gaming Keyboard        -> input1 (interface 1)
  SINO WEALTH Gaming Keyboard Mouse  -> input1 (interface 1) <- spurious

That spurious mouse interface has always emitted short/malformed
reports. Under 7.0.7 those reports were safely discarded. Under 7.0.8+
they are zero-padded, processed, and produce a modifier key event with
Shift held.


--- Exact trigger ---

The fault occurs at runtime, not at boot. Boot dmesg is structurally
identical on both kernels.

Trigger captured via udevadm monitor: when a separate Realtek wireless
mouse receiver fires unbind -> remove on the USB bus, the Sino Wealth
spurious mouse interface reacts to the hub topology change, emits a
short report, and the zero-fill behavior causes the keyboard to output
"!@#!@#" (Shift held). Physically unplugging and replugging the
keyboard does not clear this state; a system reboot is required to
restore normal functionality.


--- What does NOT mitigate the issue ---

  - Forcing power/control = on on the device USB path
  - usbhid.quirks=0x258a:002a:0x00000004 boot parameter


--- Suggested fix ---

Reconsider the zero-fill path introduced in hid_report_raw_event():
the pre-7.0.8 behavior (discard short reports with -EINVAL) was safer
for devices with non-compliant NKRO implementations that have always
emitted structurally invalid reports.

If the zero-fill behavior is intentional, adding 258a:002a to the HID
quirks table with a discard-on-short-report quirk would be an
acceptable mitigation.

--- System ---

OS:             CachyOS x86_64
Working kernel: Linux 7.0.7-zen2-1-zen
Broken kernel:  Linux 7.0.8-zen1 through 7.0.11-zen (upstream: 7.0.10+)
CPU:            Intel Core i5-13600KF

dmesg (working/broken) and udev runtime event logs are available on
request, or can be viewed in the downstream zen-kernel issue:
https://github.com/zen-kernel/zen-kernel/issues/414

Thanks for your time.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [REGRESSION] Sino Wealth 258a:002a keyboard enters stuck shift state on USB disconnect
  2026-06-04 15:43 [REGRESSION] Sino Wealth 258a:002a keyboard enters stuck shift state on USB disconnect Orlando Ulises Aguilar Rojas
@ 2026-06-05  7:03 ` Benjamin Tissoires
  2026-06-05  9:00   ` Michal Pecio
  0 siblings, 1 reply; 3+ messages in thread
From: Benjamin Tissoires @ 2026-06-05  7:03 UTC (permalink / raw)
  To: Orlando Ulises Aguilar Rojas; +Cc: linux-input, linux-usb, benjamin.tissoires

Hi,

On Jun 04 2026, Orlando Ulises Aguilar Rojas wrote:
> Hi everyone,
> 
> I am reporting a regression that I first observed in linux-zen
> 7.0.8-zen1. The zen-kernel maintainer (heftig) confirmed that the
> responsible commits also landed in upstream stable 7.0.10, so this is
> not zen-specific:
>   - HID: pass the buffer size to hid_report_raw_event
>   - HID: core: introduce hid_safe_input_report()

This is... surprising:
these commits are restoring the previous behavior that has been running
under linux for the past 20+ years, that was broken by 0a3fe972a7cb
("HID: core: Mitigate potential OOB by removing bogus memset()").

So basically, there was a short period of time in 7.0 (it was introduced
in 7.0-rc5) where the device would have been working fine.

Can you check if kernel v6.18.21 (the last one before 0a3fe972a7cb was
backported to the 6.18 series) was also showing the behavior? I strongly
suspect it will, unless there was a USB change that also triggered this
bug.

anyway...

> 
> 
> --- Summary ---
> 
> A Sino Wealth 258a:002a generic mechanical keyboard (Machenike K500)
> enters a permanent "stuck shift" / modifier ghosting state when any
> other USB device disconnects from the host. This worked flawlessly on
> 7.0.7.

ouch, very much ouch

> 
> --- Root cause ---
> 
> Before these commits, a report where csize < rsize returned -EINVAL
> and was discarded in hid_report_raw_event().
> 
> After the commits, the same condition is silently zero-padded and
> processed. Additionally, drivers/hid/usbhid/hid-core.c was updated to
> call hid_safe_input_report() passing urb->transfer_buffer_length as
> bufsize instead of urb->actual_length. Since the USB transfer
> buffer (typically 64 bytes) is always larger than rsize for this
> device, the new bsize < rsize early-exit guard never fires. The code
> reaches the zero-fill path unconditionally.

Yes. This is expected

> 
> This produces no kernel warnings — dbg_hid is not visible in normal
> dmesg — which is why the fault leaves no trace in the logs.
> 
> 
> --- Affected device ---
> 
> Bus 001 Device XXX: ID 258a:002a Sino Wealth (Machenike K500)
> USB Host: Intel xHCI 0000:00:14.0, port 1-2.2
> 
> This keyboard uses a non-compliant NKRO implementation. It registers a
> spurious mouse interface alongside its real keyboard interfaces:
> 
>   SINO WEALTH Gaming Keyboard        -> input0 (interface 0)
>   SINO WEALTH Gaming Keyboard        -> input1 (interface 1)
>   SINO WEALTH Gaming Keyboard Mouse  -> input1 (interface 1) <- spurious
> 
> That spurious mouse interface has always emitted short/malformed
> reports. Under 7.0.7 those reports were safely discarded. Under 7.0.8+
> they are zero-padded, processed, and produce a modifier key event with
> Shift held.
> 
> 
> --- Exact trigger ---
> 
> The fault occurs at runtime, not at boot. Boot dmesg is structurally
> identical on both kernels.
> 
> Trigger captured via udevadm monitor: when a separate Realtek wireless
> mouse receiver fires unbind -> remove on the USB bus, the Sino Wealth
> spurious mouse interface reacts to the hub topology change, emits a
> short report, and the zero-fill behavior causes the keyboard to output
> "!@#!@#" (Shift held).

That is seriously wrong. It's not uncommon for keyboards to expose a
mouse node when the support "macros" that you can configure in their
firmware. That allows them to send button events, or even control the mouse.

That being said, if your keyboard reacts to USB events from other
devices, then there is something seriously wrong in the firmware.

In any cases, the fix is not to revert the restored behavior, but to fix
your bogus device.

> Physically unplugging and replugging the
> keyboard does not clear this state; a system reboot is required to
> restore normal functionality.
> 
> 
> --- What does NOT mitigate the issue ---
> 
>   - Forcing power/control = on on the device USB path
>   - usbhid.quirks=0x258a:002a:0x00000004 boot parameter
> 
> 
> --- Suggested fix ---
> 
> Reconsider the zero-fill path introduced in hid_report_raw_event():
> the pre-7.0.8 behavior (discard short reports with -EINVAL) was safer
> for devices with non-compliant NKRO implementations that have always
> emitted structurally invalid reports.

No, this is not possible, the behavior was restored because it broke
several devices.

> 
> If the zero-fill behavior is intentional, adding 258a:002a to the HID
> quirks table with a discard-on-short-report quirk would be an
> acceptable mitigation.

Well, you have 2 options actually:
- write a new kernel driver that maps to the device and discards short
  reports emitted on the mouse node
- or write a HID-BPF program (see
  https://libevdev.pages.freedesktop.org/udev-hid-bpf/tutorial.html)
  that does exactly that as well, but it's simpler to debug/implement
  because you don't need a full kernel rebuild.

I don't see the benefit of adding a new generic quirk for fixing 1
device.

If I were you, I would seriously lean toward a HID-BPF program, because
that's much easier to write and test.

Cheers,
Benjamin

> 
> --- System ---
> 
> OS:             CachyOS x86_64
> Working kernel: Linux 7.0.7-zen2-1-zen
> Broken kernel:  Linux 7.0.8-zen1 through 7.0.11-zen (upstream: 7.0.10+)
> CPU:            Intel Core i5-13600KF
> 
> dmesg (working/broken) and udev runtime event logs are available on
> request, or can be viewed in the downstream zen-kernel issue:
> https://github.com/zen-kernel/zen-kernel/issues/414
> 
> Thanks for your time.
> 

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [REGRESSION] Sino Wealth 258a:002a keyboard enters stuck shift state on USB disconnect
  2026-06-05  7:03 ` Benjamin Tissoires
@ 2026-06-05  9:00   ` Michal Pecio
  0 siblings, 0 replies; 3+ messages in thread
From: Michal Pecio @ 2026-06-05  9:00 UTC (permalink / raw)
  To: Benjamin Tissoires
  Cc: Orlando Ulises Aguilar Rojas, linux-input, linux-usb,
	benjamin.tissoires

On Fri, 5 Jun 2026 09:03:42 +0200, Benjamin Tissoires wrote:
> > Trigger captured via udevadm monitor: when a separate Realtek
> > wireless mouse receiver fires unbind -> remove on the USB bus, the
> > Sino Wealth spurious mouse interface reacts to the hub topology
> > change, emits a short report, and the zero-fill behavior causes the
> > keyboard to output "!@#!@#" (Shift held).  
> 
> That is seriously wrong. It's not uncommon for keyboards to expose a
> mouse node when the support "macros" that you can configure in their
> firmware. That allows them to send button events, or even control the
> mouse.
> 
> That being said, if your keyboard reacts to USB events from other
> devices, then there is something seriously wrong in the firmware.
> 
> In any cases, the fix is not to revert the restored behavior, but to
> fix your bogus device.

It's practically impossible for a USB device to respond to disconnection
of another device, but I recall reports of disconnections apparently
causing corruption of other ongoing transactions. These should complete
with -EPIPE, -EPROTO or similar status then. Possibly the kernel or the
device doesn't handle things rigth.

Perhaps a packet trace from usbmon or Wireshark would help understand
what's going on.

> > Physically unplugging and replugging the
> > keyboard does not clear this state; a system reboot is required to
> > restore normal functionality.

When I disconnect a keyboard while holding the SHIFT key, it turns off.
Is there more to this bug than just failing to ignore bogus reports? 

Regards,
Michal

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-06-05  9:00 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-04 15:43 [REGRESSION] Sino Wealth 258a:002a keyboard enters stuck shift state on USB disconnect Orlando Ulises Aguilar Rojas
2026-06-05  7:03 ` Benjamin Tissoires
2026-06-05  9:00   ` Michal Pecio

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox