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()) { 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,15 +1574,15 @@ // 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 - // 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 - // originally applied to all blocks with a timestamp after March 15, 2012, - // 0:00 UTC. Now that the whole chain is irreversibly beyond that time it is - // applied to all blocks except the two in the chain that violate it. This - // prevents exploiting the issue against nodes during their initial block - // download. + // 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 originally applied to all blocks + // with a timestamp after March 15, 2012, 0:00 UTC. Now that the whole + // chain is irreversibly beyond that time it is applied to all blocks + // except the two in the chain that violate it. This prevents exploiting + // the issue against nodes during their initial block download. bool fEnforceBIP30 = !((pindex->nHeight == 91842 && pindex->GetBlockHash() == uint256S("0x00000000000a4d0a398161ffc163c503763" 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 @@ -228,6 +228,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])