Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fido_id does not recognize Yubikeys, Token2, and Solokeys 2 tokens #29278

Closed
abbra opened this issue Sep 22, 2023 · 1 comment
Closed

fido_id does not recognize Yubikeys, Token2, and Solokeys 2 tokens #29278

abbra opened this issue Sep 22, 2023 · 1 comment
Labels
bug 🐛 Programming errors, that need preferential fixing hwdb udev

Comments

@abbra
Copy link

abbra commented Sep 22, 2023

systemd version the issue has been seen with

254.1

Used distribution

Fedora 39 beta

Linux kernel version used

6.5.3-300.fc39.x86_64

CPU architectures issue was seen on

x86_64

Component

systemd-hwdb, systemd-udevd, udevadm

Expected behaviour you didn't see

fido_id tool is supposed to recognize FIDO2 USB token and return

ID_FIDO_TOKEN=1
ID_SECURITY_TOKEN=1

Unexpected behaviour you saw

Running fido_id /sys/path causes it to use a parent path to the device and then attempt to open report_descriptor at that level. Howeverv, the report descriptor is available in a different place which means fido_id never gets to open it and fails to recognize the token.

I tried with different keys, all of them fail:

# find /sys/ -name report_descriptor -print |xargs  -I % sh -c "cat \$(dirname %)/../../product;  echo %; od -t x1 -N16 % ; /usr/lib/udev/fido_id %"
Solo 4.1.5
/sys/devices/pci0000:00/0000:00:07.0/0000:20:00.0/0000:21:02.0/0000:22:00.0/usb5/5-2/5-2.3/5-2.3:1.0/0003:0483:A2CA.001D/report_descriptor
0000000 06 d0 f1 09 01 a1 01 09 20 15 00 26 ff 00 75 08
0000020
Failed to get device from syspath /sys/devices/pci0000:00/0000:00:07.0/0000:20:00.0/0000:21:02.0/0000:22:00.0/usb5/5-2/5-2.3/5-2.3:1.0/0003:0483:A2CA.001D/report_descriptor: No such device
YubiKey OTP+FIDO+CCID
/sys/devices/pci0000:00/0000:00:14.0/usb3/3-2/3-2:1.1/0003:1050:0407.0017/report_descriptor
0000000 06 d0 f1 09 01 a1 01 09 20 15 00 26 ff 00 75 08
0000020
Failed to get device from syspath /sys/devices/pci0000:00/0000:00:14.0/usb3/3-2/3-2:1.1/0003:1050:0407.0017/report_descriptor: No such device
YubiKey OTP+FIDO+CCID
/sys/devices/pci0000:00/0000:00:14.0/usb3/3-2/3-2:1.0/0003:1050:0407.0016/report_descriptor
0000000 05 01 09 06 a1 01 05 07 19 e0 29 e7 15 00 25 01
0000020
Failed to get device from syspath /sys/devices/pci0000:00/0000:00:14.0/usb3/3-2/3-2:1.0/0003:1050:0407.0016/report_descriptor: No such device
FIDO2 Security Key
/sys/devices/pci0000:00/0000:00:14.0/usb3/3-9/3-9:1.1/0003:349E:0022.0003/report_descriptor
0000000 06 d0 f1 09 01 a1 01 09 20 15 00 26 ff 00 75 08
0000020
Failed to get device from syspath /sys/devices/pci0000:00/0000:00:14.0/usb3/3-9/3-9:1.1/0003:349E:0022.0003/report_descriptor: No such device
FIDO2 Security Key
/sys/devices/pci0000:00/0000:00:14.0/usb3/3-9/3-9:1.0/0003:349E:0022.0002/report_descriptor
0000000 05 01 09 06 a1 01 05 07 19 e0 29 e7 15 00 25 01
0000020
Failed to get device from syspath /sys/devices/pci0000:00/0000:00:14.0/usb3/3-9/3-9:1.0/0003:349E:0022.0002/report_descriptor: No such device

Steps to reproduce the problem

# lsusb|grep Yubikey
Bus 003 Device 011: ID 1050:0407 Yubico.com Yubikey 4/5 OTP+U2F+CCID

# find /sys/ -name report_descriptor | xargs -n1 /usr/lib/udev/fido_id 2>&1 | grep 1050:0407
Failed to get device from syspath /sys/devices/pci0000:00/0000:00:14.0/usb3/3-2/3-2:1.1/0003:1050:0407.0017/report_descriptor: No such device
Failed to get device from syspath /sys/devices/pci0000:00/0000:00:14.0/usb3/3-2/3-2:1.0/0003:1050:0407.0016/report_descriptor: No such device

Additional program output to the terminal or log subsystem illustrating the issue

# LANG=C strace -f -s1024 -e trace=%file /usr/lib/udev/fido_id /sys/devices/pci0000:00/0000:00:14.0/usb3/3-2/3-2:1.1/0003:1050:0407.0017 
execve("/usr/lib/udev/fido_id", ["/usr/lib/udev/fido_id", "/sys/devices/pci0000:00/0000:00:14.0/usb3/3-2/3-2:1.1/0003:1050:0407.0017"], 0x7ffcfe6bad78 /* 34 vars */) = 0
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib64/systemd/glibc-hwcaps/x86-64-v3/libsystemd-shared-254.1-2.fc39.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib64/systemd/glibc-hwcaps/x86-64-v3/", 0x7ffdf82f9670, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib64/systemd/glibc-hwcaps/x86-64-v2/libsystemd-shared-254.1-2.fc39.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib64/systemd/glibc-hwcaps/x86-64-v2/", 0x7ffdf82f9670, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib64/systemd/libsystemd-shared-254.1-2.fc39.so", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=4078888, ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/usr/lib64/systemd/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=70171, ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/lib64/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=145104, ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/usr/lib64/systemd/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=2811464, ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/lib64/libacl.so.1", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=40824, ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/lib64/libblkid.so.1", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=246216, ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/lib64/libcap.so.2", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=36616, ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/lib64/libcrypt.so.2", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=196952, ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/lib64/libkmod.so.2", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=116000, ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/lib64/liblz4.so.1", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=135128, ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/lib64/libmount.so.1", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=337576, ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/lib64/libcrypto.so.3", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=5169192, ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/lib64/libpam.so.0", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=69776, ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/lib64/libseccomp.so.2", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=127352, ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/lib64/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=180016, ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/lib64/liblzma.so.5", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=211320, ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/lib64/libzstd.so.1", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=770816, ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/lib64/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=938392, ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/lib64/libattr.so.1", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=28248, ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/lib64/libz.so.1", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=107000, ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/lib64/libaudit.so.1", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=139048, ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/lib64/libpcre2-8.so.0", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=632968, ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/lib64/libcap-ng.so.0", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=36040, ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/proc/sys/kernel/cap_last_cap", O_RDONLY) = 3
statfs("/sys/fs/selinux", {f_type=SELINUX_MAGIC, f_bsize=4096, f_blocks=0, f_bfree=0, f_bavail=0, f_files=0, f_ffree=0, f_fsid={val=[0, 0]}, f_namelen=255, f_frsize=4096, f_flags=ST_VALID|ST_NOSUID|ST_NOEXEC|ST_RELATIME}) = 0
statfs("/sys/fs/selinux", {f_type=SELINUX_MAGIC, f_bsize=4096, f_blocks=0, f_bfree=0, f_bavail=0, f_files=0, f_ffree=0, f_fsid={val=[0, 0]}, f_namelen=255, f_frsize=4096, f_flags=ST_VALID|ST_NOSUID|ST_NOEXEC|ST_RELATIME}) = 0
access("/etc/selinux/config", F_OK)     = 0
openat(AT_FDCWD, "/etc/udev/udev.conf", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=305, ...}, AT_EMPTY_PATH) = 0
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=305, ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/", O_RDONLY|O_CLOEXEC|O_PATH|O_DIRECTORY) = 3
statx(3, ".", AT_STATX_SYNC_AS_STAT, STATX_TYPE|STATX_INO|STATX_MNT_ID, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=STATX_ATTR_IMMUTABLE|STATX_ATTR_MOUNT_ROOT, stx_mode=S_IFDIR|0755, stx_size=158, ...}) = 0
statx(3, "..", AT_STATX_SYNC_AS_STAT, STATX_TYPE|STATX_INO|STATX_MNT_ID, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=STATX_ATTR_IMMUTABLE|STATX_ATTR_MOUNT_ROOT, stx_mode=S_IFDIR|0755, stx_size=158, ...}) = 0
openat(3, "/", O_RDONLY|O_CLOEXEC|O_PATH|O_DIRECTORY) = 4
newfstatat(4, "", {st_mode=S_IFDIR|0755, st_size=158, ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/", O_RDONLY|O_CLOEXEC|O_PATH|O_DIRECTORY) = 5
openat(4, "sys", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_PATH) = 6
newfstatat(6, "", {st_mode=S_IFDIR|0555, st_size=0, ...}, AT_EMPTY_PATH) = 0
openat(6, "devices", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_PATH) = 4
newfstatat(4, "", {st_mode=S_IFDIR|0755, st_size=0, ...}, AT_EMPTY_PATH) = 0
openat(4, "pci0000:00", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_PATH) = 6
newfstatat(6, "", {st_mode=S_IFDIR|0755, st_size=0, ...}, AT_EMPTY_PATH) = 0
openat(6, "0000:00:14.0", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_PATH) = 4
newfstatat(4, "", {st_mode=S_IFDIR|0755, st_size=0, ...}, AT_EMPTY_PATH) = 0
openat(4, "usb3", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_PATH) = 6
newfstatat(6, "", {st_mode=S_IFDIR|0755, st_size=0, ...}, AT_EMPTY_PATH) = 0
openat(6, "3-2", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_PATH) = 4
newfstatat(4, "", {st_mode=S_IFDIR|0755, st_size=0, ...}, AT_EMPTY_PATH) = 0
openat(4, "3-2:1.1", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_PATH) = 6
newfstatat(6, "", {st_mode=S_IFDIR|0755, st_size=0, ...}, AT_EMPTY_PATH) = 0
openat(6, "0003:1050:0407.0017", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_PATH) = 4
newfstatat(4, "", {st_mode=S_IFDIR|0755, st_size=0, ...}, AT_EMPTY_PATH) = 0
faccessat2(4, "uevent", F_OK, 0)        = 0
openat(AT_FDCWD, "/proc/self/fd/4", O_RDONLY|O_NOCTTY|O_CLOEXEC|O_PATH) = 3
openat(AT_FDCWD, "/", O_RDONLY|O_CLOEXEC|O_PATH|O_DIRECTORY) = 3
statx(3, ".", AT_STATX_SYNC_AS_STAT, STATX_TYPE|STATX_INO|STATX_MNT_ID, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=STATX_ATTR_IMMUTABLE|STATX_ATTR_MOUNT_ROOT, stx_mode=S_IFDIR|0755, stx_size=158, ...}) = 0
statx(3, "..", AT_STATX_SYNC_AS_STAT, STATX_TYPE|STATX_INO|STATX_MNT_ID, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=STATX_ATTR_IMMUTABLE|STATX_ATTR_MOUNT_ROOT, stx_mode=S_IFDIR|0755, stx_size=158, ...}) = 0
openat(3, "/", O_RDONLY|O_CLOEXEC|O_PATH|O_DIRECTORY) = 4
newfstatat(4, "", {st_mode=S_IFDIR|0755, st_size=158, ...}, AT_EMPTY_PATH) = 0
openat(AT_FDCWD, "/", O_RDONLY|O_CLOEXEC|O_PATH|O_DIRECTORY) = 5
openat(4, "sys", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_PATH) = 6
newfstatat(6, "", {st_mode=S_IFDIR|0555, st_size=0, ...}, AT_EMPTY_PATH) = 0
openat(6, "devices", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_PATH) = 4
newfstatat(4, "", {st_mode=S_IFDIR|0755, st_size=0, ...}, AT_EMPTY_PATH) = 0
openat(4, "pci0000:00", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_PATH) = 6
newfstatat(6, "", {st_mode=S_IFDIR|0755, st_size=0, ...}, AT_EMPTY_PATH) = 0
openat(6, "0000:00:14.0", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_PATH) = 4
newfstatat(4, "", {st_mode=S_IFDIR|0755, st_size=0, ...}, AT_EMPTY_PATH) = 0
openat(4, "usb3", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_PATH) = 6
newfstatat(6, "", {st_mode=S_IFDIR|0755, st_size=0, ...}, AT_EMPTY_PATH) = 0
openat(6, "3-2", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_PATH) = 4
newfstatat(4, "", {st_mode=S_IFDIR|0755, st_size=0, ...}, AT_EMPTY_PATH) = 0
openat(4, "3-2:1.1", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_PATH) = 6
newfstatat(6, "", {st_mode=S_IFDIR|0755, st_size=0, ...}, AT_EMPTY_PATH) = 0
faccessat2(6, "uevent", F_OK, 0)        = 0
openat(AT_FDCWD, "/proc/self/fd/6", O_RDONLY|O_NOCTTY|O_CLOEXEC|O_PATH) = 3
openat(AT_FDCWD, "/sys/devices/pci0000:00/0000:00:14.0/usb3/3-2/3-2:1.1/report_descriptor", O_RDONLY|O_NOCTTY|O_NOFOLLOW|O_CLOEXEC) = -1 ENOENT (No such file or directory)
3-2:1.1: Failed to open report descriptor at '/sys/devices/pci0000:00/0000:00:14.0/usb3/3-2/3-2:1.1/report_descriptor': No such file or directory
@abbra abbra added the bug 🐛 Programming errors, that need preferential fixing label Sep 22, 2023
abbra added a commit to abbra/systemd that referenced this issue Sep 24, 2023
Fixes: systemd#29278

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
abbra added a commit to abbra/systemd that referenced this issue Sep 24, 2023
Fixes: systemd#29278

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
@abbra
Copy link
Author

abbra commented Sep 25, 2023

I tried to reproduce this on a freshly created Fedora 39 beta VM and it now works for me. I am not sure what was it.

For the record, this is how it looks after udev control -R -l debug and copying 60-fido-id.rules to /etc/udev/rules.d just to experiment:

Sep 25 08:32:03 localhost.localdomain (udev-worker)[4313]: hidraw2: Processing device (SEQNUM=3731, ACTION=add)
Sep 25 08:32:03 localhost.localdomain (udev-worker)[4313]: hidraw2: Removing watch handle -1.
Sep 25 08:32:03 localhost.localdomain (udev-worker)[4313]: hidraw2: /etc/udev/rules.d/60-fido-id.rules:6 Importing properties from results of 'fido_id'
Sep 25 08:32:03 localhost.localdomain (udev-worker)[4313]: hidraw2: Starting 'fido_id'
Sep 25 08:32:03 localhost.localdomain (udev-worker)[4313]: Successfully forked off '(spawn)' as PID 4321.
Sep 25 08:32:03 localhost.localdomain (udev-worker)[4313]: hidraw2: 'fido_id'(out) 'ID_FIDO_TOKEN=1'
Sep 25 08:32:03 localhost.localdomain (udev-worker)[4313]: hidraw2: 'fido_id'(out) 'ID_SECURITY_TOKEN=1'
Sep 25 08:32:03 localhost.localdomain (udev-worker)[4313]: hidraw2: Process 'fido_id' succeeded.
Sep 25 08:32:03 localhost.localdomain (udev-worker)[4313]: hidraw2: /usr/lib/udev/rules.d/71-seat.rules:74 Importing properties from results of builtin command 'path_id'
Sep 25 08:32:03 localhost.localdomain (udev-worker)[4313]: hidraw2: /usr/lib/udev/rules.d/73-seat-late.rules:16 RUN 'uaccess'
Sep 25 08:32:03 localhost.localdomain (udev-worker)[4313]: hidraw2: Preserve permissions of /dev/hidraw2, uid=0, gid=0, mode=0600
Sep 25 08:32:03 localhost.localdomain (udev-worker)[4313]: hidraw2: Successfully created symlink '/dev/char/241:2' to '/dev/hidraw2'
Sep 25 08:32:03 localhost.localdomain (udev-worker)[4313]: hidraw2: sd-device: Created db file '/run/udev/data/c241:2' for '/devices/pci0000:00/0000:00:02.1/0000:02:00.0/usb1/1-3/1-3:1.1/0003:349E:0022.001C/hidraw/hidraw2'
Sep 25 08:32:03 localhost.localdomain (udev-worker)[4313]: hidraw2: Running built-in command "uaccess"
Sep 25 08:32:03 localhost.localdomain (udev-worker)[4313]: hidraw2: Device processed (SEQNUM=3731, ACTION=add)
Sep 25 08:32:03 localhost.localdomain (udev-worker)[4313]: hidraw2: sd-device-monitor(worker): Passed 577 byte to netlink monitor.

I tried few more keys and they also worked. So I'm closing this issue.

@abbra abbra closed this as completed Sep 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 Programming errors, that need preferential fixing hwdb udev
Development

Successfully merging a pull request may close this issue.

1 participant