Skip to content
GoogleGHSA-v2c8-vqqp-hv3g

SQLite - Integer Overflow in FTS5 Extension

MediumCVE-2025-7709 · Published Aug 15, 2025

### Summary An integer overflow exists in the [FTS5](https://sqlite.org/fts5.html) extension. It occurs when the size of an array of tombstone pointers is calculated and truncated into a 32-bit integer. A pointer to partially controlled data can then be written out of bounds. ### Severity Moderate - The overflow can be triggered by either an attacker who is able to execute arbitrary queries or an attacker that can make an application process a controlled SQLite DB file. ### Proof of Concept ```JavaScript echo "SELECT * FROM articles WHERE articles MATCH 'whatever'" | ./sqlite3 /tmp/poc.sql ================================================================= ==3811642==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x5030000012f0 at pc 0x55eafca6599b bp 0x7ffdd1591570 sp 0x7ffdd1591568 READ of size 8 at 0x5030000012f0 thread T0 ``` ### Further Analysis The vulnerability occurs in fts5SegIterAllocTombstone() when nByte is calculated as the total size for an array of pointers: https://github.com/sqlite/sqlite/blob/d2b9cc099d66fe220eb1c4883f865ec94cb37f52/ext/fts5/fts5_index.c#L1952-L1964 ```JavaScript static void fts5SegIterAllocTombstone(Fts5Index *p, Fts5SegIter *pIter)...

GitHub advisory

Affected versions

PackageAffectedFixed in
security-research
Product
< 3.50.33.50.3
Details and references

### Summary An integer overflow exists in the [FTS5](https://sqlite.org/fts5.html) extension. It occurs when the size of an array of tombstone pointers is calculated and truncated into a 32-bit integer. A pointer to partially controlled data can then be written out of bounds. ### Severity Moderate - The overflow can be triggered by either an attacker who is able to execute arbitrary queries or an attacker that can make an application process a controlled SQLite DB file. ### Proof of Concept ```JavaScript echo "SELECT * FROM articles WHERE articles MATCH 'whatever'" | ./sqlite3 /tmp/poc.sql ================================================================= ==3811642==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x5030000012f0 at pc 0x55eafca6599b bp 0x7ffdd1591570 sp 0x7ffdd1591568 READ of size 8 at 0x5030000012f0 thread T0 ``` ### Further Analysis The vulnerability occurs in fts5SegIterAllocTombstone() when nByte is calculated as the total size for an array of pointers: https://github.com/sqlite/sqlite/blob/d2b9cc099d66fe220eb1c4883f865ec94cb37f52/ext/fts5/fts5_index.c#L1952-L1964 ```JavaScript static void fts5SegIterAllocTombstone(Fts5Index *p, Fts5SegIter *pIter){ const int nTomb = pIter->pSeg->nPgTombstone; if( nTomb>0 ){ int nByte = SZ_FTS5TOMBSTONEARRAY(nTomb+1); Fts5TombstoneArray *pNew; pNew = (Fts5TombstoneArray*)sqlite3Fts5MallocZero(&p->rc, nByte); if( pNew ){ pNew->nTombstone = nTomb; pNew->nRef = 1; pIter->pTombArray = pNew; } } } ``` https://github.com/sqlite/sqlite/blob/d2b9cc099d66fe220eb1c4883f865ec94cb37f52/ext/fts5/fts5_index.c#L566-L568 ```JavaScript /* Size (in bytes) of an Fts5TombstoneArray holding up to N tombstones */ #define SZ_FTS5TOMBSTONEARRAY(N) \ (offsetof(Fts5TombstoneArray,apTombstone)+(N)*sizeof(Fts5Data*)) ``` `nByte` is a signed 32-bit integer. While the multiplication done in the `SZ_FTS5TOMBSTONEARRAY` macro is a 64-bit multiplication, the result gets truncated to 32-bit should the resulting value exceed 2^32 - 1. `pIter->pSeg->nPgTombstone` is a fully attacker controlled, 32-bit value that is stored within the metadata tables for a FTS5 table: https://github.com/sqlite/sqlite/blob/837dc09bce7de8971c7488b70cf5da93c60fbed0/ext/fts5/fts5_index.c#L1159 `i += fts5GetVarint32(&pData[i], pSeg->nPgTombstone);` By setting `nPgTombstone` to e.g. 1610612738, `nByte` becomes 32. As a result, only 32 bytes are allocated for an array that is supposed to fit 1610612738 entries. This array is then used in the `fts5MultiIterIsDeleted()` function. An array index is calculated using the `Rowid` of the current context and is bound checked by the number of Tombstone pointers. Since `nTombstone` is the original value that was not overflowed, the `iPg` entry can point out of bounds. If the entry at `iPg` is 0, a structure is allocated and a pointer to it is written out of bounds: https://github.com/sqlite/sqlite/blob/837dc09bce7de8971c7488b70cf5da93c60fbed0/ext/fts5/fts5_index.c#L3302-L3314 ```JavaScript if( pSeg->pLeaf && pArray ){ /* Figure out which page the rowid might be present on. */ int iPg = ((u64)pSeg->iRowid) % pArray->nTombstone; assert( iPg>=0 ); /* If tombstone hash page iPg has not yet been loaded from the ** database, load it now. */ if( pArray->apTombstone[iPg]==0 ){ pArray->apTombstone[iPg] = fts5DataRead(pIter->pIndex, FTS5_TOMBSTONE_ROWID(pSeg->pSeg->iSegid, iPg) ); if( pArray->apTombstone[iPg]==0 ) return 0; } ``` Fix can be found here: https://sqlite.org/src/info/63595b74956a9391 ### Timeline **Date reported**: 07/15/2025 **Date fixed**: 07/16/2025 **Date disclosed**: 08/15/2025

Severity from
GitHub (reviewed advisory)

More Google advisories

All Google
Advisory
FFmpeg - Heap-buffer-overflow write in jpeg2000dec
HighSep 8, 2025
ChatGPT Agent - XSS on file://home/oai/redirect.html
MediumSep 8, 2025
SQLite: Integer truncation in findOrCreateAggInfoColumn
HighAug 25, 2025
OpenAI Operator - Click on arbitrary origin by TOCTOU attack
HighAug 18, 2025
tar-fs Link Directory Traversal Vulnerability
CriticalAug 14, 2025
Python Tar Filter Bypass Vulnerability
High7.5Jul 31, 2025

Critical advisories by email

Wednesdays: the week’s critical and high advisories in the AI and data stack, with the fixed versions. Only in weeks that have some.

Double opt-in. Unsubscribe any time.