Proof Portal

Project overview

Omarchy

ProbeLabsviewing a historical run

A 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.

Viewing historical run 5e89718Oct 2, 2026, 03:13 AMpr/13968Back to current
Back to findings
Known issueKI-APPLY-LOCK-PAM-NONATOMIC-WRITE

omarchy-apply-lock rewrites the lock PAM stacks in place; an interrupted run leaves a torn stack on the live path

OpenReviewedMedium

Medium-severity issue, currently open.

Description

The issue as recorded.

bin/omarchy-apply-lock writes the password PAM stack with as_root tee /etc/pam.d/omarchy-lock-password. With an enrolled finger, it also writes /etc/pam.d/omarchy-lock-fingerprint the same way. A heredoc feeds each write. tee opens the live file with O_TRUNC and rewrites it in place. The helper writes no temp file and does no rename. While tee writes, the live path holds only a prefix of the new stack, and the previous stack is already gone. An interrupted run can stop in that window: a killed installer or update, a lost session, or a power cut. The lock screen then authenticates against a torn stack. A torn password stack can lack the pam_unix line, so password unlock fails until the helper runs again. A torn fingerprint stack can cut the pam_fprintd line short. The window is short, because one process writes a few hundred bytes. The likelihood is low, but the impact on a lock screen is high. pocs/apply-lock-pam-torn-write.sh reproduces the defect on the real helper. It pauses each write after 60 bytes and kills the run. The live file then holds the torn 60-byte prefix of 549 and 122 bytes. The seeded previous stack is gone, and the inode does not change. The control arm shows that an uninterrupted run writes both stacks byte-identical to the heredocs.

Affected requirements

The requirement(s) this issue violates — click through to the spec.

Severity, explained

Why this is rated the way it is — and the scoring signals behind the rating (each ⓘ explains the term).

MediumRated severity — the impact if this issue is exploited or hit.
why this rating
Reproducer-confirmed
risk area
Availability
Security classification
Not a security surface
CVE surface
None

Where it is

The code the issue lives in — peek the affected function inline to see it in context.

  • bin/omarchy-apply-lock (writes /etc/pam.d/omarchy-lock-password and omarchy-lock-fingerprint)

How it's proven

The reproducer — an actual test that drives the real code and shows the issue happening. Run it yourself, or peek the test and the source it covers.

Known issue reproducedprofileknown_issue_reproducer
Reproducer test
Run it yourself
./pocs/apply-lock-pam-torn-write.sh
Covers (2)
Last run Oct 1, 2026, 11:46 PM

Reproduction steps

Technical steps for your engineers to confirm the issue by hand.

./pocs/apply-lock-pam-torn-write.sh

What protects you, and the fix

What limits your exposure today, and the planned remediation.

What protects you now

The helper runs only at install, at upgrade or at an explicit reconfigure. Each write is a few hundred bytes, so the window is short. A new run of bin/omarchy-apply-lock rewrites both stacks completely. If the lock screen rejects a correct password after an interrupted install or update, switch to a TTY, log in, and run the helper again.

The fix

Write each stack to a sibling temp file in /etc/pam.d. Then rename the temp file over the live path. The rename stays on one filesystem, so it is atomic. For example, `as_root tee /etc/pam.d/omarchy-lock-password.tmp` followed by `as_root mv -f /etc/pam.d/omarchy-lock-password.tmp /etc/pam.d/omarchy-lock-password`. Do the same for omarchy-lock-fingerprint, and optionally fsync before the rename. Then remove the atomic_write deferrals on SYS-REQ-260912-JW2J and SW-REQ-260912-Y0WT and add witnesses. Close criterion: pocs/apply-lock-pam-torn-write.sh flips red, because the interrupted write leaves the previous complete stack on the live path.

Blast radius

If you touch this issue, what else may need re-checking — the requirements it affects and the code and tests that hang off them. Historical view: authored trace links only — automatically derived links aren't reconstructible for past runs.

Tracing blast radius…

Touch this finding and you re-check 4 requirements · 1 code files · 1 tests.

Code files (1)
  • omarchy-apply-lock
Tests (1)
  • apply-lock-test.sh

Per-requirement evidence

For each requirement this finding touches: the implementing code, verifying tests, and proof obligations that discharge it.

Implementing code (1)
  • bin/omarchy-apply-lock
Tests & evidence (1)
  • test/shell.d/apply-lock-test.sh
Proof obligations (1)
atomic_write

Filesystem writes that produce externally-visible state shall use the write-temp-rename pattern (or an equivalent atomic primitive); partial writes shall not be observable.

  • ✗nominal (required)
Implementing code (1)
  • bin/omarchy-apply-lock
Tests & evidence (1)
  • test/shell.d/apply-lock-test.sh
Proof obligations (1)
atomic_write

Filesystem writes that produce externally-visible state shall use the write-temp-rename pattern (or an equivalent atomic primitive); partial writes shall not be observable.

  • ✗nominal (required)

Evidence trail

The raw evidence manifests behind this finding — superseded by the resolved reproducer above, kept here for traceability.

  • proof/evidence/ki-apply-lock-pam-nonatomic-write.yaml

Change history

Every recorded revision of this finding's source file — when it was added, edited, or re-classified, with the diff for each change.

Discussions

Discuss this with the proof team. Nothing changes in your audit automatically — you open a request and a staff member records any outcome inside the thread.

Sign in to discuss this with the proof team.Sign in