mirror of
https://github.com/facebook/rocksdb.git
synced 2026-10-23 08:09:02 +03:00
Summary: Pull Request resolved: https://github.com/facebook/rocksdb/pull/14993 A corrupted RocksDB SST data block whose footer sets the hash-index bit (`kDataBlockBinaryAndHash`) could drive an out-of-bounds heap read while the block is being parsed. `DataBlockHashIndex::Initialize` guarded its `num_buckets` / `map_offset` arithmetic only with `assert()`, which is compiled out in release and ASAN builds. When the encoded `num_buckets` exceeds the block, the `uint16_t` `map_offset` computation underflows; that value then flows into `Block`'s ctor at `input.remove_suffix(input.size() - map_offset)`, inflating `restart_offset_` far past the real allocation. If `size` is later zeroed as an error marker (e.g. a corrupted separated-KV footer), `Block::GetCorruptionStatus` builds a `Slice(data(), restart_offset_)` and `DataBlockFooter::DecodeFrom` reads `data() + restart_offset_ - 4`, over-reading the block's heap buffer (reported by agentic fuzzing, T279933950). Fix: - `DataBlockHashIndex::Initialize` now returns `bool` and rejects a `num_buckets` of 0 or one whose bucket array plus the `NUM_BUCKETS` field does not fit within `size`, instead of relying on debug-only asserts. - `Block`'s ctor checks that return value and also rejects blocks too large for the 64KiB `uint16_t`-offset hash-index format, marking the block corrupt (`size = 0`) rather than under-flowing `map_offset` and over-reading. Reviewed By: pdillinger Differential Revision: D113429299 fbshipit-source-id: 3167106e793252c09fd6a558e3ac96de7a2169c0