Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2017-20154: Implement fLimitFree to CTxMemPool::accept() · ghostlander/Phoenixcoin@987dd68

A vulnerability was found in ghostlander Phoenixcoin. It has been classified as problematic. Affected is the function CTxMemPool::accept of the file src/main.cpp. The manipulation leads to denial of service. Upgrading to version 0.6.6.1-pxc is able to address this issue. The name of the patch is 987dd68f71a7d8276cef3b6c3d578fd4845b5699. It is recommended to upgrade the affected component. The identifier of this vulnerability is VDB-217068.

CVE
#vulnerability#dos

@@ -480,9 +480,9 @@ bool CTransaction::CheckTransaction() const }

bool CTxMemPool::accept(CTxDB& txdb, CTransaction &tx, bool fCheckInputs, bool* pfMissingInputs) { bool CTxMemPool::accept(CTxDB &txdb, CTransaction &tx, bool fCheckInputs, bool fLimitFree, bool *pfMissingInputs) {
if (pfMissingInputs) *pfMissingInputs = false;
@@ -566,32 +566,29 @@ bool CTxMemPool::accept(CTxDB& txdb, CTransaction &tx, bool fCheckInputs, unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
// Don’t accept it if it can’t get into a block if(nFees < tx.GetMinFee(nTxSize, true, GMF_RELAY)) return error(“CTxMemPool::accept() : not enough fees”); if(fLimitFree && (nFees < tx.GetMinFee(nTxSize, true, GMF_RELAY))) return(error(“CTxMemPool::accept() : not enough fees”));
// Continuously rate-limit free transactions // This mitigates ‘penny-flooding’ – sending thousands of free transactions just to // be annoying or make other’s transactions take longer to confirm. if (nFees < MIN_RELAY_TX_FEE) { static CCriticalSection cs; if(fLimitFree && (nFees < MIN_RELAY_TX_FEE)) { static double dFreeCount; static int64 nLastTime; int64 nNow = GetTime();
{ LOCK(cs); // Use an exponentially decaying ~10-minute window: dFreeCount *= pow(1.0 - 1.0/600.0, (double)(nNow - nLastTime)); nLastTime = nNow; // -limitfreerelay unit is thousand-bytes-per-minute // At default rate it would take over a month to fill 1GB if (dFreeCount > GetArg("-limitfreerelay", 15)*10*1000 && !IsFromMe(tx)) return error(“CTxMemPool::accept() : free transaction rejected by rate limiter”); if (fDebug) printf("Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nTxSize); dFreeCount += nTxSize; } LOCK(cs);
// Use an exponentially decaying ~10-minute window: dFreeCount *= pow(1.0 - 1.0 / 600.0, (double)(nNow - nLastTime)); nLastTime = nNow; // -limitfreerelay unit is thousand-bytes-per-minute // At default rate it would take over a month to fill 1GB if(dFreeCount > GetArg("-limitfreerelay", 15) * 10 * 1000) return(error(“CTxMemPool::accept() : free transaction rejected by rate limiter”)); if(fDebug) printf("Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount + nTxSize); dFreeCount += nTxSize; }
// Check against previous transactions @@ -624,9 +621,10 @@ bool CTxMemPool::accept(CTxDB& txdb, CTransaction &tx, bool fCheckInputs, return true; }
bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMissingInputs) { return mempool.accept(txdb, *this, fCheckInputs, pfMissingInputs); bool CTransaction::AcceptToMemoryPool(CTxDB &txdb, bool fCheckInputs, bool fLimitFree, bool *pfMissingInputs) {
return mempool.accept(txdb, *this, fCheckInputs, fLimitFree, pfMissingInputs); }
bool CTxMemPool::addUnchecked(const uint256& hash, CTransaction &tx) @@ -730,9 +728,9 @@ int CMerkleTx::GetBlocksToMaturity() const }

bool CMerkleTx::AcceptToMemoryPool(CTxDB &txdb, bool fCheckInputs) { bool CMerkleTx::AcceptToMemoryPool(CTxDB &txdb, bool fCheckInputs, bool fLimitFree) {
return(CTransaction::AcceptToMemoryPool(txdb, fCheckInputs)); return(CTransaction::AcceptToMemoryPool(txdb, fCheckInputs, fLimitFree)); }
bool CMerkleTx::AcceptToMemoryPool() @@ -755,10 +753,10 @@ bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs) { uint256 hash = tx.GetHash(); if (!mempool.exists(hash) && !txdb.ContainsTx(hash)) tx.AcceptToMemoryPool(txdb, fCheckInputs); tx.AcceptToMemoryPool(txdb, fCheckInputs, false); } } return AcceptToMemoryPool(txdb, fCheckInputs); return(AcceptToMemoryPool(txdb, fCheckInputs, false)); } return false; } @@ -1581,7 +1579,7 @@ bool static Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
// Resurrect memory transactions that were in the disconnected branch BOOST_FOREACH(CTransaction& tx, vResurrect) tx.AcceptToMemoryPool(txdb, false); tx.AcceptToMemoryPool(txdb, true, false);
// Delete redundant memory transactions that are in the connected branch BOOST_FOREACH(CTransaction &tx, vDelete) { @@ -3022,8 +3020,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) }
bool fMissingInputs = false; if (tx.AcceptToMemoryPool(txdb, true, &fMissingInputs)) { if(tx.AcceptToMemoryPool(txdb, true, true, &fMissingInputs)) { SyncWithWallets(tx, NULL, true); RelayMessage(inv, vMsg); mapAlreadyAskedFor.erase(inv); @@ -3044,20 +3041,18 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) CInv inv(MSG_TX, tx.GetHash()); bool fMissingInputs2 = false;
if (tx.AcceptToMemoryPool(txdb, true, &fMissingInputs2)) { if(tx.AcceptToMemoryPool(txdb, true, true, &fMissingInputs2)) { printf(" accepted orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str()); SyncWithWallets(tx, NULL, true); RelayMessage(inv, vMsg); mapAlreadyAskedFor.erase(inv); vWorkQueue.push_back(inv.hash); vEraseQueue.push_back(inv.hash); } else if (!fMissingInputs2) { // invalid orphan else if(!fMissingInputs2) { /* Invalid or insufficient fee orphan */ vEraseQueue.push_back(inv.hash); printf(" removed invalid orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str()); printf(" removed orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str()); } } }

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda