Summary: | Fingerprint unlock prompt deactivates after a moment | ||
---|---|---|---|
Product: | [Plasma] plasmashell | Reporter: | alhsk |
Component: | Screen locking | Assignee: | Plasma Bugs List <plasma-bugs> |
Status: | CONFIRMED --- | ||
Severity: | major | CC: | kdedev, mk.mateng, nate, variable_valuables761, vpsink |
Priority: | HI | Keywords: | regression |
Version First Reported In: | 6.4.5 | ||
Target Milestone: | 1.0 | ||
Platform: | Arch Linux | ||
OS: | Linux | ||
See Also: |
https://bugs.kde.org/show_bug.cgi?id=458130 https://bugs.kde.org/show_bug.cgi?id=508247 |
||
Latest Commit: | Version Fixed In: | ||
Sentry Crash Report: |
Description
alhsk
2025-07-04 07:19:31 UTC
I'm able to reproduce this in git-master, but only if I wait for a while after the screen locks. If I let it lock automatically, and unlock it right away, fingerprint unlock works as usual. This could be a variant of bug 458130. Are you able to reproduce this as soon as the screen locks? (In reply to TraceyC from comment #1) > I'm able to reproduce this in git-master, but only if I wait for a while > after the screen locks. If I let it lock automatically, and unlock it right > away, fingerprint unlock works as usual. This could be a variant of bug > 458130. > > Are you able to reproduce this as soon as the screen locks?我能够在 git-master > 中重现这一点,但前提是我在屏幕锁定后等待一段时间。如果我让它自动锁定并立即解锁,指纹解锁会照常工作。这可能是 bug 458130 的变体。 > > 您能否在屏幕锁定后立即重现此内容? Yes Sorry,I replay too late Thanks for letting us know. I'll keep this open in case someone else is able to reproduce it. When you have the unlock prompt that has no fingerprint text, if you press Enter, can you unlock with the fingerprint? (In reply to TraceyC from comment #4) > When you have the unlock prompt that has no fingerprint text, if you press > Enter, can you unlock with the fingerprint? NO,it didn't work at all (In reply to alhsk from comment #5) > NO,it didn't work at all Thanks for clarifying. I'll let the plasmashell developers take it from here. Correcting priority, since this is not a feature request, it's a bug I can reproduce this on git master too. I'm now also seeing this on git-master I can confirm this as well on latest Plasma (6.4.5, Arch). The label "press finger on sensor" sometimes activates, and sometimes deactivates, usually after suspend. I'm fairly sure this didn't happen before (6.3.x), although I'm not sure. I'd be cool if someone cranked up the importance of this bug, or indicated where and what component are responsible of handling the fingerprint stuff so we can start looking into it. As another data point, I'm seeing this on git master too. My laptop doesn't have a fingerprint scanner or card reader, but if I leave it idle for long enough and then wake, both messages are shown briefly then disappear. aaaalright, so I compiled the _allegedly_ buggy component (kscreenlocker - plasma 6.4.5.x), ran it in debug mode and I believe I found what appears to be causing the issue. I don't know if this is hardware-dependent. 1. When the computer (laptop) goes to sleep, the BIOS sometimes likes to reset the fingerprint device, and it's enumerated again by fprintd upon wake up (and registered as a new fprint "Device") 2. This usually happens when closing the lid; and not when manually suspending the computer (be it with KDE taskbar menu, Plasma Search's shortcuts or systemd's utilities). I suspect this is caused by either the BIOS or a bug in fprintd. 3. When the computer wakes up, kscreenlocker tries to "talk" again to the previous old device, but it miserably fails because at this point fprintd has already registered another device (this can be seen with `busctl tree net.reactivated.Fprint` - there should ideally be just 1 device, not 2) 4. The old fprintd device will simply stop working and even commands such as `fprintd-verify` will fail 5. Whenever this happens, the kscreenlock process will hang for a few secs before it finally exists. I don't thinks causes the bug, but it _might_ cause a bug if I lock/unlock my computer very quickly. I suspect this happens because kscreenlocker is waiting for the useless fprint "Device" to respond successfully or something. I worked this around doing the following: 1. Edit fprintd's systemd unit file and add `TimeoutStopSec=1` to immediately kill the (now useless) fprintd service after startup 2. Create an udev rule that automatically restarts the useless fprintd daemon whenever my *VERY SPECIFIC* fingerprint device is enumerated again: `/etc/udev/rules.d/99-fprintd.rules`: "ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="06cb", ATTR{idProduct}=="00fc", RUN+="/bin/systemctl restart fprintd" My suggestion: have KDE/Plasma automatically restart the fprintd service if it returns an invalid error code (9), or at the very least indicate this on the lockscreen, e.g. something such as "fingerprint sensor disabled due to buggy driver". fprintd logs: ``` Sep 24 14:09:49 xxx fprintd[12371]: Authorization denied to :1.337 to call method 'Claim' for device 'Synaptics Sensors': Device was already claimed Sep 24 14:10:06 xxx fprintd[12371]: Authorization denied to :1.341 to call method 'Claim' for device 'Synaptics Sensors': Device was already claimed Sep 24 14:10:17 xxx fprintd[12371]: Authorization denied to :1.344 to call method 'Claim' for device 'Synaptics Sensors': Device was already claimed Sep 24 14:11:13 xxx systemd[1]: fprintd.service: State 'stop-sigterm' timed out. Killing. ``` `fprintd-verify` output: ``` Using device /net/reactivated/Fprint/Device/1 failed to claim device: GDBus.Error:net.reactivated.Fprint.Error.AlreadyInUse: Device was already claimed ``` kscreenlocker (I added a few debug messages to the source), but you can see it fails to talk to fprintd, and hence it disables the fingerprint option. I am still able to manually unlock and that's why `Unlocked` is printed at the end: ``` kscreenlocker_greet: Greeter is starting up. kscreenlocker_greet: Greeter is running in testing mode kscreenlocker_greet: Testing mode enabled: true kscreenlocker_greet: [PAM worker kde-smartcard] start: successfully started kscreenlocker_greet: [PAM worker kde-fingerprint] start: successfully started kscreenlocker_greet: [PAM worker kde] start: successfully started Locked at 1758743384 kscreenlocker_greet: PamAuthenticators: starting authenticators kscreenlocker_greet: PamAuthenticators: state changing from PamAuthenticators::Idle to PamAuthenticators::Authenticating kscreenlocker_greet: [PAM worker kde-smartcard] Authenticate: Starting authentication kscreenlocker_greet: [PAM worker kde] Authenticate: Starting authentication kscreenlocker_greet: [PAM worker kde-fingerprint] Authenticate: Starting authentication kscreenlocker_greet: PamAuthenticators: Availability changed for non-interactive authenticator kde-smartcard true kscreenlocker_greet: PamAuthenticators: Availability changed for non-interactive authenticator kde-fingerprint true kscreenlocker_greet: PamAuthenticators: Delay started on login failure for non-interactive authenticator kde-smartcard duration: 2017873 kscreenlocker_greet: [PAM worker kde] Message: Echo-off prompt: Password: kscreenlocker_greet: [PAM worker kde] Starting nested event loop to await response kscreenlocker_greet: PamAuthenticators: Secret prompt from interactive authenticator kde kscreenlocker_greet: PamAuthenticators: Delay started on login failure for non-interactive authenticator kde-fingerprint duration: 1326118 kscreenlocker_greet: [PAM worker kde-fingerprint] Authenticate: Authentication done, result code: 9 (Authentication service cannot retrieve authentication info) kscreenlocker_greet: [PAM worker] UNAVAIL/UNKNOWN m_unavailable= true kscreenlocker_greet: PamAuthenticators: Availability changed for non-interactive authenticator kde-fingerprint false kscreenlocker_greet: PamAuthenticators: Availability changed for non-interactive authenticator kde-fingerprint false kscreenlocker_greet: [PAM worker kde-smartcard] Authenticate: Authentication done, result code: 28 (Module is unknown) kscreenlocker_greet: [PAM worker] UNAVAIL/UNKNOWN m_unavailable= true kscreenlocker_greet: PamAuthenticators: Availability changed for non-interactive authenticator kde-smartcard false kscreenlocker_greet: PamAuthenticators: Availability changed for non-interactive authenticator kde-smartcard false kscreenlocker_greet: PamAuthenticators: responding to interactive authenticator kscreenlocker_greet: [PAM worker kde] Received response, exiting nested event loop kscreenlocker_greet: PamAuthenticators: Interactive authenticator kde changed business kscreenlocker_greet: [PAM worker] Fail delay function was called, but authentication result was a success! kscreenlocker_greet: [PAM worker kde] Authenticate: Authentication done, result code: 0 (Success) kscreenlocker_greet: PamAuthenticators: Interactive authenticator kde changed business < ... HANGS for some 5-10s before finally exiting ... > kscreenlocker_greet: [PAM worker] PAM_SUCCESS m_unavailable= false kscreenlocker_greet: PamAuthenticators: Success from interactive authenticator kde Unlocked ``` Ah, nevermind :(. Unfortunately, the udev hack doesn't appear to work reliably because the klockscreen component also has some logic that seems flawed. Good thing is that I managed to somehow fix it with the udev hack and by handling some corner cases in klockscreen. I also came up with a reliable way to reproduce this error with current plasma (6.4.5): 1. Restart fprintd service to start with a clean slate (systemctl restart fprintd), or kill fprintd with pkill 2. Lock the screen (at this point, the "(or press your fingerprint)" thing will appear. Do not unlock with fingerprint. 3. Either close the lid or hit the lockscreen suspend button, or do whatever anything t 4. Wake the computer up again. At this point, it appears that no matter what, even if the fprintd service is restarted to make it work again, klockscreen won't "detect" fprintd is up again. So even if the fprintd hack were to be used, klockscreen's auth logic is slightly bugged because it won't retry to use fprintd again. It permanently "thinks" the fprintd thing is dead. I'm a developer, although I have absolutely 0.000% C++/Qt experience whatsoever but I came up with the following patch and it has worked fairly well for me. I must say however, that it appears to increment the PAM faillock count by 2 (this was already an issue for me even without the patches - though vanilla klockscreen only increased the count by 1, so this underlying bug might be caused due to klockscreen triggering a pam error or something). Note to KDE devs: I'm willing to help you fix this issue. ``` diff --git a/greeter/pamauthenticator.cpp b/greeter/pamauthenticator.cpp index 077831d..d5b9963 100644 --- a/greeter/pamauthenticator.cpp +++ b/greeter/pamauthenticator.cpp @@ -132,6 +132,9 @@ int PamWorker::converse(int n, const struct pam_message **msg, struct pam_respon // if there's only the info message, let's predict the prompts too const QString info = QString::fromLocal8Bit(msg[i]->msg); qCDebug(KSCREENLOCKER_GREET, "[PAM worker %s] Message: Info message: %s", qUtf8Printable(c->m_service), qUtf8Printable(info)); + // If fingerprint device sends info message, it's now available + c->m_unavailable = false; + Q_EMIT c->unavailabilityChanged(c->m_unavailable); Q_EMIT c->infoMessage(info); break; } @@ -159,7 +162,7 @@ PamWorker::~PamWorker() void PamWorker::authenticate() { - if (m_inAuthenticate || m_unavailable) { + if (m_inAuthenticate) { return; } m_inAuthenticate = true; @@ -177,6 +180,8 @@ void PamWorker::authenticate() if (rc == PAM_SUCCESS) { rc = pam_setcred(m_handle, PAM_REFRESH_CRED); /* ignore errors on refresh credentials. If this did not work we use the old ones. */ + m_unavailable = false; + Q_EMIT unavailabilityChanged(m_unavailable); Q_EMIT succeeded(); } else if (rc == PAM_AUTHINFO_UNAVAIL || rc == PAM_MODULE_UNKNOWN) { m_unavailable = true; @@ -309,7 +314,7 @@ bool PamAuthenticator::isBusy() const bool PamAuthenticator::isAvailable() const { - return m_inAuthentication && !m_unavailable; + return !m_unavailable; } PamAuthenticator::NoninteractiveAuthenticatorTypes PamAuthenticator::authenticatorType() const diff --git a/greeter/pamauthenticators.cpp b/greeter/pamauthenticators.cpp index e9e925a..f1f6348 100644 --- a/greeter/pamauthenticators.cpp +++ b/greeter/pamauthenticators.cpp @@ -18,6 +18,7 @@ struct PamAuthenticators::Private { AuthenticatorsState state = AuthenticatorsState::Idle; bool graceLocked = false; bool hadPrompt = false; + bool interactiveCancelledByFingerprint = false; void recomputeNoninteractiveAuthenticationTypes() { @@ -51,7 +52,11 @@ PamAuthenticators::PamAuthenticators(std::unique_ptr<PamAuthenticator> &&interac qCDebug(KSCREENLOCKER_GREET) << "PamAuthenticators: Failure from interactive authenticator" << qUtf8Printable(d->interactive->service()); setState(AuthenticatorsState::Idle); d->cancelNoninteractive(); - Q_EMIT failed(PamAuthenticator::NoninteractiveAuthenticatorType::None, d->interactive.get()); + // Don't emit failed if interactive was cancelled due to fingerprint becoming available + if (!d->interactiveCancelledByFingerprint) { + Q_EMIT failed(PamAuthenticator::NoninteractiveAuthenticatorType::None, d->interactive.get()); + } + d->interactiveCancelledByFingerprint = false; }); connect(d->interactive.get(), &PamAuthenticator::loginFailedDelayStarted, this, [this](const uint uSecDelay) noexcept -> void { qCDebug(KSCREENLOCKER_GREET) << "PamAuthenticators: Delay started on login failure for interactive authenticator" << qUtf8Printable(d->interactive->service()) @@ -83,6 +88,8 @@ PamAuthenticators::PamAuthenticators(std::unique_ptr<PamAuthenticator> &&interac d->hadPrompt = true; Q_EMIT hadPromptChanged(); } + // Mark that interactive will be cancelled due to fingerprint becoming available + d->interactiveCancelledByFingerprint = true; qCDebug(KSCREENLOCKER_GREET) << "PamAuthenticators: Info message from non-interactive authenticator" << qUtf8Printable(noninteractive->service()); Q_EMIT noninteractiveInfo(noninteractive->authenticatorType(), noninteractive.get()); }); ``` (In reply to Caballo Juan from comment #13) > I'm a developer, although I have absolutely 0.000% C++/Qt experience > whatsoever but I came up with the following patch and it has worked fairly > well for me. You can submit a merge request to the relevant project on Gitlab, where it will be reviewed by the devs. (I'm not a KDE dev myself, so can't help you with the details.) Yes, please do submit that on invent.kde.org! (In reply to Nate Graham from comment #15) > Yes, please do submit that on invent.kde.org! Sure! However, this patch doesn't fix everything as I mentioned earlier (and it can't). My patch merely allows klockscreen to talk to fprintd if it ever gets restarted. The rest of the problem must be fixed in fprintd (that's why I used an udev rule to forcefully restart it, and thus allow klockscreen to talk to it again). I'll try to get the patch merged anyway, as that should make klockscreeen basically immune to temporary sensor errors. :) |