Skip to content

Commit d433363

Browse files
Michael Norrismeta-codesync[bot]
authored andcommitted
Validate SVS-Vamana stored_vectors size on deserialization (ISV2) (#5434)
Summary: Pull Request resolved: #5434 The `ISV2` (IndexSVSVamana) deserialization branch reads `ntotal`, `d` (header), and the raw `stored_vectors` payload as independent fields and never re-establishes the invariant `stored_vectors.size() == ntotal * d` that the programmatic `add()` path maintains. `IndexSVSVamana::reconstruct` guards only `key < ntotal` and `stored_vectors` non-empty, then `memcpy`s `sizeof(float) * d` bytes from `stored_vectors.data() + key * d`. A crafted index declaring e.g. `ntotal=1, d=256` with a 1-element payload reads ~1 KiB past the heap allocation (heap-buffer-overflow read). Adds the `stored_vectors.size() == ntotal * d` check at deserialization, matching the sibling flat-codes readers, converting the OOB read into a clean FaissException. The SVS family is compile-gated (FAISS_ENABLE_SVS, x86_64). Found by agentic fuzzing. Reviewed By: trang-nm-nguyen Differential Revision: D112368334 fbshipit-source-id: ba4ba275dd0444216139921c8d15628ccbb29fc0
1 parent dfd2a25 commit d433363

1 file changed

Lines changed: 7 additions & 0 deletions

File tree

faiss/impl/index_read.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2851,6 +2851,13 @@ std::unique_ptr<Index> read_index_up(IOReader* f, int io_flags) {
28512851
}
28522852
if (h == fourcc("ISV2")) {
28532853
READVECTOR(svs->stored_vectors);
2854+
FAISS_THROW_IF_NOT_MSG(
2855+
svs->stored_vectors.size() ==
2856+
mul_no_overflow(
2857+
(size_t)svs->ntotal,
2858+
(size_t)svs->d,
2859+
"IndexSVSVamana stored_vectors"),
2860+
"ISV2: stored_vectors size inconsistent with ntotal * d");
28542861
} else {
28552862
svs->stored_vectors_valid = false;
28562863
}

0 commit comments

Comments
 (0)