#1140539 systemd: sd-device fails to parse uevent properties with control characters in USB serial

Package:
systemd
Source:
systemd
Description:
system and service manager
Submitter:
Andreas Noteng
Date:
2026-06-22 11:53:02 UTC
Severity:
normal
#1140539#5
Date:
2026-06-22 11:50:52 UTC
From:
To:
Dear Maintainer,

While investigating why a USB input device's pointer is unusable under
GNOME/Wayland, I found that sd-device fails to parse two uevent properties
(UNIQ, HID_UNIQ) for this device because its USB serial number string
contains control characters. I am reporting the sd-device parse failure as
the concrete, reproducible defect. I have NOT been able to prove it is the
cause of the pointer problem (see "Open question"), so I describe what is
observed and leave the conclusion open.

== Hardware ==

Trapper Data "Mousetrapper Advanced++", USB ID 0d24:000b. Composite HID
device, four interfaces (keyboard, mouse, consumer control, system control).
Its USB serial number contains control bytes 0x14 and 0x16:

  usb 3-1.3.3.4: SerialNumber: 4W5205\x14\x16

== Reproducible defect: sd-device rejects the uevent properties ==

`udevadm test` on an event node shows sd-device rejecting UNIQ / HID_UNIQ
with EINVAL because the values contain control characters (shown here as
<0x14><0x16>; they print as ^T^V):

  sd-device: Failed to handle uevent entry 'UNIQ="4W5205<0x14><0x16>"', ignoring: Invalid argument
  sd-device: Failed to handle uevent entry 'HID_UNIQ=4W5205<0x14><0x16>', ignoring: Invalid argument

All four interfaces carry the same malformed uniq:

  event13 uniq: 4W5205^T^V
  event14 uniq: 4W5205^T^V
  event15 uniq: 4W5205^T^V
  event16 uniq: 4W5205^T^V

The error originates in sd-device's uevent parser
(src/libsystemd/sd-device/sd-device.c, "Failed to handle uevent entry ...").

== Observed symptom ==

Under GNOME/Wayland (mutter) the pointer does not move and buttons do not
register. The device works when read directly as root with
`libinput debug-events` (full POINTER_MOTION / POINTER_BUTTON /
POINTER_SCROLL), and under an Xorg session (X opens the evdev nodes directly)
once the input nodes carry seat/uaccess tags. So kernel, evdev and libinput
handle it fine; only the logind-mediated path used by Wayland compositors
fails for this device.

With the device plugged in, `fuser` shows systemd-logind holding the three
keyboard-capable nodes but NOT the pointer-only node:

  /dev/input/event13 (keyboard):         systemd-logind
  /dev/input/event15 (consumer control): systemd-logind
  /dev/input/event16 (system control):   systemd-logind
  /dev/input/event14 (mouse/pointer):    no holder

so mutter never receives the pointer node.

== Open question (cause not established) ==

I cannot establish that the parse failure causes the seating problem:

  - In `udevadm test` the bad entry is only "ignored"; the node still ends up
    with seat/uaccess tags and ID_FOR_SEAT, so the EINVAL does not by itself
    prevent tagging.
  - All four interfaces carry the identical malformed uniq and hit the same
    EINVAL, yet only the pointer-only node (ID_INPUT_MOUSE, no keyboard
    capability) fails to be taken by logind; the three keyboard-capable nodes
    are taken.

So an additional, unidentified factor singles out the pointer-only node. I
report the reproducible sd-device defect plus the observations and leave the
connection to someone with deeper knowledge of the logind/sd-device path.

== Workaround ==

  SUBSYSTEM=="input", ATTRS{idVendor}=="0d24", ATTRS{idProduct}=="000b", \
      TAG+="seat", TAG+="uaccess"

restores the device under Xorg. It does not restore it under Wayland;
switching to Xorg, or mirroring the device through uinput, is the only
Wayland workaround found.

== Regression note ==

The same device worked on the same machine under Ubuntu (default install,
probably 25.10 or 26.04, GNOME, most likely a Wayland session; exact
systemd/kernel versions no longer available). It broke after migrating to
Debian testing. This suggests a systemd and/or kernel version difference
rather than a fundamental incompatibility, but I cannot pin down which.

== Possible fix direction ==

The origin is firmware emitting control characters in a USB string descriptor
(out of scope here). Robustness could be improved by sd-device
sanitising/tolerating control characters in uevent property values, and/or by
the kernel stripping non-printable characters from serial / uniq before
exposing them. Likely worth forwarding upstream (systemd, possibly kernel).

== Versions ==

systemd 260 (Debian testing). Not yet tested on 261 (unstable).

Happy to provide full udevadm test, dmesg, fuser and libinput debug-events
logs, or to test patches.