consensus: Add CompactSize range check to deserialization#5697
Conversation
Reject CompactSize values exceeding MAX_COMPACT_SIZE (0x02000000) during deserialization, matching Bitcoin Core's serialize.h limit. Extract read_compact_size logic into a private free function to allow tests to bypass the range check when validating non-minimal encoding. Add test for the new SizeTooLargeCompactSize error at the boundary. Update bip152 error test to expect failure at deserialization rather than at index computation, since the range check now triggers earlier.
3f3f5ec to
1dd1d92
Compare
|
Thanks man! Good work on the fuzzing. A couple of comments/questions for the project more than just for you.
|
More context: I found this while doing differential fuzzing in the PSBT parser. Bitcoin Core always checks if the |
|
Ha! Interesting timing then. I only recently raised this issue: #5622 which is around the key type and its usage of a CompactSize encoding. Note in the associated PR the code comment 'the protocol abuses ...' (which I suggested). Amusing that its not the only bug we have on this data field and I"m now not surprised we missed it. |
we previously had this was discussed here: #5057 (comment) |
|
Ouch so I removed it. Thanks @jrakibi! |
Yes, adding the rust-psbt is already on the plan. I'll check to see if it gets done this week and report any issues I find. |
|
Boss! |
|
I'm gonna go ahead and ACK/merge this. But
|
|
I created rust-bitcoin/rust-psbt#74 to track it over in |
No, We can do fuzzing in any commit/branch.
Yes, I've tested with rust-psbt and it has the same issue as rust-bitcoin. Since rust-psbt v0 uses the |
Manually backport rust-bitcoin#5697. On `master` the `VarInt` type is gone but the deserialization bug fixed by 5697 exists here none the less. Add the same range check to `Decodable for VarInt`.
|
Backported in #5921 |
Manually backport rust-bitcoin#5697. On `master` the `VarInt` type is gone but the deserialization bug fixed by 5697 exists here none the less. Add the same range check to `Decodable for VarInt`.
Manually backport rust-bitcoin#5697. On `master` the `VarInt` type is gone but the deserialization bug fixed by 5697 exists here none the less. Add the same range check to `Decodable for VarInt`.
Manually backport rust-bitcoin#5697. On `master` the `VarInt` type is gone but the deserialization bug fixed by 5697 exists here none the less. Add the same range check to `Decodable for VarInt`.
Manually backport rust-bitcoin#5697. On `master` the `VarInt` type is gone but the deserialization bug fixed by 5697 exists here none the less. Add the same range check to `Decodable for VarInt`.
11bb6a8 bitcoin: update CompactSize Kani proofs (Ismail Daif) Pull request description: There were 2 existing Kani proofs, checking a CompactSize serialization/deserialization roundtrip for all `u32` values and `u64` values greater than `0xffffffff`. These proofs no longer succeeded after #5697 implemented a range-check on CompactSize deserialization. This PR updates the proofs such that a roundtrip is tested for all values in the enforced range, and values outside that range are rejected with `ParseError::OversizedCompactSize`. Closes #5954 ACKs for top commit: tcharding: ACK 11bb6a8 apoelstra: ACK 11bb6a8; successfully ran local tests; nice! We will try to be more conscientious about the Kani tests in future.. Tree-SHA512: 94c0a702a79d7154a3e8452df2292ac1773515780d78e8c1f28f53c0620f6643c8a9c520b629c3dbefd59228380a7329deb04fd14b49319a538775443ece503e
Manually backport rust-bitcoin#5697. On `master` the `VarInt` type is gone but the deserialization bug fixed by 5697 exists here none the less. Add the same range check to `Decodable for VarInt`.
…rialization 4a71193 Remove doc_auto_cfg (Tobin C. Harding) 91a6e64 consensus: Add CompactSize range check to deserialization (Tobin C. Harding) 48ac68d Update nightly toolchain version (Tobin C. Harding) Pull request description: Manually backport #5697. On `master` the `VarInt` type is gone but the deserialization bug fixed by 5697 exists here none the less. Add the same range check to `Decodable for VarInt`. ACKs for top commit: apoelstra: ACK 4a71193; successfully ran local tests Tree-SHA512: c46ed1b90f0d44c994302b69f7051388308a40939631f4542459abd58908913adbcf0f406f0b04111ae7bb74ad2ad603fb769eab3e1470a1e4fece1667fef6c5
Manually revert 91a6e64 (`git revert` didn't work.) This was a backport of rust-bitcoin#5697 which added range checking to the `VarInt` type. On master we did this then realized there are legitimate use cases for the full range of a `u64`. We then added `u64` support to compact size (rust-bitcoin#5784). Note that we cannot break the API so the new stuff introduced in `0.32.9` has to stay in there. Comment the code as such. NB: 'compact size' is the new name for varint. This backport then broke downstream users.
Manually revert 91a6e64 Note that we cannot break the API so the new stuff introduced in `0.32.9` has to stay in there. Comment the code as such. This was a backport of rust-bitcoin#5697 which added range checking to the `VarInt` type. On master we did this then realized there are legitimate use cases for the full range of a `u64`. We then added `u64` support to compact size (rust-bitcoin#5784). NB: 'compact size' is the new name for varint. This backport then broke downstream users.
Manually revert 91a6e64 Note that we cannot break the API so the new stuff introduced in `0.32.9` has to stay in there. Comment the code as such. This was a backport of rust-bitcoin#5697 which added range checking to the `VarInt` type. On master we did this then realized there are legitimate use cases for the full range of a `u64`. We then added `u64` support to compact size (rust-bitcoin#5784). NB: 'compact size' is the new name for varint. This backport then broke downstream users.
Manually revert 91a6e64 Note that we cannot break the API so the new stuff introduced in `0.32.9` has to stay in there. Comment the code as such. This was a backport of rust-bitcoin#5697 which added range checking to the `VarInt` type. On master we did this then realized there are legitimate use cases for the full range of a `u64`. We then added `u64` support to compact size (rust-bitcoin#5784). NB: 'compact size' is the new name for varint. This backport then broke downstream users.
Manually revert 91a6e64 Note that we cannot break the API so the new stuff introduced in `0.32.9` has to stay in there. Comment the code as such. This was a backport of #5697 which added range checking to the `VarInt` type. On master we did this then realized there are legitimate use cases for the full range of a `u64`. We then added `u64` support to compact size (#5784). NB: 'compact size' is the new name for varint. This backport then broke downstream users.
3bcd7c9 Manually revert VarInt range check (Tobin C. Harding) Pull request description: Manually revert 91a6e64 Note that we cannot break the API so the new stuff introduced in `0.32.9` has to stay in there. Comment the code as such. This was a backport of #5697 which added range checking to the `VarInt` type. On master we did this then realized there are legitimate use cases for the full range of a `u64`. We then added `u64` support to compact size (#5784). NB: 'compact size' is the new name for varint. This backport then broke downstream users. Close: #6138 ACKs for top commit: apoelstra: ACK 3bcd7c9; successfully ran local tests Tree-SHA512: d01078f4f8fae59c439fd404a643abfb353bcec1757ebfbcabde487ff8620d927387f91d0e749a7bbd36163f2386290d301f17c0cff9e628e37585329daf116b
Reject
CompactSizevalues exceedingMAX_COMPACT_SIZE(0x02000000) during deserialization, matching Bitcoin Core's serialize.h limit.Extract read_compact_size logic into a private free function to allow tests to bypass the range check when validating non-minimal encoding.
Add test for the new
OversizedCompactSizeerror at the boundary.Update bip152 error test to expect failure at deserialization rather than at index computation, since the range check now triggers earlier.
Found by differential fuzzing using bitcoinfuzz.