mirror of
https://github.com/facebook/rocksdb.git
synced 2024-11-29 00:34:03 +00:00
Summary: With fragmented record span across multiple blocks, if any following blocks corrupted with arbitary data, and intepreted log number less than the current log number, program will fall into infinite loop due to not skipping buffer leading bytes Pull Request resolved: https://github.com/facebook/rocksdb/pull/11979 Test Plan: existing unit tests Reviewed By: ajkr Differential Revision: D50604408 Pulled By: jowlyzhang fbshipit-source-id: e50a0c7e7c3d293fb9d5afec0a3eb4a1835b7a3b
This commit is contained in:
parent
dc87847e65
commit
f2c9075d16
|
@ -469,12 +469,14 @@ unsigned int Reader::ReadPhysicalRecord(Slice* result, size_t* drop_size,
|
||||||
const unsigned int type = header[6];
|
const unsigned int type = header[6];
|
||||||
const uint32_t length = a | (b << 8);
|
const uint32_t length = a | (b << 8);
|
||||||
int header_size = kHeaderSize;
|
int header_size = kHeaderSize;
|
||||||
if ((type >= kRecyclableFullType && type <= kRecyclableLastType) ||
|
const bool is_recyclable_type =
|
||||||
type == kRecyclableUserDefinedTimestampSizeType) {
|
((type >= kRecyclableFullType && type <= kRecyclableLastType) ||
|
||||||
|
type == kRecyclableUserDefinedTimestampSizeType);
|
||||||
|
if (is_recyclable_type) {
|
||||||
|
header_size = kRecyclableHeaderSize;
|
||||||
if (end_of_buffer_offset_ - buffer_.size() == 0) {
|
if (end_of_buffer_offset_ - buffer_.size() == 0) {
|
||||||
recycled_ = true;
|
recycled_ = true;
|
||||||
}
|
}
|
||||||
header_size = kRecyclableHeaderSize;
|
|
||||||
// We need enough for the larger header
|
// We need enough for the larger header
|
||||||
if (buffer_.size() < static_cast<size_t>(kRecyclableHeaderSize)) {
|
if (buffer_.size() < static_cast<size_t>(kRecyclableHeaderSize)) {
|
||||||
int r = kEof;
|
int r = kEof;
|
||||||
|
@ -483,11 +485,8 @@ unsigned int Reader::ReadPhysicalRecord(Slice* result, size_t* drop_size,
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const uint32_t log_num = DecodeFixed32(header + 7);
|
|
||||||
if (log_num != log_number_) {
|
|
||||||
return kOldRecord;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (header_size + length > buffer_.size()) {
|
if (header_size + length > buffer_.size()) {
|
||||||
assert(buffer_.size() >= static_cast<size_t>(header_size));
|
assert(buffer_.size() >= static_cast<size_t>(header_size));
|
||||||
*drop_size = buffer_.size();
|
*drop_size = buffer_.size();
|
||||||
|
@ -499,6 +498,14 @@ unsigned int Reader::ReadPhysicalRecord(Slice* result, size_t* drop_size,
|
||||||
return kBadRecordLen;
|
return kBadRecordLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_recyclable_type) {
|
||||||
|
const uint32_t log_num = DecodeFixed32(header + 7);
|
||||||
|
if (log_num != log_number_) {
|
||||||
|
buffer_.remove_prefix(header_size + length);
|
||||||
|
return kOldRecord;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (type == kZeroType && length == 0) {
|
if (type == kZeroType && length == 0) {
|
||||||
// Skip zero length record without reporting any drops since
|
// Skip zero length record without reporting any drops since
|
||||||
// such records are produced by the mmap based writing code in
|
// such records are produced by the mmap based writing code in
|
||||||
|
|
Loading…
Reference in a new issue