-
Notifications
You must be signed in to change notification settings - Fork 82
Validate LSMT and ZFile index sizes #438
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
0b01f46
b8d8b30
3b0d2e3
d463459
ccbfd48
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1367,18 +1367,16 @@ static SegmentMapping *do_load_index(IFile *file, HeaderTrailer *pheader_trailer | |
| LOG_ERRNO_RETURN(0, nullptr, "failed to stat file."); | ||
| assert(trailer || pht->is_sparse_rw() == false); | ||
| uint64_t index_bytes; | ||
| uint64_t trailer_offset = 0; | ||
| if (trailer) { | ||
| if (!pht->is_data_file()) | ||
| LOG_ERROR_RETURN(0, nullptr, "uncognized file type"); | ||
| pht = verify_ht(file, buf, true, stat.st_size); | ||
| if (pht == nullptr) { | ||
| return nullptr; | ||
| } | ||
| auto trailer_offset = stat.st_size - HeaderTrailer::SPACE; | ||
| trailer_offset = stat.st_size - HeaderTrailer::SPACE; | ||
| LOG_DEBUG("index_size: `, trailer offset: `", pht->index_size + 0, trailer_offset); | ||
| index_bytes = pht->index_size * sizeof(SegmentMapping); | ||
| if (index_bytes > trailer_offset - pht->index_offset) | ||
| LOG_ERROR_RETURN(0, nullptr, "invalid index bytes or size"); | ||
|
|
||
| } else { | ||
| if (!pht->is_index_file() || pht->is_sealed()) | ||
|
|
@@ -1389,6 +1387,16 @@ static SegmentMapping *do_load_index(IFile *file, HeaderTrailer *pheader_trailer | |
| pht->index_size = index_bytes / sizeof(SegmentMapping); | ||
| } | ||
|
|
||
| if (pht->index_size > MAX_LSMT_INDEX_SIZE) | ||
| LOG_ERROR_RETURN(0, nullptr, "LSMT index size ` exceeds maximum `", | ||
| pht->index_size + 0, MAX_LSMT_INDEX_SIZE); | ||
|
|
||
| if (trailer) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. without moving |
||
| index_bytes = pht->index_size * sizeof(SegmentMapping); | ||
| if (index_bytes > trailer_offset - pht->index_offset) | ||
| LOG_ERROR_RETURN(0, nullptr, "invalid index bytes or size"); | ||
| } | ||
|
|
||
| SegmentMapping *ibuf = nullptr; | ||
| posix_memalign((void **)&ibuf, ALIGNMENT4K, pht->index_size * sizeof(*ibuf)); | ||
| ret = file->pread(ibuf, index_bytes, pht->index_offset); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -954,6 +954,11 @@ IMemoryIndex *merge_memory_indexes(const IMemoryIndex **pindexes, size_t n) { | |
| mapping.reserve(pi[0]->size()); | ||
| merge_indexes(0, mapping, pi, n, 0, UINT64_MAX); | ||
|
|
||
| if (mapping.size() > MAX_LSMT_INDEX_SIZE) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do it inside merge_indexes(), just before mapping.resize() or push_back(). |
||
| LOG_ERROR_RETURN(0, nullptr, | ||
| "Merged LSMT index size ` exceeds maximum `", | ||
| mapping.size(), MAX_LSMT_INDEX_SIZE); | ||
|
Comment on lines
+957
to
+960
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 不超过“sum of input sizes”的话,这个标准过于严格了 |
||
|
|
||
| if (pindexes[0]->vsize() < static_cast<uint64_t>(UINT32_MAX) * ALIGNMENT | ||
| && mapping.size() < NODES_PER_LEVEL_32[MAX_LEVEL_32-1]) { | ||
| return new_index_with_lineriazed_bptree<uint32_t>(std::move(mapping), pindexes[0]->vsize()); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -47,6 +47,7 @@ uint64_t zfile_blk_cnt = 0; | |
| namespace ZFile { | ||
|
|
||
| const static size_t BUF_SIZE = 512; | ||
| const static uint64_t MAX_ZFILE_INDEX_SIZE = 1000000000; | ||
| const static uint32_t NOI_WELL_KNOWN_PRIME = 100007; | ||
| const static uint8_t FLAG_VALID_FALSE = 0; | ||
| const static uint8_t FLAG_VALID_TRUE = 1; | ||
|
|
@@ -1074,7 +1075,10 @@ bool load_jump_table(IFile *file, CompressionFile::HeaderTrailer *pheader_traile | |
| LOG_ERRNO_RETURN(0, false, "failed to stat file."); | ||
| } | ||
| uint64_t index_bytes = 0; | ||
| if (!pht->is_header_overwrite()) { | ||
| uint64_t trailer_offset = 0; | ||
| bool header_overwrite = pht->is_header_overwrite(); | ||
|
|
||
| if (!header_overwrite) { | ||
| struct stat stat; | ||
| ret = file->fstat(&stat); | ||
| if (ret < 0) { | ||
|
|
@@ -1084,7 +1088,7 @@ bool load_jump_table(IFile *file, CompressionFile::HeaderTrailer *pheader_traile | |
| LOG_ERROR_RETURN(0, false, "uncognized file type"); | ||
| } | ||
|
|
||
| auto trailer_offset = stat.st_size - CompressionFile::HeaderTrailer::SPACE; | ||
| trailer_offset = stat.st_size - CompressionFile::HeaderTrailer::SPACE; | ||
| ret = file->pread(buf, CompressionFile::HeaderTrailer::SPACE, trailer_offset); | ||
| if (ret < (ssize_t)CompressionFile::HeaderTrailer::SPACE) | ||
| LOG_ERRNO_RETURN(0, false, "failed to read file trailer."); | ||
|
|
@@ -1094,19 +1098,26 @@ bool load_jump_table(IFile *file, CompressionFile::HeaderTrailer *pheader_traile | |
| LOG_ERROR_RETURN(0, false, | ||
| "trailer magic, trailer type, file type or sealedness doesn't match"); | ||
| } | ||
| } | ||
|
|
||
| if (pht->index_size > MAX_ZFILE_INDEX_SIZE) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. put it just after |
||
| LOG_ERROR_RETURN(0, false, "ZFile index size ` exceeds maximum `", | ||
| pht->index_size + 0, MAX_ZFILE_INDEX_SIZE); | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do not delete this blank line |
||
| index_bytes = pht->index_size * sizeof(uint32_t); | ||
| index_bytes = pht->index_size * sizeof(uint32_t); | ||
|
|
||
| if (!header_overwrite) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do not change it |
||
| LOG_INFO("trailer_offset: `, idx_offset: `, idx_bytes: `, dict_size: `, use_dict: `", | ||
| trailer_offset, pht->index_offset, index_bytes, pht->opt.dict_size, | ||
| pht->opt.use_dict); | ||
|
|
||
| if (index_bytes > trailer_offset - pht->index_offset) | ||
| LOG_ERROR_RETURN(0, false, "invalid index bytes or size. "); | ||
| } else { | ||
| index_bytes = pht->index_size * sizeof(uint32_t); | ||
| LOG_INFO("read overwrite header. idx_offset: `, idx_bytes: `, dict_size: `, use_dict: `", | ||
| pht->index_offset, index_bytes, pht->opt.dict_size, pht->opt.use_dict); | ||
| } | ||
|
|
||
| auto ibuf = std::unique_ptr<uint32_t[]>(new uint32_t[pht->index_size]); | ||
| LOG_DEBUG("index_offset: `", pht->index_offset); | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
put it inside verify_ht()