-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
High CPU usage when using --pw-stdin and a a non-existing database #1620
Labels
Milestone
Comments
Thank you for such a detailed explanation! |
I think we should fix this for 2.3.1 |
phoerious
added a commit
that referenced
this issue
Mar 4, 2018
phoerious
added a commit
that referenced
this issue
Mar 4, 2018
Please test #1628 and see if it fixes the problem for you. |
phoerious
added a commit
that referenced
this issue
Mar 4, 2018
@phoerious Just did some quick tests with the branch you linked, and I haven't been able to replicate the bug, so it seems it is correctly fixed. |
phoerious
added a commit
that referenced
this issue
Mar 6, 2018
jtl999
pushed a commit
to jtl999/keepassxc
that referenced
this issue
Jul 29, 2018
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
KeePassXC can be set, through the command line, to unlock a database when starting up. The password can be provided through the standard input, like so:
echo 1234 | keepassxc Database.kdbx --pw-stdin
(Note that this is broken on release 2.3.0, so using the current HEAD of the git repository is required.)
If the Database.kdbx file exists, this works correctly. However, if Database.kdbx does not exist (e.g. because the user specified the wrong filename), the above command line causes KeePassXC to hang with 100% CPU usage for a long time.
Note that the description above is the common use case for reproducing the bug, but the bug can be reproduced by simply running:
echo randomstring | keepassxc
That is, KeePassXC hangs with 100% CPU when providing garbage input through the command line, which includes the case where the database does not exist (since in that case,
--pw-stdin
is just ignored).Expected Behavior
KeePassXC should not hang when providing simple invalid inputs through the command line or standard input.
Current Behavior
KeePassXC hangs with 100% CPU on the examples provided above.
Technical explanation
In the first case, if a database file name and
--pw-stdin
are provided, but the specified database file does not exist, those parameters are simply ignored, without any byte from the standard input being consumed. So, the first case is equivalent to the second case currently.In either case, the hang happens in
NativeMessagingHost::readStdIn
. This is because in the native messaging API, messages are provided through a(u32 length)(byte[length] message)
format. KeePassXC will interpret the garbage string in the standard input as a very large 32-bit unsigned length, which will cause a very large character-by-character read which will cause the hang with 100% CPU usage. Note that KeePassXC will try to readlength
characters even if EOF happens prematurely.Possible Solution
To fix the main problem (the hang), I propose that in
NativeMessagingHost::readStdIn
, while doing the read of the actual message, if EOF happens, then the read stops prematurely and the message is ignored. This is similar to the!std::cin.eof()
check that is already being done when reading the message length, but it should be done with the content of the message instead of the length.Additionally, it may be worth changing the behavior of KeePassXC when using an invalid database name along with
--pw-stdin
. In this case, it may be better if a line of stdin is consumed anyway, to avoid garbage data being provided toNativeMessagingHost
in this case. I also don't know if runningNativeMessagingHost
has any valid use case along with--pw-stdin
, in this case, it may be better to not runNativeMessagingHost
if--pw-stdin
has been passed.Steps to Reproduce (for bugs)
Run any of the following command line commands:
echo 1234 | keepassxc /does/not/exist.kdbx --pw-stdin
echo randomstring | keepassxc
Context
I was trying to set up an script to unlock my database on login, using the
--pw-stdin
option and the database file name through the command line. However, sometimes the block device that contains my database is not mounted, so the database file does not exist. I expected KeePassXC to either fail or not run in this case, but instead it hangs on 100% CPU.Debug Info
KeePassXC - Version 2.3.0-snapshot
Build Type: Snapshot
Revision: a06e85f
Libraries:
Operating system: Arch Linux
CPU architecture: x86_64
Kernel: linux 4.15.6-1-ARCH
Enabled extensions:
The text was updated successfully, but these errors were encountered: