mirror of
https://github.com/facebookresearch/faiss.git
synced 2026-10-12 02:13:36 +00:00
Validate IndexBinaryHash b <= code_size*8 during deserialization (#5011)
Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5011 Add a deserialization-time check in `read_index_binary` that rejects `IndexBinaryHash` data where `b` exceeds `code_size * 8`. Without this validation, a malformed index can cause `BitstringReader::read()` to access past the allocated code buffer during search, resulting in a heap-buffer-overflow. Reviewed By: mnorris11 Differential Revision: D98811392 fbshipit-source-id: 6847bce77be6edb66d87bd28a770c2af615868d3
This commit is contained in:
committed by
meta-codesync[bot]
parent
87bc9b0872
commit
668da4a386
@@ -2624,6 +2624,11 @@ std::unique_ptr<IndexBinary> read_index_binary_up(IOReader* f, int io_flags) {
|
||||
idxh->b > 0,
|
||||
"invalid IndexBinaryHash b=%d (must be > 0)",
|
||||
idxh->b);
|
||||
FAISS_THROW_IF_NOT_FMT(
|
||||
static_cast<size_t>(idxh->b) <= idxh->code_size * 8,
|
||||
"IndexBinaryHash b=%d exceeds code_size=%d bits",
|
||||
idxh->b,
|
||||
idxh->code_size);
|
||||
READ1(idxh->nflip);
|
||||
read_binary_hash_invlists(idxh->invlists, idxh->b, idxh->code_size, f);
|
||||
idx = std::move(idxh);
|
||||
|
||||
@@ -704,6 +704,21 @@ TEST(ReadIndexDeserialize, BinaryHashIlNbitZeroWithEntries) {
|
||||
expect_binary_read_throws_with(buf, "il_nbit=");
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Test: IndexBinaryHash with b exceeding code_size*8 triggers validation.
|
||||
// Without this check, BitstringReader::read() would access past the
|
||||
// allocated code buffer, causing a heap-buffer-overflow.
|
||||
// -----------------------------------------------------------------------
|
||||
TEST(ReadIndexDeserialize, BinaryHashBExceedsCodeSize) {
|
||||
std::vector<uint8_t> buf;
|
||||
push_fourcc(buf, "IBHh");
|
||||
push_binary_index_header(buf, /*d=*/16, /*ntotal=*/0);
|
||||
// d=16 → code_size=2 → 16 bits available
|
||||
push_val<int>(buf, 17); // b = 17 (exceeds 16 bits)
|
||||
|
||||
expect_binary_read_throws_with(buf, "IndexBinaryHash b=");
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Test: read_binary_multi_hash_map with crafted ilsz values that sum to
|
||||
// more than ntotal. Without the check, the inner loop would read past
|
||||
|
||||
Reference in New Issue
Block a user