Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App freezes after entering master password - ssh-agent deadlock #11128

Closed
mo-krauti opened this issue Aug 2, 2024 · 11 comments · Fixed by #11290
Closed

App freezes after entering master password - ssh-agent deadlock #11128

mo-krauti opened this issue Aug 2, 2024 · 11 comments · Fixed by #11290

Comments

@mo-krauti
Copy link

Overview

After entering the master password, the application freezes. Then I need to kill it and after restarting everything works fine.

Steps to Reproduce

  1. Start keepassxc
  2. Enter correct master pw (wrong pws will not freeze the app)
  3. App freezes
  4. Kill app using SIGKILL signal
  5. Restart keepassxc
  6. enter correct master pw
  7. everything works as expected

Expected Behavior

Keepassxc should not freeze.

Actual Behavior

See above

Context

When starting keepassxc using the terminal, I do not see any error messages showing up. This always only happens one time after the computer starts up. I also tried launching keepassxc, killing it without entering anything before, but then it will freeze the next time, so I always have to enter my master pw twice right now. At first I thought this might be related to #9181, but the operating is different, the freeze does not happen after hibernating and downgrading to 2.7.7 did not help.

KeePassXC - Version 2.7.9
Revision: 8f6dd13

Qt 5.15.14
Debugging mode is disabled.

Operating system: Fedora Linux 40 (Sway)
CPU architecture: x86_64
Kernel: linux 6.9.10-200.fc40.x86_64

Enabled extensions:

  • Auto-Type
  • Browser Integration
  • Passkeys
  • SSH Agent
  • KeeShare
  • YubiKey
  • Secret Service Integration

Cryptographic libraries:

  • Botan 2.19.5

Operating System: Linux
Desktop Env: Sway
Windowing System: Wayland

@mo-krauti mo-krauti added the bug label Aug 2, 2024
@droidmonkey
Copy link
Member

There is no obvious reason for this to happen only after startup launch. I am at a loss here, same with the other thread you linked.

@mo-krauti
Copy link
Author

Now it is very weird, because since a few days ago, it no longer happens every time, but the version is still exactly the same.

@droidmonkey
Copy link
Member

droidmonkey commented Aug 16, 2024

Do you only have 1 cpu core?

@lorenzholzbauer
Copy link

I use Fedora 40 as well and I also get the freeze only on first start. NixOS and other distros work fine. This may be a Fedora problem. I have a hexa-core AMD CPU, so that shouldn't be a problem. It also doesn't log anything useful, it just freezes.

@vogr
Copy link

vogr commented Sep 19, 2024

Hi, I was starting to write down a bug report but it looks like I'm having this issue! I tracked it down to ssh-agent socket activation. Here is my full bug report.

Overview

I recently set up SSH integration in KeepassXC, and since then, after powering on my computer I always need to unlock my keepassxc database twice:

  • The first time, the UI hangs when I press enter to unlock the database, until my OS (Fedora) prompts me with "Keepassxc is not responding", at which point I force quit it.
  • The second time, I can properly unlock and access my database.

Steps to Reproduce

2. Enable SSH agent integration in KeepassXC, and set SSH_AUTH_SOCK to /run/user/1000/ssh-agent.socket

  1. Add an SSH key entry to KeepassXC, enable the option "Add key to agent when the database is unlocked"
  2. Enable the systemd service for OpenSSH's ssh-agent:
    $ systemctl --user enable ssh-agent
    
  3. Reboot
  4. Attempt to unlock the database

Expected Behavior

  • The database is unlocked and the SSH keys are added to the agent

Actual Behavior

  • KeepassXC hangs until the OS prompts the user to kill it.

Context

Crash when ssh-agent is waiting for activation

The first time an attempt is made to unlock the database, ssh-agent is not running yet: systemd has prepared a socket but the agent will only start when this socket starts being used:

$ systemctl status --user ssh-agent      
○ ssh-agent.service - OpenSSH key agent
     Loaded: loaded (/usr/lib/systemd/user/ssh-agent.service; indirect; preset: disabled)
    Drop-In: /usr/lib/systemd/user/service.d
             └─10-timeout-abort.conf
     Active: inactive (dead) since Thu 2024-09-19 13:57:54 CEST; 39s ago
   Duration: 7.024s
TriggeredBy: ● ssh-agent.socket
       Docs: man:ssh-agent(1)
             man:ssh-add(1)
             man:ssh(1)
$ systemctl status --user ssh-agent.socket
● ssh-agent.socket - OpenSSH key agent
     Loaded: loaded (/usr/lib/systemd/user/ssh-agent.socket; enabled; preset: disabled)
     Active: active (listening) since Thu 2024-09-19 13:58:31 CEST; 1min 1s ago
   Triggers: ● ssh-agent.service
       Docs: man:ssh-agent(1)
             man:ssh-add(1)
             man:ssh(1)
     Listen: /run/user/1000/ssh-agent.socket (Stream)
     CGroup: /user.slice/user-1000.slice/[email protected]/app.slice/ssh-agent.socket

When trying to unlock the database in this situation, the UI hangs.

No hang once the agent is running

After the first crash, the agent is running:

● ssh-agent.socket - OpenSSH key agent
     Loaded: loaded (/usr/lib/systemd/user/ssh-agent.socket; enabled; preset: disabled)
     Active: active (running) since Thu 2024-09-19 13:58:31 CEST; 3min 45s ago
   Triggers: ● ssh-agent.service
       Docs: man:ssh-agent(1)
             man:ssh-add(1)
             man:ssh(1)
     Listen: /run/user/1000/ssh-agent.socket (Stream)
     CGroup: /user.slice/user-1000.slice/[email protected]/app.slice/ssh-agent.socket

● ssh-agent.service - OpenSSH key agent
     Loaded: loaded (/usr/lib/systemd/user/ssh-agent.service; indirect; preset: disabled)
    Drop-In: /usr/lib/systemd/user/service.d
             └─10-timeout-abort.conf
     Active: active (running) since Thu 2024-09-19 14:02:10 CEST; 6s ago
TriggeredBy: ● ssh-agent.socket
       Docs: man:ssh-agent(1)
             man:ssh-add(1)
             man:ssh(1)
    Process: 8285 ExecStartPre=/usr/bin/rm -f $SSH_AUTH_SOCK (code=exited, status=0/SUCCESS)
   Main PID: 8286 (ssh-agent)
      Tasks: 1 (limit: 19014)
     Memory: 856.0K (peak: 1.1M)
        CPU: 17ms
     CGroup: /user.slice/user-1000.slice/[email protected]/app.slice/ssh-agent.service
             └─8286 /usr/bin/ssh-agent -D -a /run/user/1000/ssh-agent.socket

... and now we can unlock database.

If I manually start the agent (systemctl start --user ssh-agent.service), I can also avoid the first hang and directly unlock the database!

Backtrace

KeepassXC hangs waiting for a reply from the agent:

#0  0x00007ffff5d1cdb0 in __GI_ppoll (fds=fds@entry=0x7fffffffb278, nfds=nfds@entry=1, timeout=<optimized out>, 
    timeout@entry=0x0, sigmask=sigmask@entry=0x0) at ../sysdeps/unix/sysv/linux/ppoll.c:42
#1  0x00007ffff65079ad in ppoll
    (__fds=<optimized out>, __nfds=<optimized out>, __timeout=<optimized out>, __ss=<optimized out>)
    at kernel/qcore_unix.cpp:129
#2  qt_ppoll (fds=0x7fffffffb278, nfds=1, timeout_ts=0x0) at kernel/qcore_unix.cpp:132
#3  qt_ppoll (fds=0x7fffffffb278, nfds=1, timeout_ts=0x0) at kernel/qcore_unix.cpp:129
#4  qt_safe_poll (fds=fds@entry=0x7fffffffb278, nfds=nfds@entry=1, timeout_ts=<optimized out>)
    at kernel/qcore_unix.cpp:155
#5  0x00007ffff7e82930 in qt_poll_msecs (nfds=1, fds=0x7fffffffb278, timeout=<optimized out>)
    at ../../include/QtCore/5.15.14/QtCore/private/../../../../../src/corelib/kernel/qcore_unix_p.h:381
#6  QNativeSocketEnginePrivate::nativeSelect
    (this=this@entry=0x55555637f180, timeout=<optimized out>, checkRead=checkRead@entry=true, checkWrite=checkWrite@entry=false, selectForRead=0x7fffffffb376, selectForWrite=0x7fffffffb377) at socket/qnativesocketengine_unix.cpp:1436
#7  0x00007ffff7e80383 in QNativeSocketEngine::waitForReadOrWrite
    (this=0x5555575701d0, readyToRead=<optimized out>, readyToWrite=<optimized out>, checkRead=true, checkWrite=false, msecs=<optimized out>, timedOut=0x0) at socket/qnativesocketengine.cpp:1120
#8  0x00007ffff7e6e011 in QAbstractSocket::waitForReadyRead (this=0x5555562d07b0, msecs=-1)
    at socket/qabstractsocket.cpp:2293
#9  0x0000555555849c8f in BinaryStream::read
    (this=this@entry=0x7fffffffb4a0, ptr=ptr@entry=0x7fffffffb424 "\377\177", size=size@entry=4)
    at /usr/src/debug/keepassxc-2.7.9-1.fc40.x86_64/src/sshagent/BinaryStream.cpp:64
#10 0x0000555555849dc2 in BinaryStream::read (this=0x7fffffffb4a0, i=@0x7fffffffb424: 32767)
    at /usr/src/debug/keepassxc-2.7.9-1.fc40.x86_64/src/sshagent/BinaryStream.cpp:90
#11 BinaryStream::readString (this=0x7fffffffb4a0, ba=...)
    at /usr/src/debug/keepassxc-2.7.9-1.fc40.x86_64/src/sshagent/BinaryStream.cpp:117
#12 0x000055555587ae1c in SSHAgent::sendMessageOpenSSH(QByteArray const&, QByteArray&) [clone .constprop.0]
    (this=this@entry=0x555555b59140 <(anonymous namespace)::Q_QGS_s_sshAgent::innerFunction()::holder>, in=..., out=...) at /usr/src/debug/keepassxc-2.7.9-1.fc40.x86_64/src/sshagent/SSHAgent.cpp:189
#13 0x0000555555852a3c in SSHAgent::sendMessage
    (this=0x555555b59140 <(anonymous namespace)::Q_QGS_s_sshAgent::innerFunction()::holder>, in=..., out=...)
    at /usr/src/debug/keepassxc-2.7.9-1.fc40.x86_64/src/sshagent/SSHAgent.cpp:171
#14 SSHAgent::addIdentity
    (this=this@entry=0x555555b59140 <(anonymous namespace)::Q_QGS_s_sshAgent::innerFunction()::holder>, key=..., settings=..., databaseUuid=...) at /usr/src/debug/keepassxc-2.7.9-1.fc40.x86_64/src/sshagent/SSHAgent.cpp:309
#15 0x0000555555856a72 in SSHAgent::databaseUnlocked
    (this=0x555555b59140 <(anonymous namespace)::Q_QGS_s_sshAgent::innerFunction()::holder>, db=...)
    at /usr/src/debug/keepassxc-2.7.9-1.fc40.x86_64/src/sshagent/SSHAgent.cpp:540
#16 0x00005555557245f1 in DatabaseWidget::loadDatabase (this=0x555556382320, accepted=<optimized out>)
    at /usr/src/debug/keepassxc-2.7.9-1.fc40.x86_64/src/gui/DatabaseWidget.cpp:1204
...

When looking at the code in sendMessageOpenSSH, it looks no timeout is set when calling stream.readString(out), resulting in the hang. The weird thing is that socket.waitForConnected(500) apparently returns with no error, but then the agent never replies to the message.

Versions and OS

KeePassXC - Version 2.7.9
Revision: 8f6dd13

Qt 5.15.14
Debugging mode is disabled.

Operating system: Fedora Linux 40 (Workstation Edition)
CPU architecture: x86_64
Kernel: linux 6.10.9-200.fc40.x86_64

Enabled extensions:

  • Auto-Type
  • Browser Integration
  • Passkeys
  • SSH Agent
  • KeeShare
  • YubiKey
  • Secret Service Integration

Cryptographic libraries:

  • Botan 2.19.5

Operating System: Linux
Desktop Env: Gnome
Windowing System: Wayland

@droidmonkey
Copy link
Member

Looks like we never set a proper timeout using this function:

void BinaryStream::setTimeout(int timeout)

As evidenced by the -1 in the function call here:

#8  0x00007ffff7e6e011 in QAbstractSocket::waitForReadyRead (this=0x5555562d07b0, msecs=-1)
    at socket/qabstractsocket.cpp:2293
#9  0x0000555555849c8f in BinaryStream::read
    (this=this@entry=0x7fffffffb4a0, ptr=ptr@entry=0x7fffffffb424 "\377\177", size=size@entry=4)
    at /usr/src/debug/keepassxc-2.7.9-1.fc40.x86_64/src/sshagent/BinaryStream.cpp:64

@vogr
Copy link

vogr commented Sep 20, 2024

Good catch!

I found two relevant threads regarding the underlying issue with ssh-agent:

Until (if ever) this PR is merged, ssh-agent is actually ... not compatible with socket activation, so I think I'll try to change the service files on my system to disable that.

@lorenzholzbauer
Copy link

[Unit]
Description=SSH key agent

[Service]
Type=simple
Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket
# DISPLAY required for ssh-askpass to work
Environment=DISPLAY=:0
ExecStart=/usr/bin/ssh-agent -D -a $SSH_AUTH_SOCK

[Install]
WantedBy=default.target

This custom systemd service appears to work for me. It stopped freezing and connecting over ssh works fine.

@droidmonkey
Copy link
Member

Can anyone here test this PR against the previously broken ssh-agent behavior? #11290

@droidmonkey droidmonkey changed the title App freezes after entering master password App freezes after entering master password - ssh-agent deadlock Sep 23, 2024
@github-project-automation github-project-automation bot moved this to To triage in WIP Tracker Sep 23, 2024
@droidmonkey droidmonkey moved this from To triage to In review in WIP Tracker Sep 23, 2024
@vogr
Copy link

vogr commented Sep 23, 2024

I built #11290, I can confirm that the database successfully unlocks after a short wait and shows the error "Agent protocol error". After that, I can also properly use "Add key to SSH agent" without having to lock and unlock the database again. Thanks!

@droidmonkey
Copy link
Member

droidmonkey commented Sep 23, 2024

Excellent, I might lower the timeout to 3 seconds, it's current at 5

droidmonkey added a commit that referenced this issue Oct 26, 2024
@github-project-automation github-project-automation bot moved this from In review to Done in WIP Tracker Nov 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

4 participants