YAML Metadata Warning:empty or missing yaml metadata in repo card

Check out the documentation for more information.

PoC: hnswlib loadIndex β€” cur_element_count > max_elements β†’ heap OOB WRITE (CWE-787), master unpatched

Target

hnswlib (~4.5k stars) β€” header-only HNSW approximate-nearest-neighbor library embedded in vector databases and retrieval stacks (ChromaDB, Milvus ecosystem, countless RAG pipelines). Saved index files are loaded via HierarchicalNSW::loadIndex() / the index-loading constructor.

Vulnerability

loadIndex (master hnswalg.h, verified 2026-07-18) reads both max_elements and cur_element_count from the file, then:

// integrity walk: only checks total file-size consistency β€” NEVER compares
// cur_element_count against max_elements
data_level0_memory_ = (char *) malloc(max_elements * size_data_per_element_);   // :776
input.read(data_level0_memory_, cur_element_count * size_data_per_element_);    // :779

A crafted index with max_elements=4, cur_element_count=50 allocates 96 bytes and then reads 1200 bytes into it β€” a heap-buffer-overflow WRITE of 1104 attacker-controlled file bytes. The "index seems to be corrupted" integrity check added to master does not catch it: it only verifies that the file's total size matches cur_element_count, which the attacker satisfies by simply including the data.

Immediately after the overflow, loadIndex allocates linkLists_ (an array of heap pointers) and proceeds to read per-element link lists β€” overflowing into this region corrupts pointers that are later dereferenced during search/insertion, i.e. the primitive is sufficient for controlled-pointer corruption β†’ potential control-flow hijack, not just a crash.

Proof of concept (this repo)

  • gen_malicious_index.py β€” writes malicious.hnsw (1496 B), crafted to pass the master integrity walk
  • poc_driver.cpp β€” loads it with the real library: new hnswlib::HierarchicalNSW<float>(&space, "malicious.hnsw")
  • asan_trace.txt β€” captured output
python3 gen_malicious_index.py malicious.hnsw
g++ -fsanitize=address -g -O0 -std=c++17 -I. poc_driver.cpp -o poc_driver -pthread
./poc_driver malicious.hnsw

Result (master headers fetched 2026-07-18):

==3940013==ERROR: AddressSanitizer: heap-buffer-overflow
WRITE of size 1199
    #4 hnswlib::HierarchicalNSW<float>::loadIndex(...)  hnswalg.h:779
    #5 hnswlib::HierarchicalNSW<float>::HierarchicalNSW(...)  hnswalg.h:85

0 bytes after a 96-byte region. Fully deterministic.

Impact

Any service loading user-supplied HNSW index files (vector-DB snapshot import, model/index sharing, RAG deployment pipelines) is exposed to attacker-controlled heap corruption at load time. Same "file-supplied count trusted without cross-validation" class as the model-parser vulnerabilities tracked as CVE-2026-27940 / CVE-2026-7482 ("Bleeding Llama", CVSS 9.1) β€” here in the vector-index layer that AI infrastructure actually ships.

Suggested fix

In loadIndex, after reading the header: if (cur_element_count > max_elements) throw std::runtime_error("cur_element_count exceeds max_elements"); β€” before both the integrity walk and the allocation.

Note on distinctness

Distinct from GHSA-xwc8-rf6m-xr86 (double free via init_index with large M β€” different function, different root cause) and from the neighbor-id search-time OOB (searchBaseLayerST, separate issue). This is a load-time allocation/read size mismatch in loadIndex itself, unpatched on master as of 2026-07-18.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support