Refactor YubiKey key to avoid deadlock

- Add mutex to get m_connectedKeys
- Fix deadlock when the app uses Quick Unlock and the YubiKey is unplugged
This commit is contained in:
w15dev 2025-01-29 02:23:15 +03:00 committed by Jonathan White
parent 5ee5e4998a
commit 81fa8d5947
2 changed files with 15 additions and 3 deletions

View File

@ -75,11 +75,19 @@ bool YubiKey::findValidKeys()
{ {
QMutexLocker lock(&s_interfaceMutex); QMutexLocker lock(&s_interfaceMutex);
findValidKeys(lock);
return !m_usbKeys.isEmpty() || !m_pcscKeys.isEmpty();
}
void YubiKey::findValidKeys(const QMutexLocker& locker)
{
// Check QMutexLocker since version 6.4
Q_UNUSED(locker);
m_connectedKeys = 0; m_connectedKeys = 0;
m_usbKeys = YubiKeyInterfaceUSB::instance()->findValidKeys(m_connectedKeys); m_usbKeys = YubiKeyInterfaceUSB::instance()->findValidKeys(m_connectedKeys);
m_pcscKeys = YubiKeyInterfacePCSC::instance()->findValidKeys(m_connectedKeys); m_pcscKeys = YubiKeyInterfacePCSC::instance()->findValidKeys(m_connectedKeys);
return !m_usbKeys.isEmpty() || !m_pcscKeys.isEmpty();
} }
void YubiKey::findValidKeysAsync() void YubiKey::findValidKeysAsync()
@ -98,6 +106,8 @@ YubiKey::KeyMap YubiKey::foundKeys()
int YubiKey::connectedKeys() int YubiKey::connectedKeys()
{ {
QMutexLocker lock(&s_interfaceMutex);
return m_connectedKeys; return m_connectedKeys;
} }
@ -171,7 +181,7 @@ YubiKey::challenge(YubiKeySlot slot, const QByteArray& challenge, Botan::secure_
// Make sure we tried to find available keys // Make sure we tried to find available keys
if (m_usbKeys.isEmpty() && m_pcscKeys.isEmpty()) { if (m_usbKeys.isEmpty() && m_pcscKeys.isEmpty()) {
findValidKeys(); findValidKeys(lock);
} }
if (m_usbKeys.contains(slot)) { if (m_usbKeys.contains(slot)) {

View File

@ -84,6 +84,8 @@ signals:
private: private:
explicit YubiKey(); explicit YubiKey();
void findValidKeys(const QMutexLocker& locker);
static YubiKey* m_instance; static YubiKey* m_instance;
QTimer m_interactionTimer; QTimer m_interactionTimer;