Package: release.debian.org Severity: normal Tags: bookworm User: [email protected] Usertags: pu X-Debbugs-Cc: Shani Yosef <[email protected]> Control: affects -1 + src:sqlite3
Hi RMs, [ Reason ] A security fix that might be exploited, but as far the security team goes, doesn't warrant a DSA. Then an optimization error which might produce invalid data. [ Impact ] The first issue can lead to a memory corruption issue, the second might generate invalid data. Any of these might cause application crashes and/or database corruption. [ Tests ] Local testing and the two fixes are part of Trixie + Sid as well. [ Risks ] I do not think there is any risk. I've already backported these fixes for Trixie as well, there are no issues. [ Checklist ] [x] *all* changes are documents in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in bookworm [x] the issue is verified as fixed in unstable Thanks for considering, Laszlo/GCS
diff -Nru sqlite3-3.40.1/debian/changelog sqlite3-3.40.1/debian/changelog --- sqlite3-3.40.1/debian/changelog 2024-11-02 21:03:43.000000000 +0100 +++ sqlite3-3.40.1/debian/changelog 2025-08-26 18:18:10.000000000 +0200 @@ -1,3 +1,15 @@ +sqlite3 (3.40.1-2+deb12u2) bookworm; urgency=medium + + [ Shani Yosef <[email protected]> ] + * Backport upstream security fix for CVE-2025-6965: the number of aggregate + terms could exceed the number of columns available (closes: #1109379). + + [ Laszlo Boszormenyi (GCS) ] + * Fix a bug in the NOT NULL/IS NULL optimization that can cause invalid + data. + + -- Laszlo Boszormenyi (GCS) <[email protected]> Tue, 26 Aug 2025 18:18:10 +0200 + sqlite3 (3.40.1-2+deb12u1) bookworm; urgency=medium * Non-maintainer upload. diff -Nru sqlite3-3.40.1/debian/patches/41-fix_a_bug_in_the_NOT_NULL-IS_NULL_optimization.patch sqlite3-3.40.1/debian/patches/41-fix_a_bug_in_the_NOT_NULL-IS_NULL_optimization.patch --- sqlite3-3.40.1/debian/patches/41-fix_a_bug_in_the_NOT_NULL-IS_NULL_optimization.patch 1970-01-01 01:00:00.000000000 +0100 +++ sqlite3-3.40.1/debian/patches/41-fix_a_bug_in_the_NOT_NULL-IS_NULL_optimization.patch 2025-05-24 15:52:55.000000000 +0200 @@ -0,0 +1,58 @@ +Index: sqlite3/src/expr.c +================================================================== +--- sqlite3/src/expr.c ++++ sqlite3/src/expr.c +@@ -5279,15 +5279,15 @@ + case TK_ISNULL: + case TK_NOTNULL: { + assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL ); + assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL ); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); +- sqlite3VdbeTypeofColumn(v, r1); ++ assert( regFree1==0 || regFree1==r1 ); ++ if( regFree1 ) sqlite3VdbeTypeofColumn(v, r1); + sqlite3VdbeAddOp2(v, op, r1, dest); + VdbeCoverageIf(v, op==TK_ISNULL); + VdbeCoverageIf(v, op==TK_NOTNULL); +- testcase( regFree1==0 ); + break; + } + case TK_BETWEEN: { + testcase( jumpIfNull==0 ); + exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfTrue, jumpIfNull); +@@ -5454,15 +5454,15 @@ + break; + } + case TK_ISNULL: + case TK_NOTNULL: { + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); +- sqlite3VdbeTypeofColumn(v, r1); ++ assert( regFree1==0 || regFree1==r1 ); ++ if( regFree1 ) sqlite3VdbeTypeofColumn(v, r1); + sqlite3VdbeAddOp2(v, op, r1, dest); + testcase( op==TK_ISNULL ); VdbeCoverageIf(v, op==TK_ISNULL); + testcase( op==TK_NOTNULL ); VdbeCoverageIf(v, op==TK_NOTNULL); +- testcase( regFree1==0 ); + break; + } + case TK_BETWEEN: { + testcase( jumpIfNull==0 ); + exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfFalse, jumpIfNull); + +Index: sqlite3/src/vdbe.c +================================================================== +--- sqlite3/src/vdbe.c ++++ sqlite3/src/vdbe.c +@@ -3545,10 +3545,11 @@ + } + }else{ + zHdr += sqlite3PutVarint(zHdr, serial_type); + if( pRec->n ){ + assert( pRec->z!=0 ); ++ assert( pRec->z!=(const char*)sqlite3CtypeMap ); + memcpy(zPayload, pRec->z, pRec->n); + zPayload += pRec->n; + } + } + if( pRec==pLast ) break; + diff -Nru sqlite3-3.40.1/debian/patches/42-CVE-2025-6965.patch sqlite3-3.40.1/debian/patches/42-CVE-2025-6965.patch --- sqlite3-3.40.1/debian/patches/42-CVE-2025-6965.patch 1970-01-01 01:00:00.000000000 +0100 +++ sqlite3-3.40.1/debian/patches/42-CVE-2025-6965.patch 2025-08-26 18:13:12.000000000 +0200 @@ -0,0 +1,117 @@ +From c52e9d97d485a3eb168e3f8f3674a7bc4b419703 Mon Sep 17 00:00:00 2001 +From: drh <> +Date: Fri, 27 Jun 2025 19:02:21 +0000 +Subject: [PATCH] Raise an error right away if the number of aggregate terms in + a query exceeds the maximum number of columns. + +FossilOrigin-Name: 5508b56fd24016c13981ec280ecdd833007c9d8dd595edb295b984c2b487b5c8 +--- + manifest | 16 ++++++++-------- + manifest.uuid | 2 +- + src/expr.c | 16 +++++++++++++++- + src/sqliteInt.h | 10 +++++----- + 4 files changed, 29 insertions(+), 15 deletions(-) + +Customized by us to be applied to the sqlite3 version 3.40.1 + +diff --git a/src/expr.c b/src/expr.c +index 7a4e59f28d..cdae3169b2 100644 +--- a/src/expr.c ++++ b/src/expr.c +@@ -6277,6 +6277,8 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ + ** is not an entry there already. + */ + int k; ++ int mxTerm = pParse->db->aLimit[SQLITE_LIMIT_COLUMN]; ++ assert( mxTerm <= SMXV(i16) ); + pCol = pAggInfo->aCol; + for(k=0; k<pAggInfo->nColumn; k++, pCol++){ + if( pCol->iTable==pExpr->iTable +@@ -6289,6 +6291,10 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ + if( (k>=pAggInfo->nColumn) + && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0 + ){ ++ if( k>mxTerm ){ ++ sqlite3ErrorMsg(pParse, "more than %d aggregate terms", mxTerm); ++ k = mxTerm; ++ } + pCol = &pAggInfo->aCol[k]; + assert( ExprUseYTab(pExpr) ); + pCol->pTab = pExpr->y.pTab; +@@ -6327,6 +6333,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_COLUMN ){ + pExpr->op = TK_AGG_COLUMN; + } ++ assert( k <= SMXV(pExpr->iAgg) ); + pExpr->iAgg = (i16)k; + break; + } /* endif pExpr->iTable==pItem->iCursor */ +@@ -6342,13 +6349,19 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ + ** function that is already in the pAggInfo structure + */ + struct AggInfo_func *pItem = pAggInfo->aFunc; ++ int mxTerm = pParse->db->aLimit[SQLITE_LIMIT_COLUMN]; ++ assert( mxTerm <= SMXV(i16) ); + for(i=0; i<pAggInfo->nFunc; i++, pItem++){ + if( pItem->pFExpr==pExpr ) break; + if( sqlite3ExprCompare(0, pItem->pFExpr, pExpr, -1)==0 ){ + break; + } + } +- if( i>=pAggInfo->nFunc ){ ++ if( i>mxTerm ){ ++ sqlite3ErrorMsg(pParse, "more than %d aggregate terms", mxTerm); ++ i = mxTerm; ++ assert( i<pAggInfo->nFunc ); ++ }else if( i>=pAggInfo->nFunc ){ + /* pExpr is original. Make a new entry in pAggInfo->aFunc[] + */ + u8 enc = ENC(pParse->db); +@@ -6373,6 +6386,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ + */ + assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); + ExprSetVVAProperty(pExpr, EP_NoReduce); ++ assert( i <= SMXV(pExpr->iAgg) ); + pExpr->iAgg = (i16)i; + pExpr->pAggInfo = pAggInfo; + return WRC_Prune; +diff --git a/src/sqliteInt.h b/src/sqliteInt.h +index e4b74f6d0b..f9bed00234 100644 +--- a/src/sqliteInt.h ++++ b/src/sqliteInt.h +@@ -941,6 +941,15 @@ typedef INT16_TYPE LogEst; + #define LARGEST_UINT64 (0xffffffff|(((u64)0xffffffff)<<32)) + #define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) + ++/* ++** Macro SMXV(n) return the maximum value that can be held in variable n, ++** assuming n is a signed integer type. UMXV(n) is similar for unsigned ++** integer types. ++*/ ++#define SMXV(n) ((((i64)1)<<(sizeof(n)*8-1))-1) ++#define UMXV(n) ((((i64)1)<<(sizeof(n)*8))-1) ++ ++ + /* + ** Round up a number to the next larger multiple of 8. This is used + ** to force 8-byte alignment on 64-bit architectures. +@@ -2718,7 +2727,7 @@ struct AggInfo { + ** than the source table */ + int sortingIdx; /* Cursor number of the sorting index */ + int sortingIdxPTab; /* Cursor number of pseudo-table */ +- int nSortingColumn; /* Number of columns in the sorting index */ ++ u32 nSortingColumn; /* Number of columns in the sorting index */ + int mnReg, mxReg; /* Range of registers allocated for aCol and aFunc */ + ExprList *pGroupBy; /* The group by clause */ + struct AggInfo_col { /* For each column used in source tables */ +@@ -2726,8 +2735,8 @@ struct AggInfo { + Expr *pCExpr; /* The original expression */ + int iTable; /* Cursor number of the source table */ + int iMem; /* Memory location that acts as accumulator */ +- i16 iColumn; /* Column number within the source table */ +- i16 iSorterColumn; /* Column number in the sorting index */ ++ int iColumn; /* Column number within the source table */ ++ int iSorterColumn; /* Column number in the sorting index */ + } *aCol; + int nColumn; /* Number of used entries in aCol[] */ + int nAccumulator; /* Number of columns that show through to the output. diff -Nru sqlite3-3.40.1/debian/patches/series sqlite3-3.40.1/debian/patches/series --- sqlite3-3.40.1/debian/patches/series 2024-11-02 21:03:43.000000000 +0100 +++ sqlite3-3.40.1/debian/patches/series 2025-08-26 18:18:06.000000000 +0200 @@ -7,6 +7,8 @@ 32-dynamic_link.patch 02-use-packaged-lempar.c.patch 40-amalgamation_configure.patch +41-fix_a_bug_in_the_NOT_NULL-IS_NULL_optimization.patch +42-CVE-2025-6965.patch 0001-Fix-a-buffer-overread-in-the-sessions-extension-that.patch 0002-Avoid-a-stack-overflow-that-could-be-caused-by-a-rec.patch 0003-Fix-a-technically-undefined-signed-integer-overflow-.patch

