| 
 | 1 | +From 1cc975ab5c8a066268501f98c71a54d20939f5e7 Mon Sep 17 00:00:00 2001  | 
 | 2 | +From: Madhur Aggarwal < [email protected]>  | 
 | 3 | +Date: Thu, 24 Jul 2025 10:43:07 +0000  | 
 | 4 | +Subject: [PATCH] Patch CVE-2025-6965  | 
 | 5 | + | 
 | 6 | +Upstream Patch Reference: https://www.sqlite.org/src/vpatch?from=c9ddd15b0197e6e5&to=5508b56fd24016c1  | 
 | 7 | +---  | 
 | 8 | + sqlite3.c | 25 +++++++++++++++++++++----  | 
 | 9 | + 1 file changed, 21 insertions(+), 4 deletions(-)  | 
 | 10 | + | 
 | 11 | +diff --git a/sqlite3.c b/sqlite3.c  | 
 | 12 | +index 8f9309a..dd0c5f4 100644  | 
 | 13 | +--- a/sqlite3.c  | 
 | 14 | ++++ b/sqlite3.c  | 
 | 15 | +@@ -14867,6 +14867,9 @@ typedef INT16_TYPE LogEst;  | 
 | 16 | + #define LARGEST_INT64  (0xffffffff|(((i64)0x7fffffff)<<32))  | 
 | 17 | + #define LARGEST_UINT64 (0xffffffff|(((u64)0xffffffff)<<32))  | 
 | 18 | + #define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)  | 
 | 19 | ++#define SMXV(n) ((((i64)1)<<(sizeof(n)*8-1))-1)  | 
 | 20 | ++#define UMXV(n) ((((i64)1)<<(sizeof(n)*8))-1)  | 
 | 21 | ++  | 
 | 22 | +   | 
 | 23 | + /*  | 
 | 24 | + ** Round up a number to the next larger multiple of 8.  This is used  | 
 | 25 | +@@ -18637,7 +18640,7 @@ struct AggInfo {  | 
 | 26 | +                           ** from source tables rather than from accumulators */  | 
 | 27 | +   u8 useSortingIdx;       /* In direct mode, reference the sorting index rather  | 
 | 28 | +                           ** than the source table */  | 
 | 29 | +-  u16 nSortingColumn;     /* Number of columns in the sorting index */  | 
 | 30 | ++  u32 nSortingColumn;     /* Number of columns in the sorting index */  | 
 | 31 | +   int sortingIdx;         /* Cursor number of the sorting index */  | 
 | 32 | +   int sortingIdxPTab;     /* Cursor number of pseudo-table */  | 
 | 33 | +   int iFirstReg;          /* First register in range for aCol[] and aFunc[] */  | 
 | 34 | +@@ -18646,8 +18649,8 @@ struct AggInfo {  | 
 | 35 | +     Table *pTab;             /* Source table */  | 
 | 36 | +     Expr *pCExpr;            /* The original expression */  | 
 | 37 | +     int iTable;              /* Cursor number of the source table */  | 
 | 38 | +-    i16 iColumn;             /* Column number within the source table */  | 
 | 39 | +-    i16 iSorterColumn;       /* Column number in the sorting index */  | 
 | 40 | ++    int iColumn;             /* Column number within the source table */  | 
 | 41 | ++    int iSorterColumn;       /* Column number in the sorting index */  | 
 | 42 | +   } *aCol;  | 
 | 43 | +   int nColumn;            /* Number of used entries in aCol[] */  | 
 | 44 | +   int nAccumulator;       /* Number of columns that show through to the output.  | 
 | 45 | +@@ -114514,7 +114517,9 @@ static void findOrCreateAggInfoColumn(  | 
 | 46 | + ){  | 
 | 47 | +   struct AggInfo_col *pCol;  | 
 | 48 | +   int k;  | 
 | 49 | ++  int mxTerm = pParse->db->aLimit[SQLITE_LIMIT_COLUMN];  | 
 | 50 | +   | 
 | 51 | ++  assert( mxTerm <= SMXV(i16) );  | 
 | 52 | +   assert( pAggInfo->iFirstReg==0 );  | 
 | 53 | +   pCol = pAggInfo->aCol;  | 
 | 54 | +   for(k=0; k<pAggInfo->nColumn; k++, pCol++){  | 
 | 55 | +@@ -114532,6 +114537,10 @@ static void findOrCreateAggInfoColumn(  | 
 | 56 | +     assert( pParse->db->mallocFailed );  | 
 | 57 | +     return;  | 
 | 58 | +   }  | 
 | 59 | ++  if( k>mxTerm ){  | 
 | 60 | ++    sqlite3ErrorMsg(pParse, "more than %d aggregate terms", mxTerm);  | 
 | 61 | ++    k = mxTerm;  | 
 | 62 | ++  }  | 
 | 63 | +   pCol = &pAggInfo->aCol[k];  | 
 | 64 | +   assert( ExprUseYTab(pExpr) );  | 
 | 65 | +   pCol->pTab = pExpr->y.pTab;  | 
 | 66 | +@@ -114565,6 +114574,7 @@ fix_up_expr:  | 
 | 67 | +   if( pExpr->op==TK_COLUMN ){  | 
 | 68 | +     pExpr->op = TK_AGG_COLUMN;  | 
 | 69 | +   }  | 
 | 70 | ++  assert( k <= SMXV(pExpr->iAgg) );  | 
 | 71 | +   pExpr->iAgg = (i16)k;  | 
 | 72 | + }  | 
 | 73 | +   | 
 | 74 | +@@ -114648,13 +114658,19 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){  | 
 | 75 | +         ** function that is already in the pAggInfo structure  | 
 | 76 | +         */  | 
 | 77 | +         struct AggInfo_func *pItem = pAggInfo->aFunc;  | 
 | 78 | ++        int mxTerm = pParse->db->aLimit[SQLITE_LIMIT_COLUMN];  | 
 | 79 | ++        assert( mxTerm <= SMXV(i16) );  | 
 | 80 | +         for(i=0; i<pAggInfo->nFunc; i++, pItem++){  | 
 | 81 | +           if( pItem->pFExpr==pExpr ) break;  | 
 | 82 | +           if( sqlite3ExprCompare(0, pItem->pFExpr, pExpr, -1)==0 ){  | 
 | 83 | +             break;  | 
 | 84 | +           }  | 
 | 85 | +         }  | 
 | 86 | +-        if( i>=pAggInfo->nFunc ){  | 
 | 87 | ++        if( i>mxTerm ){  | 
 | 88 | ++          sqlite3ErrorMsg(pParse, "more than %d aggregate terms", mxTerm);  | 
 | 89 | ++          i = mxTerm;  | 
 | 90 | ++          assert( i<pAggInfo->nFunc );  | 
 | 91 | ++        }else if( i>=pAggInfo->nFunc ){  | 
 | 92 | +           /* pExpr is original.  Make a new entry in pAggInfo->aFunc[]  | 
 | 93 | +           */  | 
 | 94 | +           u8 enc = ENC(pParse->db);  | 
 | 95 | +@@ -114706,6 +114722,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){  | 
 | 96 | +         */  | 
 | 97 | +         assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );  | 
 | 98 | +         ExprSetVVAProperty(pExpr, EP_NoReduce);  | 
 | 99 | ++        assert( i <= SMXV(pExpr->iAgg) );  | 
 | 100 | +         pExpr->iAgg = (i16)i;  | 
 | 101 | +         pExpr->pAggInfo = pAggInfo;  | 
 | 102 | +         return WRC_Prune;  | 
 | 103 | +--   | 
 | 104 | +2.45.4  | 
 | 105 | + | 
0 commit comments