mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-12 01:41:36 +00:00
core/state,triedb/pathdb: add defensive length checks in encodeBinary and encodeStemBlob
Addresses review findings I13 and S6. encodeBinary: reject non-nil bintrie leaves with length != 32 at the trust boundary between the hasher and the state update. Previously a wrong-length leaf silently made it into the diff layer's accountData and only surfaced as a panic deep in the Flush path (stemBuilder.set). encodeStemBlob: add an upper-bound check on the value count (must be <= 256, the maximum offsets per stem). Previously a buggy producer could pass an arbitrarily long values slice.
This commit is contained in:
parent
69c0028094
commit
9fc733c2e2
2 changed files with 12 additions and 1 deletions
|
|
@ -301,10 +301,18 @@ func (sc *stateUpdate) encodeBinary() (map[common.Hash][]byte, map[common.Addres
|
||||||
accounts[fullKey] = nil
|
accounts[fullKey] = nil
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
// Defensive length check: every non-nil bintrie leaf must be
|
||||||
|
// exactly 32 bytes. A wrong-length leaf from the hasher would
|
||||||
|
// silently produce garbage in the diff layer; catch it here at
|
||||||
|
// the trust boundary rather than deep in the flush path where
|
||||||
|
// the stemBuilder.set panic would fire with less context.
|
||||||
|
if len(w.Value) != 32 {
|
||||||
|
return nil, nil, nil, nil, fmt.Errorf("bintrie leaf at stem %x offset %d has value len %d, want 32", w.Stem, w.Offset, len(w.Value))
|
||||||
|
}
|
||||||
// Take an owning copy: the hasher reuses its underlying buffers
|
// Take an owning copy: the hasher reuses its underlying buffers
|
||||||
// across blocks, so retaining its slices would create cross-block
|
// across blocks, so retaining its slices would create cross-block
|
||||||
// aliasing bugs in the pathdb diff layer.
|
// aliasing bugs in the pathdb diff layer.
|
||||||
v := make([]byte, len(w.Value))
|
v := make([]byte, 32)
|
||||||
copy(v, w.Value)
|
copy(v, w.Value)
|
||||||
accounts[fullKey] = v
|
accounts[fullKey] = v
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,9 @@ func encodeStemBlob(bitmap [stemBlobBitmapSize]byte, values [][]byte) ([]byte, e
|
||||||
if count != len(values) {
|
if count != len(values) {
|
||||||
return nil, fmt.Errorf("stem blob popcount=%d values=%d: %w", count, len(values), errStemBlobMalformed)
|
return nil, fmt.Errorf("stem blob popcount=%d values=%d: %w", count, len(values), errStemBlobMalformed)
|
||||||
}
|
}
|
||||||
|
if count > stemBlobBitmapBits {
|
||||||
|
return nil, fmt.Errorf("stem blob value count %d exceeds max %d: %w", count, stemBlobBitmapBits, errStemBlobMalformed)
|
||||||
|
}
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue