Closed Bug 2046936 Opened 5 months ago Closed

Closing about:webauthn does not cancel its listen() session, wedging a BgIOThreadPool thread and hanging shutdown at XPCOMShutdownThreads

Categories

(Core :: DOM: Web Authentication, defect)

defect

Tracking

()

RESOLVED FIXED
153 Branch
Tracking Status
firefox153 --- fixed

People

(Reporter: florian, Assigned: florian)

References

(Blocks 2 open bugs)

Details

Attachments

(1 external file)

We frequently see this shutdown-hang crash in CI (Linux and macOS):

Hit MOZ_CRASH(Shutdown hanging at step XPCOMShutdownThreads. Something is blocking the main-thread.) at nsTerminator.cpp
PROCESS-CRASH | ... | Shutdown hanging at step XPCOMShutdownThreads. [@ mozilla::(anonymous namespace)::RunWatchdog]

Root cause: about:webauthn calls nsIWebAuthnService::Listen() on load to start an interactive management session. WebAuthnService::Listen() (and RunCommand()) route unconditionally to the authrs service, whose listen() dispatches a status-receiver task to the global background I/O thread pool (NS_DispatchBackgroundTask with may_block), where it blocks on a channel recv() for the lifetime of the session.

When the page closes, its beforeunload handler calls AboutWebauthnService.cancel(0) to tear the session down. But WebAuthnService::Cancel() only forwards to a backend when there is a matching mActiveTransaction, which is created only for modal register/sign operations, never for Listen(). So cancel(0) returns without ever calling AuthrsService()->Cancel(). The authrs StateMachine keeps the device monitor (and the StatusUpdate sender) alive, so the BgIOThreadPool recv() never returns.

At shutdown, BackgroundEventTarget::Shutdown() calls mIOPool->Shutdown() (ShutdownWithTimeout(-1), an infinite timeout), so the main thread waits forever for the wedged pool thread at XPCOMShutdownThreads, and the terminator watchdog crashes the process. This is platform-independent (the WebAuthnService::Listen/Cancel routing is shared C++), matching the Linux and macOS reports.

Profile (parent main thread spinning in nsThreadPool::ShutdownWithTimeout BgIOThreadPool; BgIOThreadPool #2 stuck in authrs_bridge ... interactive_status_callback -> recv): https://share.firefox.dev/4xoScvE

Steps to reproduce locally:

./mach test --headless browser/components/contextualidentity/test/browser/browser_aboutURLs.js

(the test loads every about: page, including about:webauthn). The hang is intermittent in CI; it may be easier to reproduce with the profiler-by-default test changes from bug 2032957 applied.

Fix: have WebAuthnService::Cancel() also forward to AuthrsService()->Cancel(aTransactionId) so a listen() session is torn down (authrs cancel is a no-op when nothing matches). With that, the test drops from a ~93s hang->crash to a ~15s pass.

about:webauthn starts an interactive management session with
nsIWebAuthnService::Listen(), which WebAuthnService routes unconditionally to
the authrs service; authrs dispatches a status receiver that blocks on a
channel recv() on the background I/O thread pool for the lifetime of the
session. WebAuthnService::Cancel() only forwarded to a backend when there was
a matching mActiveTransaction, which is created for modal register/sign
operations but never for Listen(). So the page's beforeunload cancel(0) never
reached authrs, the status receiver kept running and wedged a BgIOThreadPool
thread, and the infinite-timeout background pool shutdown then hung the main
thread at XPCOMShutdownThreads until the terminator watchdog crashed.

Forward Cancel() to the authrs service for transactions not tracked as an
mActiveTransaction, so an interactive session is torn down; authrs's cancel is
a no-op when nothing matches.

See Also: → 2046944
Pushed by fqueze@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/3ad55f6f29c3 https://hg.mozilla.org/integration/autoland/rev/0da4bc42cdc6 Cancel about:webauthn's interactive session on the authrs service so closing the page tears down its listener, r=jschanck.
Pushed by agoloman@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/2a1cf47db2d0 https://hg.mozilla.org/mozilla-central/rev/1598748f7994 Cancel about:webauthn's interactive session on the authrs service so closing the page tears down its listener, r=jschanck.
Status: ASSIGNED → RESOLVED
Closed: 5 months ago
Resolution: --- → FIXED
Target Milestone: --- → 153 Branch
QA Whiteboard: [qa-triage-done-c154/b153]
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: