From: predze Date: Fri, 27 Mar 2026 00:00:00 +0100 Subject: [PATCH] hid: usbhid: discard uniq strings containing control characters usb_string() is called directly to populate hid->uniq, bypassing any cached/validated copy in udev->serial. Some USB HID devices (e.g. the ASUS ROG Azoth 0b05:1a85) return a serial string with embedded ASCII control characters (< 0x20) on cold boot or for certain interfaces. These control characters end up in the UNIQ= property of the kernel uevent, where systemd's property_is_valid() (sd-device.c) rejects them, causing logind TakeDevice to fail with ENODEV/EPERM for the affected input event nodes. The result is that Wayland compositors cannot claim the input devices. Clear hid->uniq if the string returned by usb_string() contains any ASCII control characters or DEL (0x7f). Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2448678 Ref: https://github.com/systemd/systemd/issues/41296 --- drivers/hid/usbhid/hid-core.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -1427,7 +1427,23 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id * snprintf(hid->phys + len, sizeof(hid->phys) - len, "%d", intf->altsetting[0].desc.bInterfaceNumber); - if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0) - hid->uniq[0] = 0; + if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0) { + hid->uniq[0] = 0; + } else { + const unsigned char *s; + + /* + * Discard uniq if it contains ASCII control characters or DEL. + * Some devices return a garbled serial on certain interfaces; + * control chars in UNIQ= cause systemd's property_is_valid() to + * reject the device, breaking logind TakeDevice for Wayland. + */ + for (s = hid->uniq; *s; s++) { + if (*s < 0x20 || *s == 0x7f) { + hid->uniq[0] = 0; + break; + } + } + } usbhid = kzalloc(sizeof(*usbhid), GFP_KERNEL);