【BUG】In the SeekForGetImpl function of the block.cc file, the check for whether data_ is null is omitted. The function directly uses data_ for hash lookup and subsequent parsing, which poses a potential risk of null pointer for RocksDB-v6.26.1.
Author: wkxNiubiCreated Sep 14, 2026Updated Sep 14, 2026
Problem Description
This issue is caused by inconsistent state of DataBlockIter, resulting in a potential null pointer dereference. When the iterator has not been initialized or has been invalidated by calling Invalidate(), the member variable data_ may be nullptr. However, SeekForGet() only checks whether data_block_hash_index_ is empty, but does not check data_. If the hash index pointer is still non-null or has a residual value, it will enter SeekForGetImpl(). The function then directly executes: data_block_hash_index_->Lookup(data_, map_offset, target_user_key); Lookup() performs address operations on data_ and reads the hash bucket. When data_ is nullptr, this is undefined behavior and may cause the RocksDB process to crash.
How to reproduce
- Use kDataBlockBinaryAndHash to create a data block containing at least one record.
- Initialize DataBlockIter using Block::NewDataIterator() and ensure that data_block_hash_index_ is not empty.
- Call: iter.Invalidate(Status::OK()); At this point, data_ is set to nullptr, but data_block_hash_index_ has not been cleared.
- Construct a valid InternalKey, and then call: iter.SeekForGet(internal_key.Encode()); SeekForGet() will enter SeekForGetImpl() due to the remaining hash index pointers, and finally perform the hash bucket read using an empty data_.
Content of the code evidence
bool DataBlockIter::SeekForGetImpl(const Slice& target) {
Slice target_user_key = ExtractUserKey(target);
uint32_t map_offset = restarts_ + num_restarts_ * sizeof(uint32_t);
uint8_t entry =
data_block_hash_index_->Lookup(data_, map_offset, target_user_key);
if (entry == kCollision) {
// HashSeek not effective, falling back
SeekImpl(target);
return true;
}Source: facebook/rocksdb