diff --git a/src/consensus/tx_check.cpp b/src/consensus/tx_check.cpp --- a/src/consensus/tx_check.cpp +++ b/src/consensus/tx_check.cpp @@ -29,7 +29,7 @@ "bad-txns-oversize"); } - // Check for negative or overflow output values + // Check for negative or overflow output values (see CVE-2010-5139) Amount nValueOut = Amount::zero(); for (const auto &txout : tx.vout) { if (txout.nValue < Amount::zero()) { @@ -41,7 +41,6 @@ return state.Invalid(TxValidationResult::TX_CONSENSUS, REJECT_INVALID, "bad-txns-vout-toolarge"); } - nValueOut += txout.nValue; if (!MoneyRange(nValueOut)) { return state.Invalid(TxValidationResult::TX_CONSENSUS, diff --git a/src/net_processing.cpp b/src/net_processing.cpp --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -2988,7 +2988,7 @@ AddOrphanTx(ptx, pfrom->GetId()); // DoS prevention: do not allow mapOrphanTransactions to grow - // unbounded + // unbounded (see CVE-2012-3789) unsigned int nMaxOrphanTx = (unsigned int)std::max( int64_t(0), gArgs.GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS)); diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -139,7 +139,7 @@ return set_error(serror, ScriptError::OP_COUNT); } - // Some opcodes are disabled. + // Some opcodes are disabled (CVE-2010-5137). if (IsOpcodeDisabled(opcode, flags)) { return set_error(serror, ScriptError::DISABLED_OPCODE); } @@ -1712,6 +1712,8 @@ ScriptExecutionMetrics metrics = {}; + // scriptSig and scriptPubKey must be evaluated sequentially on the same + // stack rather than being simply concatenated (see CVE-2010-5141) std::vector stack, stackCopy; if (!EvalScript(stack, scriptSig, flags, checker, metrics, serror)) { // serror is set diff --git a/src/test/data/script_tests.json b/src/test/data/script_tests.json --- a/src/test/data/script_tests.json +++ b/src/test/data/script_tests.json @@ -1052,7 +1052,7 @@ ["NOP", "SIZE 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["Disabled opcodes"], +["Disabled opcodes (CVE-2010-5137)"], ["'abc'", "IF INVERT ELSE 1 ENDIF", "P2SH,STRICTENC", "DISABLED_OPCODE", "INVERT disabled"], ["2 0 IF 2MUL ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "2MUL disabled"], ["2 0 IF 2DIV ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "2DIV disabled"], diff --git a/src/validation.cpp b/src/validation.cpp --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1574,7 +1574,7 @@ // transactions, unless those are already completely spent. If such // overwrites are allowed, coinbases and transactions depending upon those // can be duplicated to remove the ability to spend the first instance -- - // even after being sent to another address. See BIP30 and + // even after being sent to another address. See BIP30, CVE-2012-1909, and // http://r6.ca/blog/20120206T005236Z.html for more information. This logic // is not necessary for memory pool transactions, as AcceptToMemoryPool // already refuses previously-known transaction ids entirely. This rule was diff --git a/test/functional/feature_block.py b/test/functional/feature_block.py --- a/test/functional/feature_block.py +++ b/test/functional/feature_block.py @@ -699,7 +699,7 @@ # # Blocks are not allowed to contain a transaction whose id matches that of an earlier, # not-fully-spent transaction in the same chain. To test, make identical coinbases; - # the second one should be rejected. + # the second one should be rejected. See also CVE-2012-1909. # self.log.info( "Reject a block with a transaction with a duplicate hash of a previous transaction (BIP30)") diff --git a/test/functional/mempool_accept.py b/test/functional/mempool_accept.py --- a/test/functional/mempool_accept.py +++ b/test/functional/mempool_accept.py @@ -227,6 +227,8 @@ rawtxs=[ToHex(tx)], ) + # The following two validations prevent overflow of the output amounts + # (see CVE-2010-5139). self.log.info('A transaction with too large output value') tx = FromHex(CTransaction(), raw_tx_reference) tx.vout[0].nValue = 21000000 * COIN + 1 diff --git a/test/functional/p2p_invalid_block.py b/test/functional/p2p_invalid_block.py --- a/test/functional/p2p_invalid_block.py +++ b/test/functional/p2p_invalid_block.py @@ -59,10 +59,12 @@ block_time = best_block["time"] + 1 # Use merkle-root malleability to generate an invalid block with - # same blockheader. + # same blockheader (CVE-2012-2459). # Manufacture a block with 3 transactions (coinbase, spend of prior # coinbase, spend of that spend). Duplicate the 3rd transaction to # leave merkle root and blockheader unchanged but invalidate the block. + # For more information on merkle-root malleability see + # src/consensus/merkle.cpp. self.log.info("Test merkle root malleability.") block2 = create_block(tip, create_coinbase(height), block_time) @@ -92,7 +94,7 @@ node.p2p.send_blocks_and_test( [block2], node, success=False, reject_reason='bad-txns-duplicate') - # Check transactions for duplicate inputs + # Check transactions for duplicate inputs (CVE-2018-17144) self.log.info("Test duplicate input block.") block2_orig.vtx[2].vin.append(block2_orig.vtx[2].vin[0])