mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-10 22:18:54 +01:00
wallet: avoid returning a reference to vMasterKey after releasing the mutex that guards it
`CWallet::GetEncryptionKey()` would return a reference to the internal
`CWallet::vMasterKey`, guarded by `CWallet::cs_wallet`, which is unsafe.
Returning a copy would be a shorter solution, but could have security
implications of the master key remaining somewhere in the memory even
after `CWallet::Lock()` (the current calls to
`CWallet::GetEncryptionKey()` are safe, but that is not future proof).
So, instead of `EncryptSecret(m_storage.GetEncryptionKey(), ...)`
change the `GetEncryptionKey()` method to provide the encryption
key to a given callback:
`m_storage.WithEncryptionKey([](const CKeyingMaterial& k) { EncryptSecret(k, ...); })`
This silences the following (clang 18):
```
wallet/wallet.cpp:3520:12: error: returning variable 'vMasterKey' by reference requires holding mutex 'cs_wallet' [-Werror,-Wthread-safety-reference-return]
3520 | return vMasterKey;
| ^
```
This commit is contained in:
@@ -811,7 +811,9 @@ bool LegacyScriptPubKeyMan::AddKeyPubKeyInner(const CKey& key, const CPubKey &pu
|
||||
|
||||
std::vector<unsigned char> vchCryptedSecret;
|
||||
CKeyingMaterial vchSecret{UCharCast(key.begin()), UCharCast(key.end())};
|
||||
if (!EncryptSecret(m_storage.GetEncryptionKey(), vchSecret, pubkey.GetHash(), vchCryptedSecret)) {
|
||||
if (!m_storage.WithEncryptionKey([&](const CKeyingMaterial& encryption_key) {
|
||||
return EncryptSecret(encryption_key, vchSecret, pubkey.GetHash(), vchCryptedSecret);
|
||||
})) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -997,7 +999,9 @@ bool LegacyScriptPubKeyMan::GetKey(const CKeyID &address, CKey& keyOut) const
|
||||
{
|
||||
const CPubKey &vchPubKey = (*mi).second.first;
|
||||
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
|
||||
return DecryptKey(m_storage.GetEncryptionKey(), vchCryptedSecret, vchPubKey, keyOut);
|
||||
return m_storage.WithEncryptionKey([&](const CKeyingMaterial& encryption_key) {
|
||||
return DecryptKey(encryption_key, vchCryptedSecret, vchPubKey, keyOut);
|
||||
});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -2128,7 +2132,9 @@ std::map<CKeyID, CKey> DescriptorScriptPubKeyMan::GetKeys() const
|
||||
const CPubKey& pubkey = key_pair.second.first;
|
||||
const std::vector<unsigned char>& crypted_secret = key_pair.second.second;
|
||||
CKey key;
|
||||
DecryptKey(m_storage.GetEncryptionKey(), crypted_secret, pubkey, key);
|
||||
m_storage.WithEncryptionKey([&](const CKeyingMaterial& encryption_key) {
|
||||
return DecryptKey(encryption_key, crypted_secret, pubkey, key);
|
||||
});
|
||||
keys[pubkey.GetID()] = key;
|
||||
}
|
||||
return keys;
|
||||
@@ -2262,7 +2268,9 @@ bool DescriptorScriptPubKeyMan::AddDescriptorKeyWithDB(WalletBatch& batch, const
|
||||
|
||||
std::vector<unsigned char> crypted_secret;
|
||||
CKeyingMaterial secret{UCharCast(key.begin()), UCharCast(key.end())};
|
||||
if (!EncryptSecret(m_storage.GetEncryptionKey(), secret, pubkey.GetHash(), crypted_secret)) {
|
||||
if (!m_storage.WithEncryptionKey([&](const CKeyingMaterial& encryption_key) {
|
||||
return EncryptSecret(encryption_key, secret, pubkey.GetHash(), crypted_secret);
|
||||
})) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user