CVE-2025-48595 AI-generated analysis
platform/external/sqlite (libsqlite3 amalgamation dist/sqlite3.c, dist/orig/sqlite3.c, shell.c); platform/build/release RELEASE_PACKAGE_LIBSQLITE3 flag on Android 15/16
Google fixed CVE-2025-48595 by moving the bundled SQLite library to a patched upstream point release instead of applying a single targeted patch. On Android 14 that meant 3.42.0 to 3.42.1, after a first 3.39.6 update was reverted. On Android 15 and 16 it meant RELEASE_PACKAGE_LIBSQLITE3 flag changes (Android 15: trunk_staging flag file deleted; Android 16: ap3a moved to 3.44.5).
Root cause
The material does not isolate the vulnerable code. The fix is a cumulative upstream SQLite patch-release update, and the bulletin only states High severity EoP. The 3.42.0 to 3.42.1 diff in effect on Android 14 contains several memory-safety and corruption-handling hardenings in the amalgamation: - defragmentPage copied only part of the page into temp space. - lockBtree set BTS_PAGESIZE_FIXED before validating the page size. - loadStatTbl padded stat4 samples with only 2 zero bytes. - sessionReadRecord read 8-byte INTEGER/FLOAT values without checking the remaining input. - fts5DoSecureDelete copied nPrefix2-nPrefix bytes from pSeg->term.p without checking nPrefix2 against pSeg->term.n, and recomputed page-index offsets differently. - fts5DlidxLvlNext and fts5WriteDlidxAppend did signed rowid delta arithmetic. - findOrCreateAggInfoColumn stored iAgg as (i16)k without masking and had no early return for an already-registered expression. - valueNew did not reset the returned aMem slot to NULL. The material does not show which of these corresponds to the CVE.
How the fix works
- Commit 2abdb383b72c (android-security-14.0.0_r24) updates dist/orig/sqlite3.c, dist/sqlite3.c, dist/orig/sqlite3.h and dist/sqlite3.h from 3.39.2 to 3.39.6 (SQLITE_SOURCE_ID 2025-08-01 642be27a38). It adds LICENSE and NOTICE, rewrites METADATA and README.version, and rebases the hunk offsets in dist/Android.patch. Notable content: - a bounds check on pCell+4 in modifyPagePointer - a rewrite of the balance_nonroot page-number sort, with sqlite3PcacheMove dropping a colliding cached page - unixGetTempname and the temp_store_directory / data_store_directory pragmas now run under SQLITE_MUTEX_STATIC_TEMPDIR - sqlite3FinishTrigger refuses triggers that write to shadow tables - the codeEqualityTerm aiMap array is sized MAX(nEq,n) - OP_MustBeInt is emitted before OP_Filter - FTS3 allocations move to sqlite3_malloc64/realloc64 with i64 sizes - iAgg is masked with 0x7fff in analyzeAggregate - NULL guards in sqlite3_strglob/sqlite3_strlike and dbpageUpdate - NULL guards in shell.c eqp_append and dump_callback
- Commit ba40d842b44f (android-security-14.0.0_r25) fully reverts the 3.39.6 update. Its message says the branch was missing the mandatory udc patch aosp/2622587, which upgraded sqlite to 3.40.0, and that CVE fixes must be applied on top of that patch.
- Commit 3b55568966b4 (android-security-14.0.0_r25) is the effective fix. It updates the amalgamation and both sqlite3.h copies from 3.42.0 to 3.42.1 (SQLITE_SOURCE_ID 2025-08-06 4a8bf3c146), updates the METADATA version and archive, adds NOTICE, and rebases dist/Android.patch. Code changes in sqlite3.c: - defragmentPage does memcpy(temp, data, usableSize) for the whole page. - lockBtree sets BTS_PAGESIZE_FIXED only after the page-size checks. - sqlite3BtreeIntegrityCheck sets sCheck.v0 for each root. - valueNew calls sqlite3VdbeMemSetNull on the returned slot. - vdbeRecordCompareDebug tolerates corrupt short integer fields. - findOrCreateAggInfoColumn returns early if pCol->pCExpr==pExpr and masks iAgg with 0x7fff. - loadStatTbl allocates pSample->n + 8 bytes. - sqlite3SrcListLookup sets fg.notCte. - EP_Unlikely is cleared, and sqlite3ExprTruthValue uses sqlite3ExprSkipCollateAndLikely. - sessionReadRecord returns SQLITE_CORRUPT_BKPT when fewer than 8 bytes remain. - fts5DlidxLvlNext and fts5WriteDlidxAppend use u64 deltas. - fts5MultiIterDoCompare no longer copies bDel. - fts5DoSecureDelete handles bDel, sets FTS5_CORRUPT when nPrefix2>pSeg->term.n, and recomputes key offsets. - fts5FlushOneHash handles bDel entries under secure-delete. shell.c changes: recoverIsValidPage rejects nByte<4; .dump quotes names via printf('"%w"'); -nonce uses cmdline_option_value.
- Android 16 (platform/build/release b11607ea3ec7): flag_values/ap3a/RELEASE_PACKAGE_LIBSQLITE3.textproto changes from 3440300 to 3440500.
- Android 15 (platform/build/release df01bf9a7498): deletes flag_values/trunk_staging/RELEASE_PACKAGE_LIBSQLITE3.textproto, which held 3440300.
- Android 17 (platform/external/sqlite e13117e12f88, android-17.0.0_r1): removes the obsolete dist/sqlite-autoconf-3500100 (3.50.1) source tree.
Completeness
- On Android 14 the effective change is the whole 3.42.0 to 3.42.1 upstream delta. The 3.39.6 delta was reverted. The material does not show whether the 3.42.0 baseline already contained the hardenings from the 3.39.6 update.
- One change appears in both the 3.39.6 and 3.42.1 deltas: masking pExpr->iAgg with 0x7fff. The material does not say this is the CVE fix.
- Both dist/sqlite3.c and dist/orig/sqlite3.c are updated, and dist/Android.patch is rebased onto the new line offsets.
- At android-security-14.0.0_r29 the amalgamation and headers are 3.42.1, but METADATA and README.version still read 3.42.0 and NOTICE is absent.
- Android 15 and 16 are fixed only through the RELEASE_PACKAGE_LIBSQLITE3 flag. The material does not show the source delta of the selected package.
Behavior changes
- On Android 14, SQLITE_VERSION / SQLITE_VERSION_NUMBER become 3.42.1 / 3042001 with a 2025-08-06 source id. The fts5 source id string changes to match.
- Session extension: sessionReadRecord returns SQLITE_CORRUPT for input that ends inside an 8-byte INTEGER/FLOAT value.
- FTS5 secure-delete: FTS5_CORRUPT is set when the prefix length exceeds the term length, and handling of deleted entries changes in fts5FlushOneHash and fts5DoSecureDelete.
- Btree: BTS_PAGESIZE_FIXED is set only after the page-size checks pass, and defragmentPage copies the whole usable page into temp space.
- stat4 sample buffers get 8 bytes of zero padding instead of 2.
- sqlite3 shell: .recover rejects free blocks smaller than 4 bytes, .dump quotes table and column names, and the -nonce argument goes through cmdline_option_value.
- Android 16 ap3a selects sqlite package 3440500 instead of 3440300. Android 15 trunk_staging no longer pins 3440300.
Per major
- Android 14: Adapted fix in several steps. 2abdb383b72c (r24) updated sqlite from 3.39.2 to 3.39.6. ba40d842b44f (r25) reverted it because the mandatory aosp/2622587 (sqlite 3.40.0 upgrade) was missing. 3b55568966b4 (r25) then applied the 3.42.0 to 3.42.1 update. At android-security-14.0.0_r29, 3/8 lines of the tracked patched region are present; dist/sqlite3.c and sqlite3.h are 3.42.1, while METADATA and README.version still say 3.42.0.
- Android 15: Adapted fix via build flag. platform/build/release df01bf9a7498 deletes flag_values/trunk_staging/RELEASE_PACKAGE_LIBSQLITE3.textproto (3440300). 2/2 lines of the patched region are present at android-security-15.0.0_r17. The resulting sqlite version is not shown.
- Android 16: Adapted fix via build flag. platform/build/release b11607ea3ec7 changes flag_values/ap3a/RELEASE_PACKAGE_LIBSQLITE3.textproto from 3440300 to 3440500. 2/2 lines of the patched region are present at android-security-16.0.0_r8.
- Android 17: Fixed in the base release (android-17.0.0_r1). platform/external/sqlite e13117e12f88 removes the obsolete dist/sqlite-autoconf-3500100 (3.50.1) tree, and the patched files are absent at android-security-17.0.0_r1. The shipped version is not shown.
Unknowns
- Which upstream SQLite change corresponds to CVE-2025-48595, and what input triggers it.
- How the vulnerable code is reached on Android (for example, which SQL or database content).
- Whether the 3.42.0 baseline on Android 14 already contained the hardenings from the reverted 3.39.6 update.
- Why METADATA and README.version at android-security-14.0.0_r29 still state 3.42.0, and why NOTICE is absent there.
- Which sqlite version Android 15 trunk_staging resolves to after the flag file deletion, and which version Android 17 ships.
- The content of the sqlite 3.44.3 to 3.44.5 delta selected on Android 16.