Skip to content

Clear lockRequested latch on lock() so later lock() actually locks - #8

Open
kvnloo wants to merge 1 commit into
quattrofrom
cursor/clear-lock-requested-latch-006f
Open

Clear lockRequested latch on lock() so later lock() actually locks#8
kvnloo wants to merge 1 commit into
quattrofrom
cursor/clear-lock-requested-latch-006f

Conversation

@kvnloo

@kvnloo kvnloo commented Sep 10, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes a security issue where a stalled lock request prevents all subsequent lock attempts, allowing the machine to suspend unlocked.

Problem

When lock() is called and lockRequested is set to true but the session never reaches sessionLock.locked or sessionLock.secure (the lock stalls), lockRequested stays latched true forever. Because root.locked derives from lockRequested || sessionLock.locked || sessionLock.secure, the IPC lock() method's guard if (!root.locked && !root.beginLock()) short-circuits on !root.locked being false, so beginLock() is never called again. The method returns "ok" without actually locking.

This makes every subsequent lock attempt a silent no-op. The lid-close lock handler receives "ok" and proceeds as if the session is locked, allowing the machine to suspend with the session fully exposed. On resume, Hyprland shows its crashed-lockscreen failsafe.

Solution

Before checking root.locked, detect a stalled lock state: when lockRequested is true but the session is neither locked nor secure, clear the latch and stop the associated timers. This ensures beginLock() gets called for a fresh lock attempt.

The fix is minimal and surgical: it only resets state when a lock is demonstrably stalled (requested but not materialized), and does so immediately before the retry.

Changes

  • shell/plugins/lock/Service.qml: Add stall detection in the IPC lock() handler to clear lockRequested, pendingSessionLock, and stop both timers when the lock is stuck
  • test/shell.d/lock-requested-latch-test.sh: New test verifying the latch-clearing behavior

Testing

  • New test lock-requested-latch-test.sh passes, verifying all latch-reset conditions
  • Existing lock tests pass: lock-stranded-recovery-test.sh, system-lock-test.sh, sleep-lock-test.sh

Related

Fixes omacom#10299

Adjacent PRs omacom#7169, omacom#8930, omacom#9429 address other lock lifecycle issues but do not fix this latch behavior.

Open in Web Open in Cursor 

When a lock request stalls after setting lockRequested=true but never
reaches sessionLock.locked or sessionLock.secure, the latch stays true
forever. Because root.locked derives from lockRequested, the IPC lock()
method then short-circuits and returns 'ok' without ever calling
beginLock(), making every subsequent lock attempt a silent no-op.

This is a security issue: the machine can suspend unlocked because the
lid-close lock handler receives 'ok' from a latched-stuck request that
never actually locks.

The fix detects a stalled lock state in the IPC lock() handler: when
lockRequested is true but the session is neither locked nor secure,
clear the latch and associated timers before checking root.locked.
This ensures beginLock() gets called for a fresh lock attempt.

Adds test/shell.d/lock-requested-latch-test.sh to verify the latch is
cleared and timers are stopped before retrying the lock.

Fixes omacom#10299

Co-authored-by: Kevin Rajan <kvnloo@users.noreply.github.com>
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.

Stalled lock latches lockRequested, so every later lock() returns "ok" without locking — machine suspends unlocked

2 participants