Repository navigation
Conversation
…rusted u32 prefixes Scorex Vec<T> parsing, NipopowProof/PoPowHeader parsing, and ReducedTransaction parsing pre-allocated buffers from u32 count/length prefixes taken from untrusted input, so a few bytes could abort the process with an allocation failure instead of returning a parse error (sibling of the ergotree-ir paths fixed for ergoplatform#944). - sigma-ser: cap Vec<T> pre-allocation at 1024; add scorex_parse_bytes_exact, which grows the buffer only as bytes arrive and errors exactly like read_exact on a short stream. - ergo-nipopow: cap prefix/suffix-tail pre-allocations; read the PoPowHeader header and interlinks-proof buffers via scorex_parse_bytes_exact. - ergo-lib: read the reduced transaction's embedded tx buffer via scorex_parse_bytes_exact, mapping Io back to SigmaParsingError::Io so the error on a short stream is unchanged. Fixes ergoplatform#946
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #946. Sibling of #945 (which fixed the same bug class in
ergotree-ir's Sigma paths for #944); this covers the Scorex serialization layer and the crates built on it, which that audit didn't reach.The gap
Four parse paths sized a buffer by an untrusted u32 prefix before reading a single payload byte, so a few input bytes aborted the process with an allocation failure instead of returning a parse error (all reproduced on
developunder a 2 GB address-space limit):Vec<T>::scorex_parse— VLQu32::MAXcount → 17 GB allocation (foru32items), SIGABRTNipopowProof::scorex_parseprefix countu32::MAX→ ~1.58 TB allocation, SIGABRTPoPowHeader::scorex_parseheader sizeu32::MAX→ 4 GB allocation, SIGABRTReducedTransaction::sigma_parsetx lengthu32::MAX→ 4 GB allocation, SIGABRTNiPoPoW proofs arrive from peers, and a reduced transaction (EIP-19) exists to be transferred and parsed by another party (e.g. a cold wallet) — both should fail with a parse error, not abort.
The fix (same pattern as #945)
sigma-ser:Vec<T>::scorex_parsecaps the pre-allocation at 1024 elements (the buffer still grows to the real count as items parse). New pub helperscorex_parse_bytes_exactreads exactly the claimed length, growing the buffer only as bytes arrive and erroring exactly likeread_exact(Io("failed to fill whole buffer")) on a short stream.ergo-nipopow: prefix and suffix-tail pre-allocations capped the same way; thePoPowHeaderheader and interlinks-proof buffers now go throughscorex_parse_bytes_exact.ergo-lib:ReducedTransaction's embedded-transaction buffer goes through the same helper; the helper'sIoerror is mapped back toSigmaParsingError::Io, so a short stream fails with exactly the errorread_exactproduced before (pinned by the new test).Deliberate non-changes
The rest of the workspace's allocation sites were audited and are not affected: u8/u16 count prefixes (context extension, box tokens, tuples, collection/sigma-boolean items,
ProofBytes, peer features, header fields), the transaction token-id count (bound-checked againstMAX_OUTPUTS_COUNT * MAX_TOKENS_COUNTbefore allocating — the codebase's own precedent), andBigInt256/UnsignedBigInt(length checked ≤ 32 first).BatchMerkleProofcollects its u32-length indices/proofs without pre-allocating by the claimed length, so a huge length already fails on the first read — verified empirically, left alone. ThePoPowHeaderinterlinks collection is the same safe pattern.Tests
scorex_parse_bytes_exact.cargo test: sigma-ser 56, ergo-nipopow 5, ergo-lib (--all-features) 122+1, ergo-merkle-tree and ergo-chain-types green, ergotree-ir + ergotree-interpreter green. Clippy-D warningsclean on the touched crates;cargo fmt --checkclean.Built by @Kshot9000 — donations (Ergo): 9fcM5RWnAjmP4vx5bnW6yohB6H9bLq8sJbaPLHtwZLtQPB32Pvy
Note:
cargo check -p ergo-nipopow --no-default-featuresfails insideergotree-iron pristinedevelopas well (verified with these changes stashed) — pre-existing and unrelated.