Skip to content

pam: fix deadlock on terminate - #1059

Merged
vaxerski merged 1 commit into
mainfrom
fix-pam-deadlock
Aug 7, 2026
Merged

vaxerski merged 1 commit into
mainfrom
fix-pam-deadlock

Conversation

@vaxerski

@vaxerski vaxerski commented Aug 6, 2026

Copy link
Copy Markdown
Member

ref #1055

needs testing

@MaiteALC

MaiteALC commented Aug 6, 2026

Copy link
Copy Markdown

How I tested

I'm not familiar with the C++ ecosystem and its build system, so I asked Google Gemini for the build commands, and they tell me to run:

  1. cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -S . -B ./build

  2. cmake --build ./build --config Release --target hyprlock -j$(nproc)

Then, I switched my hypridle config file to use the new hyprlock I locally compiled and ran systemctl suspend to reproduce the issue.


Results

It always works, but always lags.

The screen freezes for about 2 or 3 seconds in an intermediate state between the lock screen and the home screen (in its last state before the suspension), and then, I can type my password.

None coredumpctl logs has been produced. I think it means no errors has occurred, hyprlock only lags now.

@MaiteALC

MaiteALC commented Aug 6, 2026

Copy link
Copy Markdown

Tell me if there is something I can do to better test your fix

@g0spel

g0spel commented Aug 7, 2026

Copy link
Copy Markdown

Tested on AMD Barcelo laptop (Omarchy + CachyOS kernel, Hyprland 0.56.1-3.1). Built from 2373350 with cmake -B build -DCMAKE_BUILD_TYPE=Release, put the binary in ~/.local/bin so it shadows the distro hyprlock.
Before this fix, the exact repro was: lid close → resume → enter password → unlock works, but hyprlock stays as a zombie forever. pidof hyprlock still matches, hyprctl locked is false, no lock surface, and every subsequent lock attempt becomes a no-op because my distro's lock script guards with pidof hyprlock. I captured coredumps of two of these zombies: the main thread was stuck in std::thread::join() (futex wait on the PAM thread's TCB), and the PAM thread was sitting in pam_authenticate() → pam_unix → pam_prompt → conv waiting on a condition variable. The log always stopped at "Unlocked, exiting!" — "Reached the end, exiting" never appeared.
With this build, did 4 suspend/resume cycles with unlock after each, plus a manual lock/unlock via my lock key. All of them now log the full clean-exit chain (Unlocked, exiting! → Reached the end, exiting) and no process is left behind afterwards. The deadlock is gone.
One thing worth noting separately: in 2 of the 4 suspend cycles I saw the lock request get finished immediately ("yeeten") right when the lid close coincided with hyprlock starting. Before the fix that scenario was one of my zombie coredumps; now hyprlock logs conversation failed and exits cleanly. The screen still locked and unlocked fine in those rounds (Hyprland still held the session lock), so functionally it worked — the "auth failure" there is just the terminateRequested/isFadingOutOrTerminating check in conv() doing its job on a rejected lock, not a regression from this PR. The yeeten itself looks like a separate race on the Hyprland side (suspend broadcast vs. lock request timing), but I didn't dig further into it.
So: the deadlock fix is solid on my end — no more zombies, no leftover processes, no regressions in normal lock/unlock. Thanks for the quick fix.

@vaxerski
vaxerski merged commit 1f337a4 into main Aug 7, 2026
2 checks passed
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.

Random system suspends, hibernates, and hyprlock freezes/segfaults on unlock (since v0.56)

3 participants