Validate validity/rowids blob sizes in rescore KNN path

The rescore KNN loop read validity and rowids blobs from the chunks
iterator without checking their sizes matched chunk_size expectations.
A truncated or corrupt blob could cause OOB reads in bitmap_copy or
rowid array access. The flat KNN path already had these checks.

Adds corruption tests: truncated rowids blob and truncated validity
blob both produce errors instead of crashes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alex Garcia 2026-03-31 17:49:40 -07:00
parent f2c9fb8f08
commit 5522e86cd2
2 changed files with 36 additions and 5 deletions

View file

@ -426,10 +426,18 @@ static int rescore_knn(vec0_vtab *p, vec0_cursor *pCur,
unsigned char *chunkValidity =
(unsigned char *)sqlite3_column_blob(stmtChunks, 1);
i64 *chunkRowids = (i64 *)sqlite3_column_blob(stmtChunks, 2);
int validityBytes = sqlite3_column_bytes(stmtChunks, 1);
int rowidsBytes = sqlite3_column_bytes(stmtChunks, 2);
if (!chunkValidity || !chunkRowids) {
rc = SQLITE_ERROR;
goto cleanup;
}
// Validate blob sizes match chunk_size expectations
if (validityBytes < (p->chunk_size + 7) / 8 ||
rowidsBytes < p->chunk_size * (int)sizeof(i64)) {
rc = SQLITE_ERROR;
goto cleanup;
}
memset(chunk_distances, 0, p->chunk_size * sizeof(f32));
memset(chunk_topk_idxs, 0, k_oversample * sizeof(i32));