libwalletqt: capture background sync password by value
What changed, and why it matters
This commit changes how a wallet password is passed into a background task. Previously, the password was captured by reference (a pointer to the original variable), which could mean the task reads from memory that is no longer valid if the original variable is destroyed before the task runs. Now it is captured by value, making a safe copy. This is a defensive fix that may prevent a use-after-free or read of stale memory, but the commit itself does not prove an exploitable vulnerability exists.
Treat as a hardening/lifetime fix. Review whether the scheduler can outlive the caller and confirm no other sensitive variables in the same lambda or nearby scheduler calls are captured by reference. Consider adding a regression test or code-review checklist for lambda captures of secrets.
Security signals we found
Password-related variable changed from by-reference to by-value capture
Asynchronous scheduler lambda captures local variable
Potential use-after-free / stale read of sensitive string data
Single-line lifetime fix in wallet background sync path
Evidence from the diff
In Wallet::setupBackgroundSync(), the lambda submitted to m_scheduler.run captured wallet_password by reference (&wallet_password). If the scheduler executes the lambda asynchronously after the caller’s wallet_password QString has gone out of scope or been modified, the lambda would reference invalid or changed memory. The patch captures wallet_password by value, ensuring a copy exists for the lifetime of the lambda. This is a classic C++ lifetime bug fix; the security relevance is that a password string could be read from freed memory or observe unintended mutations.
Changed components
src/libwalletqt/Wallet.cppWallet::setupBackgroundSync()Background sync scheduler taskInspect captured patch +1 / −1
diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp
index a5ac692..d9720dc 100644
--- a/src/libwalletqt/Wallet.cpp
+++ b/src/libwalletqt/Wallet.cpp
@@ -536,7 +536,7 @@ void Wallet::setupBackgroundSync(const Wallet::BackgroundSyncType background_syn
pauseRefresh();
// run inside scheduler because of lag when stopping/starting refresh
- m_scheduler.run([this, refreshEnabled, background_sync_type, &wallet_password] {
+ m_scheduler.run([this, refreshEnabled, background_sync_type, wallet_password] {
m_walletImpl->setupBackgroundSync(
static_cast<Monero::Wallet::BackgroundSyncType>(background_sync_type),
wallet_password.toStdString(),
Why this scored 57/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.