
クリックベイトなリポジトリ名で申し訳ないが、このCVEは完全にLLMが幻覚しただけのゴミであり、主張がこれほど矛盾しているのにCNAがこれを受理したのを見ると本当に悲しい 💔
CVE-2026-51302 は実在しません 😱
公開されたSQLでは、AddressSanitizer 環境下のいずれの SQLite 3.41 リリースでも use-after-free を再現できません。さらに重要なことに、記載された根本原因は影響を受けるソースと完全に矛盾しています:
exprComputeOperands() は SQLite 3.41.0、3.41.1、3.41.2 のいずれにも存在しません;regFree1 は仮想マシンのレジスタ識別子(整数)であり、ヒープストレージへのポインタではありません;sqlite3ReleaseTempReg() はレジスタを再利用可能にするだけで、regFree1 にダングリングCポインタを残しません;exprComputeOperands() を含むソースバージョンでは、アドバイザリが主張する順序とは逆に、一時レジスタが解放される前にオペランドが計算されます; そしてexprComputeOperands() が導入された最適化は実行されません。このCVEレコードは拒否されるべきであり、私はMITREに対してCNA紛争を提起するつもりです 😉
アドバイザリは影響を受けるバージョンを「SQLite 3.41」と特定し、次のクエリを提供しています:
SELECT CASE WHEN (1+3) THEN (5*8) ELSE (2/0) END FROM test;
その主張は以下の通りです:
sqlite3ReleaseTempReg() が regFree1 に関連付けられたヒープメモリを解放する;regFree1 がダングリング参照として残る;exprComputeOperands() がその後、解放されたメモリにアクセスする; そしてSQLite 3.41.0 のアマルガメーションでは、この関数は次のように定義されています:
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;
}
}
}
この関数は iReg を int として受け取ります。レジスタ番号が再割り当てできるように、その整数を pParse->aTempReg に記録します:
SQLITE_PRIVATE int sqlite3GetTempReg(Parse *pParse){
if( pParse->nTempReg==0 ){
return ++pParse->nMem;
}
return pParse->aTempReg[--pParse->nTempReg];
}
これは VDBE プログラム生成時におけるレジスタのライフタイム管理です。アドバイザリは regFree1 を、解放されたヒープストレージへの生存ポインタであるかのように説明していますが、そうではありません:
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);
生成された比較処理は、レジスタ識別子が再利用のために解放される前に、それらを消費します。
Gitミラーの blame 検索により、exprComputeOperands() が次のコミットで導入されたことが判明しました:
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.
この関数は公式の SQLite 3.41 アマルガメーション3つすべてに存在しません。SQLite 3.41 の脆弱性が、2025年に導入された関数を通る実行経路をたどることはあり得ません。ねえMITRE、本当に? 🥲
最新のSQLiteソースでは、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() はレジスタ識別子を生成します。呼び出し側はそれらを消費してから解放します。一方アドバイザリは、sqlite3ReleaseTempReg() が先に実行され、exprComputeOperands() が後で解放されたオブジェクトにアクセスすると主張しています。
exprComputeOperands() は、一方のオペランドが NULL の場合に、高コストなサブクエリオペランドの評価を回避するために導入されました。公開された式は:
CASE WHEN (1+3) THEN (5*8) ELSE (2/0) END
算術演算と CASE 式を含みますが、サブクエリオペランドは含まれていません。このクエリに関する説明は、この関数の呼び出し条件に対応していません。
ちなみにVMです
Debian GNU/Linux 13 (trixie)
Clang 19.1.7
AddressSanitizer enabled
Optimisation level: -O1
Frame pointers retained
Sanitizer recovery disabled
アマルガメーションのSHA:
3.41.0 146ce189b67fdbefbf2d72cdc81e198d07ff643614cc9102e9bf063255e8e7e1
3.41.1 df0d54bf246521360c8148f64e7e5ad07a4665b4f902339e844f4c493d535ff5
3.41.2 01df06a84803c1ab4d62c64e995b151b2dbcf5dbc93bbc5eee213cb18225d987
3.53.3 646421e12aac110282ef8cc68f1a62d4bb15fc7b8f09da0b53e29ee690500431