wallet2: validate block hash when repairing empty hashchain
What changed, and why it matters
This commit adds a safety check in Monero's wallet code. When the wallet tries to repair its local record of the blockchain (the 'hashchain'), it now refuses to continue if the network node returns a block hash that isn't a valid hexadecimal string. Before this change, an invalid or malformed hash could silently be converted to an empty or garbage value, potentially corrupting the wallet's view of the blockchain.
Treat as a hardening fix. Review whether other hex_to_pod() calls in wallet2.cpp and related RPC parsing paths similarly ignore return values. No immediate emergency response is indicated by the diff alone, but the fix should be included in the next maintenance release.
Security signals we found
Unchecked return value from hex string parsing
Potential silent corruption of blockchain hash chain state
Daemon-supplied input used without validation
Defensive input validation added in wallet-to-daemon RPC path
Evidence from the diff
In wallet2::trim_hashchain(), the code calls epee::string_tools::hex_to_pod() to convert the daemon-returned block_header.hash string into a crypto::hash. The previous code ignored the boolean return value, which indicates success/failure of the hex-to-binary conversion. The patch wraps the call in THROW_WALLET_EXCEPTION_IF so that a conversion failure throws a wallet_internal_error rather than leaving ‘hash’ in an indeterminate state and calling m_blockchain.refill(hash). This is a defensive validation fix; the actual security outcome depends on whether a malicious or buggy daemon could exploit the prior silent failure to cause consensus/wallet-state issues.
Changed components
src/wallet/wallet2.cppwallet2::trim_hashchain()m_blockchain hashchain refill logicInspect captured patch +2 / −1
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index fadfb9f..d0402d4 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -6816,7 +6816,8 @@ void wallet2::trim_hashchain()
if (m_node_rpc_proxy.get_block_header_by_height(m_blockchain.size() - 1, block_header))
throw std::runtime_error("Failed to request block header by height");
crypto::hash hash;
- epee::string_tools::hex_to_pod(block_header.hash, hash);
+ THROW_WALLET_EXCEPTION_IF(!epee::string_tools::hex_to_pod(block_header.hash, hash),
+ error::wallet_internal_error, "Daemon returned an invalid block hash");
m_blockchain.refill(hash);
}
catch(...)
Why this scored 42/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.