Security: Replace queued checkpoint blocks with duplicate hashes (#2697)
We don't check the authorizing data hash until checkpoint blocks reach the state. So signatures, proofs, or scripts could be different, even if the block hash is the same. Co-authored-by: Conrado Gouvea <conrado@zfnd.org>
This commit is contained in:
parent
8bff71e857
commit
34c7a27c2a
|
@ -539,13 +539,23 @@ where
|
|||
.entry(height)
|
||||
.or_insert_with(|| QueuedBlockList::with_capacity(1));
|
||||
|
||||
// Replace older requests by newer ones by swapping the oneshot.
|
||||
// Replace older requests with newer ones.
|
||||
// The newer block is ok, the older block is an error.
|
||||
for qb in qblocks.iter_mut() {
|
||||
if qb.block.hash == hash {
|
||||
let e = VerifyCheckpointError::NewerRequest { height, hash };
|
||||
tracing::trace!(?e, "failing older of duplicate requests");
|
||||
let old_tx = std::mem::replace(&mut qb.tx, new_qblock.tx);
|
||||
let _ = old_tx.send(Err(e));
|
||||
|
||||
// ## Security
|
||||
//
|
||||
// Replace the entire queued block.
|
||||
//
|
||||
// We don't check the authorizing data hash until checkpoint blocks reach the state.
|
||||
// So signatures, proofs, or scripts could be different,
|
||||
// even if the block hash is the same.
|
||||
|
||||
let old = std::mem::replace(qb, new_qblock);
|
||||
let _ = old.tx.send(Err(e));
|
||||
return Ok(req_block);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue