From 11704e6023ec739b868b53b56b927ee2f15eaa5e Mon Sep 17 00:00:00 2001 From: DanS Date: Tue, 14 Jul 2026 11:21:28 -0500 Subject: [PATCH] fix(nspv): add missing length lower-bounds before request/vopret reads nSPV handlers (gated behind non-default -nspv_msg) read request[1]/vopret[1] before confirming the peer sent >=2 bytes: #6 (MEDIUM) NSPV_UTXOS/NSPV_TXIDS evaluated request[1] whenever len<69 (incl len==1); the 4351d5b73 value-clamp left this lower bound open. The TXIDS/MEMPOOL else-branch debug prints also read request[1] unconditionally. Add len>=2 guards / drop request[1] from the prints. #7 (LOW) NSPV_MEMPOOL_CCEVALCODE read vopret[1] on a possibly-1-byte vector. Guard with vopret.size()>=2. Co-Authored-By: Claude Opus 4.8 --- src/hush_nSPV_fullnode.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hush_nSPV_fullnode.h b/src/hush_nSPV_fullnode.h index 0bc2368a8..53817725c 100644 --- a/src/hush_nSPV_fullnode.h +++ b/src/hush_nSPV_fullnode.h @@ -324,7 +324,7 @@ int32_t NSPV_mempoolfuncs(bits256 *satoshisp,int32_t *vindexp,std::vector= 2 && vopret[0] == evalcode && vopret[1] == func ) { txids.push_back(hash); num++; @@ -657,7 +657,7 @@ void hush_nSPVreq(CNode *pfrom,std::vector request) // received a reque if ( timestamp > pfrom->prevtimes[ind] ) { struct NSPV_utxosresp U; - if ( len < 64+5 && request[1] < 64 && (request[1] == len-3 || request[1] == len-7 || request[1] == len-11) ) + if ( len >= 2 && len < 64+5 && request[1] < 64 && (request[1] == len-3 || request[1] == len-7 || request[1] == len-11) ) { int32_t skipcount = 0; char coinaddr[64]; uint8_t filter; uint8_t isCC = 0; memcpy(coinaddr,&request[2],request[1]); // request[1] < 64 bounds the copy + the terminator write @@ -697,7 +697,7 @@ void hush_nSPVreq(CNode *pfrom,std::vector request) // received a reque if ( timestamp > pfrom->prevtimes[ind] ) { struct NSPV_txidsresp T; - if ( len < 64+5 && request[1] < 64 && (request[1] == len-3 || request[1] == len-7 || request[1] == len-11) ) + if ( len >= 2 && len < 64+5 && request[1] < 64 && (request[1] == len-3 || request[1] == len-7 || request[1] == len-11) ) { int32_t skipcount = 0; char coinaddr[64]; uint32_t filter; uint8_t isCC = 0; memcpy(coinaddr,&request[2],request[1]); // request[1] < 64 bounds the copy + the terminator write @@ -730,7 +730,7 @@ void hush_nSPVreq(CNode *pfrom,std::vector request) // received a reque } NSPV_txidsresp_purge(&T); } - } else fprintf(stderr,"len.%d req1.%d\n",len,request[1]); + } else fprintf(stderr,"len.%d\n",len); } } else if ( request[0] == NSPV_MEMPOOL ) @@ -767,7 +767,7 @@ void hush_nSPVreq(CNode *pfrom,std::vector request) // received a reque NSPV_mempoolresp_purge(&M); } } - } else fprintf(stderr,"len.%d req1.%d\n",len,request[1]); + } else fprintf(stderr,"len.%d\n",len); } } else if ( request[0] == NSPV_NTZS )