Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NCC-E005955-M2F] zebra-chain: Check that header block version field is valid when serializing blocks #497

Closed
1 of 2 tasks
Tracked by #6277
teor2345 opened this issue Jun 17, 2020 · 8 comments · Fixed by #6475
Closed
1 of 2 tasks
Tracked by #6277
Assignees
Labels
A-consensus Area: Consensus rule updates C-audit Category: Issues arising from audit findings C-bug Category: This is a bug C-security Category: Security issues I-invalid-data Zebra relies on invalid or untrusted data, or sends invalid data

Comments

@teor2345
Copy link
Contributor

teor2345 commented Jun 17, 2020

Impact

Zebra assumes all serialization/deserialization functions cannot produce invalid data. Unenforced constraints violate this assumption and may affect consensus or interoperability.

Description

Zebra implements the ZCashSerialize trait for consensus-critical data.

pub trait ZcashSerialize: Sized {
/// Write `self` to the given `writer` using the canonical format.
///
/// This function has a `zcash_` prefix to alert the reader that the
/// serialization in use is consensus-critical serialization, rather than
/// some other kind of serialization.
///
/// Notice that the error type is [`std::io::Error`]; this indicates that
/// serialization MUST be infallible up to errors in the underlying writer.
/// In other words, any type implementing `ZcashSerialize` must make illegal
/// states unrepresentable.
fn zcash_serialize<W: io::Write>(&self, writer: W) -> Result<(), io::Error>;

Note the highlighted requirement that illegal states must be unrepresentable.

The function zcash_deserialize() for Header contains historical information regarding the version field of the header. In particular, it specifies that the only valid version number is 4, but that incorrect implementations in the past resulted in several blocks with an incorrect value. The function has some special case handling for this, as well as an explicit check that the parsed version is greater than or equal to 4:

// # Consensus
//
// > The block version number MUST be greater than or equal to 4.
//
// https://zips.z.cash/protocol/protocol.pdf#blockheader
if version < 4 {
return Err(SerializationError::Parse("version must be at least 4"));
}

This is similarly captured in other annotations for the version field, where it is specified that:

The only constraint is that it must be at least 4 when interpreted as an i32 .

In comparison, the corresponding zcash_deserialize() function does not perform validation on the version field:

fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
writer.write_u32::<LittleEndian>(self.version)?;
self.previous_block_hash.zcash_serialize(&mut writer)?;
writer.write_all(&self.merkle_root.0[..])?;
writer.write_all(&self.commitment_bytes[..])?;
writer.write_u32::<LittleEndian>(
self.time
.timestamp()
.try_into()
.expect("deserialized and generated timestamps are u32 values"),
)?;
writer.write_u32::<LittleEndian>(self.difficulty_threshold.0)?;
writer.write_all(&self.nonce[..])?;
self.solution.zcash_serialize(&mut writer)?;
Ok(())
}

No instances within the codebase will currently set this value incorrectly, but it appears to be a violation of the specified constraint. It is possible to construct a Header such that the output of zcash_serialize will not correctly deserialize within Zebra.

Recommendation

Align the constraint checks for the version field such that any serialized Header will correctly deserialize without an error.

Location

zebra-chain/src/block/serialize.rs

Original issue description

Once Zebra starts generating its own blocks, we'll need to do the version check in a few more places:

  • make sure serialized blocks contain a version that's 4 or greater, based on the consensus rules
  • impose a stricter version check on generated blocks, to ensure the version is always 4

This task is open to contributors, but some parts of it depend on future Zebra features.

@teor2345 teor2345 added Poll::Pending A-consensus Area: Consensus rule updates good first issue E-help-wanted Call for participation: Help is requested to fix this issue. labels Jun 17, 2020
@dconnolly dconnolly modified the milestone: Wallet Support 💰 Jun 18, 2020
@yaahc
Copy link
Contributor

yaahc commented Jun 25, 2020

Removing open-to-contributors on this one based on henry's comment pending further discussion in today's gardening session

@yaahc yaahc removed good first issue E-help-wanted Call for participation: Help is requested to fix this issue. labels Jun 25, 2020
@oxarbitrage
Copy link
Contributor

Comment from Henry says "not sure about that one" but nothing more. I think we should detail further.

@yaahc
Copy link
Contributor

yaahc commented Jul 9, 2020

I think the issue is that this depends on generating blocks which is something we don't have implemented yet, but I'm not sure, @hdevalence?

@oxarbitrage
Copy link
Contributor

I am asking because if that is the case i think we could still check the version in the receiving side just as we did with header_solution and coinbase.

@teor2345
Copy link
Contributor Author

teor2345 commented Aug 3, 2020

The BlockVerifier checks the version on blocks as of PR #748.

@teor2345 teor2345 closed this as completed Aug 3, 2020
@teor2345
Copy link
Contributor Author

teor2345 commented Aug 3, 2020

Oops, that's not correct, I misread the code.

Note: generated blocks aren't part of the "sync and validate" milestone. They only happen if we implement mining.

@teor2345 teor2345 reopened this Aug 3, 2020
@dconnolly dconnolly added this to the Wallet Support 💰 milestone Aug 3, 2020
@hdevalence hdevalence added S-blocked Status: Blocked on other tasks and removed Poll::Pending labels Aug 17, 2020
@mpguerra mpguerra removed this from the Wallet Support 💰 milestone Jan 5, 2021
@teor2345 teor2345 removed the S-blocked Status: Blocked on other tasks label Jan 5, 2021
@mpguerra mpguerra added E-help-wanted Call for participation: Help is requested to fix this issue. and removed E-easy labels Mar 16, 2021
@teor2345
Copy link
Contributor Author

We don't plan on generating blocks any time soon.

@teor2345
Copy link
Contributor Author

This came up in the audit: there is a missing check in the block header version serialize function.

@teor2345 teor2345 reopened this Mar 22, 2023
@teor2345 teor2345 added C-bug Category: This is a bug P-Medium ⚡ C-security Category: Security issues I-invalid-data Zebra relies on invalid or untrusted data, or sends invalid data C-audit Category: Issues arising from audit findings and removed E-help-wanted Call for participation: Help is requested to fix this issue. P-Optional ✨ labels Mar 22, 2023
@teor2345 teor2345 changed the title Check that version is valid in generated blocks Check that header block version field is valid when serializing blocks Mar 22, 2023
@teor2345 teor2345 changed the title Check that header block version field is valid when serializing blocks NCC-E005955-M2F: Check that header block version field is valid when serializing blocks Mar 22, 2023
@mpguerra mpguerra changed the title NCC-E005955-M2F: Check that header block version field is valid when serializing blocks [NCC-E005955-M2F] zebra-chain: Check that header block version field is valid when serializing blocks Mar 23, 2023
@arya2 arya2 self-assigned this Mar 28, 2023
@mergify mergify bot closed this as completed in #6475 Apr 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-consensus Area: Consensus rule updates C-audit Category: Issues arising from audit findings C-bug Category: This is a bug C-security Category: Security issues I-invalid-data Zebra relies on invalid or untrusted data, or sends invalid data
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants