Skip to content

Linux: add a 2 second read timeout for USB HID#360

Open
micolous wants to merge 1 commit into
mozilla:ctap2-2021from
micolous:ctap2/1958831-linux-hid-timeout
Open

Linux: add a 2 second read timeout for USB HID#360
micolous wants to merge 1 commit into
mozilla:ctap2-2021from
micolous:ctap2/1958831-linux-hid-timeout

Conversation

@micolous

@micolous micolous commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Adds a 2 second read() timeout for USB HID on Linux.

Potentially fixes https://bugzilla.mozilla.org/show_bug.cgi?id=1958831

Background

There are a few projects which extend Firefox/authenticator-rs' CTAP2 transport support by using uhid (and similar) to simulate a USB HID authenticator and proxying commands (eg: BTLE, PC/SC, TPM).

Unfortunately, some of these transports are slower and less reliable than USB, and simulated devices may not even send CTAPHID_KEEPALIVE as frequently as suggested by the spec (100 ms). Sometimes they stop responding entirely, rather than reporting an error. A misbehaving device can cause an application using this library to hang, potentially indefinitely.

I've written a tester for Linux which looks like a USB HID authenticator but never responds sends any replies (or always replies with CTAPHID_KEEPALIVE), which causes authenticator_rs and (current) Firefox to hang: https://github.com/micolous/webauthn-toys/tree/main/fido_tarpit

While authenticator-rs has a ~20 second timeout where the device will be "removed", the slow read() won't ever be interrupted, and it won't proceed to send further commands to a working authenticator. In Firefox, the browser just entirely stops responding after a WebAuthn request.

In this PR

This PR applies a 2 second timeout on all USB HID reads on Linux by poll()ing before each read() (ie: 20x recommended time). Authenticators can still respond with CTAPHID_KEEPALIVE before this timeout, and get extra time.

Applications can still pass a keep_alive parameter to impose further deadlines on some requests, and interrupt unreasonably slow authenticators.

I tested this against about a dozen USB HID U2F and FIDO2 authenticators from many vendors, and they all easily meet the timeout.

Not addressed by this PR

An authenticator can still stall indefinitely by sending CTAPHID_KEEPALIVE in response to CTAPHID_INIT (which isn't allowed by the spec) or a CTAPHID_CBOR authenticatorGetInfo request, and trigger lock-ups.

I started investigating solutions in https://github.com/micolous/authenticator-rs/tree/ctap2/1958831-ignore-unexpected-timeouts, but that will require more invasive changes across all platforms (as it would require all requests become cancellable).

Only macOS applies any timeout on read(). Other platforms may wish to consider similar changes, but testing these is hard :)

Potential breakages

This PR will potentially break really slow (physical and virtual) devices. As noted above, these do not meet the CTAP specification's recommendations.

Virtual devices with slow transports should attempt to send and cache an authenticatorGetInfo request on application start-up or user activity (wake/unlock screen), and only present a virtual device when the transport is actually usable. They must also return an error on transport-level errors or timeouts.

authenticator-rs will discover new devices that become present during a registration/authentication ceremony, so a virtual device doesn't have to be present at all times if it is the only FIDO USB HID.

@micolous micolous force-pushed the ctap2/1958831-linux-hid-timeout branch from b2f9993 to 9bc5797 Compare July 3, 2026 01:12
@micolous micolous changed the title WIP: linux: add a 2 second read timeout for USB HID Linux: add a 2 second read timeout for USB HID Jul 3, 2026
@micolous micolous marked this pull request as ready for review July 3, 2026 02:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant