fix(nspv/wallet): bound nSPV request buffers + fix uninitialized fee / null-deref

hush_nSPV_fullnode.h: bound the REMOTERPC method strcpy and json memcpy to their
fixed buffers (method[64], json[11000]); add lower-length and memcpy-source bounds
to the UTXOS/TXIDS coinaddr[64] copies and the MEMPOOL handler. These paths
deserialize attacker-controlled request bytes -> stack overflow / OOB read. The
nSPV server is opt-in via -nspv_msg (off by default; DragonX uses lightwalletd).

rpc/blockchain.cpp: getchaintxstats null-checks pwalletMain (crash under -disablewallet).
wallet/rpcwallet.cpp: z_sendmany initializes nFee to the default miners fee (was read
uninitialized when no fee param supplied).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-13 15:56:09 -05:00
parent 4a0a334649
commit 4351d5b733
3 changed files with 19 additions and 13 deletions

View File

@@ -1654,7 +1654,7 @@ UniValue getchaintxstats(const UniValue& params, bool fHelp, const CPubKey& mypk
ret.pushKV("deshielding_payments", (int64_t)pindex->nChainDeshieldingPayments);
ret.pushKV("shielding_payments", (int64_t)pindex->nChainShieldingPayments);
int64_t nullifierCount = pwalletMain->NullifierCount();
int64_t nullifierCount = pwalletMain ? pwalletMain->NullifierCount() : 0; // null under -disablewallet
//TODO: this is unreliable, is only a cache or subset of total nullifiers
ret.pushKV("nullifiers", (int64_t)nullifierCount);
ret.pushKV("shielded_pool_size", (int64_t)(pindex->nChainShieldedOutputs - pindex->nChainShieldedSpends));