
Clickbait. La CVE è spazzatura AI.
scusate per il nome clickbait del repo, ma questa CVE è spazzatura completamente e totalmente allucinata da un LLM; onestamente, è triste vedere una CNA accettare una cosa del genere, visto quanto sono incoerenti le affermazioni 💔
CVE-2026-51302 non è reale 😱
La SQL pubblicata non riproduce un use-after-free in nessuna release di SQLite 3.41 sotto AddressSanitizer. Ancora più importante, la causa principale dichiarata è completamente incompatibile con il sorgente interessato:
exprComputeOperands() non esiste in SQLite 3.41.0, 3.41.1 o 3.41.2;regFree1 è un identificatore intero di registro della macchina virtuale, non un puntatore a memoria heap;sqlite3ReleaseTempReg() rende un registro disponibile per il riutilizzo e non lascia un puntatore C pendente in regFree1;exprComputeOperands(), gli operandi vengono calcolati prima che i registri temporanei vengano rilasciati, contrariamente alla sequenza dichiarata nell'advisory; eexprComputeOperands().Questo record CVE dovrebbe essere respinto e solleverò una disputa CNA con MITRE 😉
L'advisory identifica la versione interessata come "SQLite 3.41" e fornisce questa query:
SELECT CASE WHEN (1+3) THEN (5*8) ELSE (2/0) END FROM test;
Afferma che:
sqlite3ReleaseTempReg() libera la memoria heap associata a regFree1;regFree1 rimane come riferimento pendente;exprComputeOperands() accede successivamente alla memoria liberata; eL'amalgamation di SQLite 3.41.0 definisce la funzione come segue:
SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){
if( iReg ){
sqlite3VdbeReleaseRegisters(pParse, iReg, 1, 0, 0);
if( pParse->nTempReg<ArraySize(pParse->aTempReg) ){
pParse->aTempReg[pParse->nTempReg++] = iReg;
}
}
}
La funzione riceve iReg come int. Registra quel numero intero in pParse->aTempReg in modo che il numero di registro possa essere riallocato:
SQLITE_PRIVATE int sqlite3GetTempReg(Parse *pParse){
if( pParse->nTempReg==0 ){
return ++pParse->nMem;
}
return pParse->aTempReg[--pParse->nTempReg];
}
Questa è la gestione del ciclo di vita dei registri durante la generazione del programma VDBE. L'advisory descrive regFree1 come se fosse un puntatore sopravvissuto a memoria heap liberata. Non lo è:
int regFree1 = 0, regFree2 = 0;
int r1, r2;
r1 = exprVectorRegister(pParse, pLeft, i, regLeft, &pL, ®Free1);
r2 = exprVectorRegister(pParse, pRight, i, regRight, &pR, ®Free2);
codeCompare(pParse, pL, pR, opx, r1, r2, addrDone, p5, isCommuted);
sqlite3ReleaseTempReg(pParse, regFree1);
sqlite3ReleaseTempReg(pParse, regFree2);
La comparazione generata consuma gli identificatori di registro prima che vengano rilasciati per il riutilizzo.
Una ricerca con git blame sul mirror Git ha rilevato che exprComputeOperands() è stata introdotta da:
e24f20a4f5a6d26cdaece58eff77619a4ee757b9
2025-06-30T10:30:47Z
Factor out the code that tries to avoid evaluating subquery operands if the other operand is NULL into a subroutine, so that it can be more easily reused by other parts of the code generator.
La funzione è assente da tutte e tre le amalgamation ufficiali di SQLite 3.41. Una vulnerabilità in SQLite 3.41 non può seguire un percorso di esecuzione attraverso una funzione introdotta nel 2025, ma dai MITRE, davvero? 🥲
Nel sorgente moderno di SQLite, l'ordine di chiamata abbreviato in sqlite3ExprIfTrue() è:
addrIsNull = exprComputeOperands(
pParse, pExpr, &r1, &r2, ®Free1, ®Free2);
codeCompare(
pParse, pExpr->pLeft, pExpr->pRight, op,
r1, r2, dest, jumpIfNull, ExprHasProperty(pExpr, EP_Commuted));
/* Other switch cases and generated-bytecode handling occur here. */
sqlite3ReleaseTempReg(pParse, regFree1);
sqlite3ReleaseTempReg(pParse, regFree2);
exprComputeOperands() produce gli identificatori di registro. Il chiamante li consuma e poi li rilascia. L'advisory invece afferma che sqlite3ReleaseTempReg() viene eseguita per prima e che exprComputeOperands() accede successivamente all'oggetto rilasciato.
exprComputeOperands() è stata introdotta per evitare di valutare un costoso operando di subquery quando l'altro operando è NULL. L'espressione pubblicata:
CASE WHEN (1+3) THEN (5*8) ELSE (2/0) END
contiene operazioni aritmetiche e un'espressione CASE ma nessun operando di subquery. La motivazione fornita per questa query non corrisponde alle condizioni di chiamata della funzione.
vm, tra l'altro
Debian GNU/Linux 13 (trixie)
Clang 19.1.7
AddressSanitizer enabled
Optimisation level: -O1
Frame pointers retained
Sanitizer recovery disabled
SHA delle amalgamation:
3.41.0 146ce189b67fdbefbf2d72cdc81e198d07ff643614cc9102e9bf063255e8e7e1
3.41.1 df0d54bf246521360c8148f64e7e5ad07a4665b4f902339e844f4c493d535ff5
3.41.2 01df06a84803c1ab4d62c64e995b151b2dbcf5dbc93bbc5eee213cb18225d987
3.53.3 646421e12aac110282ef8cc68f1a62d4bb15fc7b8f09da0b53e29ee690500431