From 1995a41d7cd1c4a97714bcd511c17e271b49ca6f Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 31 Oct 2026 22:15:52 +0900 Subject: [PATCH] udev: detect USB smartcard readers through the usb-interface hwdb Instead of setting ID_SMARTCARD_READER from a direct match on ID_USB_INTERFACES in 60-fido-id.rules, set it for devices exposing a smartcard (CCID) interface, i.e. interface class 0b, in the usb-interface hwdb. The hwdb lookup is done in 50-udev-default.rules.in, which is processed before 60-fido-id.rules, so the subsequent rules that match on ID_SMARTCARD_READER are not affected. As the property can be set to either 0 or 1 in the hwdb, make the rules in 70-uaccess.rules.in and 99-systemd.rules.in match on "1" instead of any non-empty value. This makes the property, and the tags and the target depending on it, require hwdb.bin, which matters when a smartcard reader is already used in the initrd. Mention that in NEWS. --- NEWS | 9 +++++++++ hwdb.d/60-usb-interface.hwdb | 7 +++++++ hwdb.d/parse_hwdb.py | 1 + rules.d/60-fido-id.rules | 1 - rules.d/70-uaccess.rules.in | 2 +- rules.d/99-systemd.rules.in | 2 +- 6 files changed, 19 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 61474808764..252f7ae2716 100644 --- a/NEWS +++ b/NEWS @@ -150,6 +150,15 @@ CHANGES WITH 263 in spe: adds rustc >= 1.85, bindgen >= 0.71.1 and meson >= 1.4.0 as optional build dependencies. + * The ID_SMARTCARD_READER udev property for USB smartcard (CCID) + readers is now set through the udev hwdb instead of by a udev rule + that directly matches the USB interfaces. If a smartcard reader is + already used in the initrd, e.g. by systemd-cryptsetup to activate + encrypted host disks, the initrd must now include hwdb.bin. + Otherwise, the reader does not get the property and + systemd-cryptsetup may not find the device, so the activation may no + longer work. + Changes in the system and service manager: * LockPersonality= no longer refuses querying the personality with diff --git a/hwdb.d/60-usb-interface.hwdb b/hwdb.d/60-usb-interface.hwdb index 534005161a3..eb97b47bc80 100644 --- a/hwdb.d/60-usb-interface.hwdb +++ b/hwdb.d/60-usb-interface.hwdb @@ -18,6 +18,9 @@ # # Specify if a device is a printer # ID_PRINTER=0|1 +# +# Specify if a device is a smartcard reader +# ID_SMARTCARD_READER=0|1 # USB3 Vision devices exposing the device control interface usb-interface:v*p*:ef0500:* @@ -27,3 +30,7 @@ usb-interface:v*p*:ef0500:* # Printers (interface class 07, subclass 01) usb-interface:v*p*:0701??:* ID_PRINTER=1 + +# Smartcard readers (interface class 0b, CCID) +usb-interface:v*p*:0b????:* + ID_SMARTCARD_READER=1 diff --git a/hwdb.d/parse_hwdb.py b/hwdb.d/parse_hwdb.py index f1990224d10..0e8934ac293 100755 --- a/hwdb.d/parse_hwdb.py +++ b/hwdb.d/parse_hwdb.py @@ -222,6 +222,7 @@ def property_grammar(): ('ID_LINK_DIR', Word(alphanums + '-_')), ('ID_USB3_VISION', zero_one), ('ID_PRINTER', zero_one), + ('ID_SMARTCARD_READER', zero_one), ('POINTINGSTICK_SENSITIVITY', INTEGER), ('ID_INTEGRATION', Or(('internal', 'external'))), ('ID_INPUT_TOUCHPAD_INTEGRATION', Or(('internal', 'external'))), diff --git a/rules.d/60-fido-id.rules b/rules.d/60-fido-id.rules index 48c259ee04e..f0855411dc3 100644 --- a/rules.d/60-fido-id.rules +++ b/rules.d/60-fido-id.rules @@ -7,7 +7,6 @@ SUBSYSTEM=="hidraw", IMPORT{program}="fido_id" # Tag any form of security token as such ENV{ID_SECURITY_TOKEN}=="1", TAG+="security-device" -SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{ID_USB_INTERFACES}=="*:0b????:*", ENV{ID_SMARTCARD_READER}="1" # Tag any CCID device (i.e. Smartcard Reader) as security token ENV{ID_SMARTCARD_READER}=="1", TAG+="security-device" diff --git a/rules.d/70-uaccess.rules.in b/rules.d/70-uaccess.rules.in index 7ec0e72a48d..999f3cc9adb 100644 --- a/rules.d/70-uaccess.rules.in +++ b/rules.d/70-uaccess.rules.in @@ -61,7 +61,7 @@ SUBSYSTEM=="misc", KERNEL=="kvm", TAG+="uaccess" {% endif %} # smart-card readers -ENV{ID_SMARTCARD_READER}=="?*", TAG+="uaccess" +ENV{ID_SMARTCARD_READER}=="1", TAG+="uaccess" # (USB) authentication devices ENV{ID_SECURITY_TOKEN}=="?*", TAG+="uaccess" diff --git a/rules.d/99-systemd.rules.in b/rules.d/99-systemd.rules.in index 3c85126f35a..aada3d5fa4d 100644 --- a/rules.d/99-systemd.rules.in +++ b/rules.d/99-systemd.rules.in @@ -55,7 +55,7 @@ SUBSYSTEM=="net", KERNEL!="lo", TAG+="systemd", ENV{SYSTEMD_ALIAS}+="/sys/subsys SUBSYSTEM=="bluetooth", TAG+="systemd", ENV{SYSTEMD_ALIAS}+="/sys/subsystem/bluetooth/devices/%k", \ ENV{SYSTEMD_WANTS}+="bluetooth.target", ENV{SYSTEMD_USER_WANTS}+="bluetooth.target" -ENV{ID_SMARTCARD_READER}=="?*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="smartcard.target", ENV{SYSTEMD_USER_WANTS}+="smartcard.target" +ENV{ID_SMARTCARD_READER}=="1", TAG+="systemd", ENV{SYSTEMD_WANTS}+="smartcard.target", ENV{SYSTEMD_USER_WANTS}+="smartcard.target" TAG=="security-device", TAG+="systemd" SUBSYSTEM=="sound", KERNEL=="controlC*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="sound.target", ENV{SYSTEMD_USER_WANTS}+="sound.target"