Proof Portal
Omarchy
ProbeLabs65 findings · 95 requirementsA proof layer — requirements, tests and verified fixes — for two of Omarchy's subsystems: the application menu (launcher scripts, QML model, JSONC config, search and selection) and the lock screen (lock scripts, QML, PAM authentication). Scope is deliberately limited to those components of omacom/omarchy; the rest of the distribution is not covered.
Lock screen re-arms fingerprint PAM indefinitely — 6,451 cycles / 6,454 USB resets over 53h
Reported by surfstyk · filed Sep 3, 2026Closed upstream on 2026-10-11 by the bot omarchybot, as a duplicate of #9913 (R-1029). GitHub close reason: duplicate.
At a glance
- 1 · What is claimed?
- Only the report text below — no validator has restated it as checkable claims yet.
- 2 · What does it affect?
- 3 · Is it reproducible?
- No validation has been run yet.
- 4 · What remains unclear?
- Not validated yet: no claims, no reproducer.
- 5 · What happens next?
- Our staff decide whether the report is valid. Where this project allows it, agents decide whether it duplicates another report or a known issue. So far: in the audited area (lock) — decided by agents · verified. The outcome (valid, duplicate, not a bug, …) is not decided yet. See the decision.
Original report
Summary
The Quickshell lock screen re-arms fingerprint PAM unconditionally and without bound for the entire duration of a lock. On a machine that stays locked for a long time, this produces a continuous ~30s authentication cycle that never stops. On my laptop it ran for 53 hours straight — 6,451 PAM cycles and 6,454 USB resets of the fingerprint sensor — and the session ended in a hard kernel freeze whose last log line was one of those USB resets.
The unbounded retry is clearly visible in the source. The freeze is circumstantial and I am not claiming it as proven — but the retry loop itself looks like a bug worth bounding regardless.
Environment
- Omarchy
4.0.2-1 - Hyprland
0.56.2, SDDM, kernel7.1.9-arch1-2 - Dell Inspiron 16 5635, AMD Ryzen 7 7730U w/ Radeon Graphics
- Fingerprint sensor: Goodix
27c6:639c("Goodix MOC Fingerprint Sensor (press)"), one enrolled finger /etc/pam.d/omarchy-lock-fingerprintpresent and correctly wired (auth required pam_fprintd.so) — this is not the Omarchy 3 / hyprlock "PAM not wired up" bug from #5503
Steps to reproduce
- Enroll a fingerprint (Setup > Security > Fingerprint).
- Configure the machine to stay awake while unattended — in my case an always-on host with:
# /etc/systemd/logind.conf.d/30-alwayson.conf
HandleLidSwitch=lock
IdleAction=ignore- Let the screen lock and leave it locked for hours (lid closed is enough).
- Watch the journal.
Observed behaviour
A cycle repeating every ~30.3s, indefinitely:
15:53:23 omarchy-shell[1390293]: quickshell.service.pam.subprocess: Starting pam session for user "..." with config "omarchy-lock-fingerprint"
15:53:23 kernel: usb 3-4: reset full-speed USB device number 3 using xhci_hcd
15:53:23 omarchy-shell[1390293]: Relaying pam message: "Place your right index finger on the fingerprint reader"
15:53:53 omarchy-shell[1390293]: Relaying pam message: "Verification timed out"
15:53:53 omarchy-shell[1390293]: Error while authenticating: "Authentication service cannot retrieve authentication info" (code 9)
15:53:53 omarchy-shell[1390488]: Starting pam session ... (next subprocess, new PID)The 30s is fprintd's own verification timeout; the extra 250ms is fingerprintRetryTimer.
Totals for that single boot (Aug 31 07:34:52 → Sep 2 15:56:58, ~53h):
6451× "Place your right index finger"6454×usb 3-4: reset ... using xhci_hcd
The loop began 15 minutes after the first idle-lock following the 4.0.1 → 4.0.2 upgrade and reboot.
Root cause
shell/plugins/lock/Service.qml re-arms on every non-success result, and again on error:
function handleFingerprintFinished(result) {
fingerprintAuthenticating = false
if (!lockRequested) return
if (result === PamResult.Success) {
finishUnlock()
} else if (fingerprintConfigured) {
fingerprintRetryTimer.restart() // no cap, no backoff
}
}onError: function(error) {
root.fingerprintAuthenticating = false
if (root.lockRequested && root.fingerprintConfigured) fingerprintRetryTimer.restart()
}Timer { id: fingerprintRetryTimer; interval: 250; repeat: false; onTriggered: root.startFingerprint() }The intent is documented at ~line 427 ("The fingerprint PAM stays armed for the whole lock"), so this is by design — but the design has no upper bound, no backoff, and no way to opt out short of deleting /etc/pam.d/omarchy-lock-fingerprint. shell.json exposes only idle.screensaver and idle.lock.
A timeout is treated identically to a genuine failed match. Nothing distinguishes "nobody is at the machine" from "someone is trying to unlock".
Why it matters
Each cycle spawns a PAM subprocess and triggers a USB device reset. Over two days that is ~6.5k of each. Beyond the wear on the sensor and the journal noise, an unattended locked machine is exactly the state where nobody is watching for trouble.
On the freeze, stated carefully: the journal ends abruptly at 15:57:28 mid-boot with no shutdown, no panic, no OOM, no thermal or DRM errors, and the final line is the 6,454th usb 3-4: reset ... xhci_hcd. That is suggestive, not conclusive — nothing was written to disk. I mention it only as motivation for bounding the loop, not as a diagnosis.
Suggested fix
Any of:
- Cap consecutive retries, and stop re-arming after N failures until user input (a keypress or pointer motion) is seen.
- Back off exponentially instead of a fixed 250ms.
- Distinguish
PamResulttimeout from a real match failure, and don't re-arm on timeout when the session has been idle. - Expose a bound in
shell.json(e.g.lock.fingerprintRetries).
The first seems closest to intent: a person actually standing at the machine generates input events, so gating re-arm on recent input would keep fingerprint unlock instant for real use while letting an untouched machine go quiet.
Workaround
sudo mv /etc/pam.d/omarchy-lock-fingerprint{,.disabled} — the fingerprintCheckProc in Service.qml tests for that file, so this cleanly sets fingerprintConfigured = false and stops the loop. Password unlock is unaffected, and fingerprint for sudo / polkit-1 keeps working since those PAM stacks reference pam_fprintd.so independently.
View raw text
## Summary
The Quickshell lock screen re-arms fingerprint PAM unconditionally and without bound for the entire duration of a lock. On a machine that stays locked for a long time, this produces a continuous ~30s authentication cycle that never stops. On my laptop it ran for **53 hours straight — 6,451 PAM cycles and 6,454 USB resets of the fingerprint sensor** — and the session ended in a hard kernel freeze whose last log line was one of those USB resets.
The unbounded retry is clearly visible in the source. The freeze is circumstantial and I am **not** claiming it as proven — but the retry loop itself looks like a bug worth bounding regardless.
## Environment
- Omarchy `4.0.2-1`
- Hyprland `0.56.2`, SDDM, kernel `7.1.9-arch1-2`
- Dell Inspiron 16 5635, AMD Ryzen 7 7730U w/ Radeon Graphics
- Fingerprint sensor: Goodix `27c6:639c` ("Goodix MOC Fingerprint Sensor (press)"), one enrolled finger
- `/etc/pam.d/omarchy-lock-fingerprint` present and correctly wired (`auth required pam_fprintd.so`) — this is **not** the Omarchy 3 / hyprlock "PAM not wired up" bug from #5503
## Steps to reproduce
1. Enroll a fingerprint (*Setup > Security > Fingerprint*).
2. Configure the machine to stay awake while unattended — in my case an always-on host with:
```
# /etc/systemd/logind.conf.d/30-alwayson.conf
HandleLidSwitch=lock
IdleAction=ignore
```
3. Let the screen lock and leave it locked for hours (lid closed is enough).
4. Watch the journal.
## Observed behaviour
A cycle repeating every ~30.3s, indefinitely:
```
15:53:23 omarchy-shell[1390293]: quickshell.service.pam.subprocess: Starting pam session for user "..." with config "omarchy-lock-fingerprint"
15:53:23 kernel: usb 3-4: reset full-speed USB device number 3 using xhci_hcd
15:53:23 omarchy-shell[1390293]: Relaying pam message: "Place your right index finger on the fingerprint reader"
15:53:53 omarchy-shell[1390293]: Relaying pam message: "Verification timed out"
15:53:53 omarchy-shell[1390293]: Error while authenticating: "Authentication service cannot retrieve authentication info" (code 9)
15:53:53 omarchy-shell[1390488]: Starting pam session ... (next subprocess, new PID)
```
The 30s is fprintd's own verification timeout; the extra 250ms is `fingerprintRetryTimer`.
Totals for that single boot (Aug 31 07:34:52 → Sep 2 15:56:58, ~53h):
- `6451` × "Place your right index finger"
- `6454` × `usb 3-4: reset ... using xhci_hcd`
The loop began 15 minutes after the first idle-lock following the `4.0.1 → 4.0.2` upgrade and reboot.
## Root cause
`shell/plugins/lock/Service.qml` re-arms on **every** non-success result, and again on error:
```qml
function handleFingerprintFinished(result) {
fingerprintAuthenticating = false
if (!lockRequested) return
if (result === PamResult.Success) {
finishUnlock()
} else if (fingerprintConfigured) {
fingerprintRetryTimer.restart() // no cap, no backoff
}
}
```
```qml
onError: function(error) {
root.fingerprintAuthenticating = false
if (root.lockRequested && root.fingerprintConfigured) fingerprintRetryTimer.restart()
}
```
```qml
Timer { id: fingerprintRetryTimer; interval: 250; repeat: false; onTriggered: root.startFingerprint() }
```
The intent is documented at ~line 427 (*"The fingerprint PAM stays armed for the whole lock"*), so this is by design — but the design has no upper bound, no backoff, and no way to opt out short of deleting `/etc/pam.d/omarchy-lock-fingerprint`. `shell.json` exposes only `idle.screensaver` and `idle.lock`.
A timeout is treated identically to a genuine failed match. Nothing distinguishes "nobody is at the machine" from "someone is trying to unlock".
## Why it matters
Each cycle spawns a PAM subprocess and triggers a USB device reset. Over two days that is ~6.5k of each. Beyond the wear on the sensor and the journal noise, an unattended locked machine is exactly the state where nobody is watching for trouble.
**On the freeze**, stated carefully: the journal ends abruptly at `15:57:28` mid-boot with no shutdown, no panic, no OOM, no thermal or DRM errors, and the final line is the 6,454th `usb 3-4: reset ... xhci_hcd`. That is suggestive, not conclusive — nothing was written to disk. I mention it only as motivation for bounding the loop, not as a diagnosis.
## Suggested fix
Any of:
- Cap consecutive retries, and stop re-arming after N failures until user input (a keypress or pointer motion) is seen.
- Back off exponentially instead of a fixed 250ms.
- Distinguish `PamResult` timeout from a real match failure, and don't re-arm on timeout when the session has been idle.
- Expose a bound in `shell.json` (e.g. `lock.fingerprintRetries`).
The first seems closest to intent: a person actually standing at the machine generates input events, so gating re-arm on recent input would keep fingerprint unlock instant for real use while letting an untouched machine go quiet.
## Workaround
`sudo mv /etc/pam.d/omarchy-lock-fingerprint{,.disabled}` — the `fingerprintCheckProc` in `Service.qml` tests for that file, so this cleanly sets `fingerprintConfigured = false` and stops the loop. Password unlock is unaffected, and fingerprint for `sudo` / `polkit-1` keeps working since those PAM stacks reference `pam_fprintd.so` independently.
Validation
Not checked yet. A validator will restate this report as checkable claims, map it to the project's requirements and write a reproducer that the proof engine runs.
Linked
- Fixed bypr/7179· confirmed
- Related PRpr/10653· confirmed
- Fixed bypr/12461· confirmed
- Fixed bypr/12420· confirmed
- Related PRpr/10393· confirmed
- Fixed bypr/11273· confirmed
- Fixed bypr/12690· confirmed
Decision
Decisions are recorded by our staff — or, where this project allows it, by agents: checked by a second, independent agent, or by a single agent where the project's policy says so. Any decision reached so far is shown below.
- Decided by agents · verified: in the audited area (lock)
The outcome (valid, duplicate, not a bug, …) is not decided yet.