mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-23 07:15:29 +01:00
wallet: throw error if legacy entries are present on loading descriptor wallets
In the wallet key-value-loading routine, most legacy type entries require a LegacyScriptPubKeyMan instance after successful deserialization. On a descriptor wallet, creating that (via method `GetOrCreateLegacyScriptPubKeyMan`) fails and then leads to a null-pointer dereference crash. Fix this by throwing an error if if the wallet flags indicate that we have a descriptor wallet and there is a legacy entry found.
This commit is contained in:
parent
50422b770a
commit
349ed2a0ee
3 changed files with 18 additions and 1 deletions
|
@ -2919,6 +2919,10 @@ std::shared_ptr<CWallet> CWallet::Create(WalletContext& context, const std::stri
|
||||||
"The wallet might had been created on a newer version.\n"
|
"The wallet might had been created on a newer version.\n"
|
||||||
"Please try running the latest software version.\n"), walletFile);
|
"Please try running the latest software version.\n"), walletFile);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
} else if (nLoadWalletRet == DBErrors::UNEXPECTED_LEGACY_ENTRY) {
|
||||||
|
error = strprintf(_("Unexpected legacy entry in descriptor wallet found. Loading wallet %s\n\n"
|
||||||
|
"The wallet might have been tampered with or created with malicious intent.\n"), walletFile);
|
||||||
|
return nullptr;
|
||||||
} else {
|
} else {
|
||||||
error = strprintf(_("Error loading %s"), walletFile);
|
error = strprintf(_("Error loading %s"), walletFile);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -315,6 +315,7 @@ public:
|
||||||
std::map<uint160, CHDChain> m_hd_chains;
|
std::map<uint160, CHDChain> m_hd_chains;
|
||||||
bool tx_corrupt{false};
|
bool tx_corrupt{false};
|
||||||
bool descriptor_unknown{false};
|
bool descriptor_unknown{false};
|
||||||
|
bool unexpected_legacy_entry{false};
|
||||||
|
|
||||||
CWalletScanState() = default;
|
CWalletScanState() = default;
|
||||||
};
|
};
|
||||||
|
@ -332,6 +333,11 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
|
||||||
if (filter_fn && !filter_fn(strType)) {
|
if (filter_fn && !filter_fn(strType)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// Legacy entries in descriptor wallets are not allowed, abort immediately
|
||||||
|
if (pwallet->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS) && DBKeys::LEGACY_TYPES.count(strType) > 0) {
|
||||||
|
wss.unexpected_legacy_entry = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (strType == DBKeys::NAME) {
|
if (strType == DBKeys::NAME) {
|
||||||
std::string strAddress;
|
std::string strAddress;
|
||||||
ssKey >> strAddress;
|
ssKey >> strAddress;
|
||||||
|
@ -833,6 +839,12 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
|
||||||
std::string strType, strErr;
|
std::string strType, strErr;
|
||||||
if (!ReadKeyValue(pwallet, ssKey, ssValue, wss, strType, strErr))
|
if (!ReadKeyValue(pwallet, ssKey, ssValue, wss, strType, strErr))
|
||||||
{
|
{
|
||||||
|
if (wss.unexpected_legacy_entry) {
|
||||||
|
strErr = strprintf("Error: Unexpected legacy entry found in descriptor wallet %s. ", pwallet->GetName());
|
||||||
|
strErr += "The wallet might have been tampered with or created with malicious intent.";
|
||||||
|
pwallet->WalletLogPrintf("%s\n", strErr);
|
||||||
|
return DBErrors::UNEXPECTED_LEGACY_ENTRY;
|
||||||
|
}
|
||||||
// losing keys is considered a catastrophic error, anything else
|
// losing keys is considered a catastrophic error, anything else
|
||||||
// we assume the user can live with:
|
// we assume the user can live with:
|
||||||
if (IsKeyType(strType) || strType == DBKeys::DEFAULTKEY) {
|
if (IsKeyType(strType) || strType == DBKeys::DEFAULTKEY) {
|
||||||
|
|
|
@ -52,7 +52,8 @@ enum class DBErrors
|
||||||
LOAD_FAIL,
|
LOAD_FAIL,
|
||||||
NEED_REWRITE,
|
NEED_REWRITE,
|
||||||
NEED_RESCAN,
|
NEED_RESCAN,
|
||||||
UNKNOWN_DESCRIPTOR
|
UNKNOWN_DESCRIPTOR,
|
||||||
|
UNEXPECTED_LEGACY_ENTRY
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace DBKeys {
|
namespace DBKeys {
|
||||||
|
|
Loading…
Add table
Reference in a new issue