Don't let a usbfs claim count as a kernel driver (#6744)

The vendor-ID guess rejects any device with a driver bound, on the
reasoning that libfprint drives readers from userspace so a real one sits
there unbound. But libusb claims interfaces through a synthetic usbfs
driver, so the reader binds one for as long as fprintd holds the claim —
which is exactly while it is being enrolled or verified against.

Readers that name themselves take the product-string branch and never
reach this, so the exposure is the ones that don't: Goodix 27c6:6594
reports "Goodix USB2.0 MISC", matches on vendor ID alone, and drops out
of detection mid-authentication. The menu entry disappears and the
first-run invitation stops firing while the reader is in use.

Ignore a driver link that resolves to usbfs, and keep rejecting the real
ones — usbio-bridge, usbhid, uvcvideo — including on a device that has
both.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
David Heinemeier Hansson
2026-08-12 14:01:58 +02:00
committed by GitHub
co-authored by Claude Opus 5
parent a9c159a1f4
commit 970ec26bb0
2 changed files with 22 additions and 2 deletions
+8 -2
View File
@@ -18,9 +18,15 @@ usb_devices_path="${OMARCHY_USB_DEVICES_PATH:-/sys/bus/usb/devices}"
# — all bind one. Only the vendor-ID guess needs this; a device that names
# itself a fingerprint reader is trusted outright.
has_kernel_driver() {
local intf
local intf driver
for intf in "$1"/*:*; do
[[ -e $intf/driver ]] && return 0
[[ -e $intf/driver ]] || continue
# usbfs is the exception: libusb claims an interface through it, so a reader
# fprintd is enrolling or verifying against binds a driver for as long as it
# holds the claim. That is userspace driving the device — what a reader is
# supposed to look like — so it must not read as a kernel driver here.
driver=$(readlink -f "$intf/driver")
[[ ${driver##*/} == "usbfs" ]] || return 0
done
return 1
}