| From e40cc16b472071f553700c7208394e6cf73d5688 Mon Sep 17 00:00:00 2001 |
| From: drh <drh@noemail.net> |
| Date: Sun, 24 May 2020 03:01:36 +0000 |
| Subject: [PATCH] Combination of patches to fix CVE2020-13435 |
| |
| Combines: |
| |
| Move some utility Walker callbacks into the walker.c source file, as they seem to belong there better. |
| When rewriting a query for window functions, if the rewrite changes the depth of TK_AGG_FUNCTION nodes, be sure to adjust the Expr.op2 field appropriately. Fix for ticket [7a5279a25c57adf1] |
| Defensive code that tries to prevent a recurrence of problems like the one described in ticket [7a5279a25c57adf1] |
| |
| FossilOrigin-Name: dac438236f7c5419d4e7e094e8b3f19f83cd3b1a18bc8acb14aee90d4514fa3c |
| FossilOrigin-Name: ad7bb70af9bb68d192137188bb2528f1e9e43ad164c925174ca1dafc9e1f5339 |
| FossilOrigin-Name: 572105de1d44bca4f18c99d373458889163611384eebbc9659474874ee1701f4 |
| |
| Upstream-Status: Backport |
| CVE: CVE-2020-13435 |
| |
| Reference to upstream patches: |
| https://github.com/sqlite/sqlite/commit/e40cc16b472071f553700c7208394e6cf73d5688 |
| https://github.com/sqlite/sqlite/commit/c37577bb2dfb602a5cdbba8322a01b548c34c185 |
| https://github.com/sqlite/sqlite/commit/0934d640456bb168a8888ae388643c5160afe501 |
| |
| Patches combined and converted to amalgamation format |
| |
| Signed-off-by: Steve Sakoman <steve@sakoman.com> |
| --- |
| diff --git a/sqlite3.c b/sqlite3.c |
| index 5ff2c14..02892f8 100644 |
| --- a/sqlite3.c |
| +++ b/sqlite3.c |
| @@ -18965,6 +18965,9 @@ SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker*, Select*); |
| SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker*, Expr*); |
| SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker*, Select*); |
| SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker*, Select*); |
| +SQLITE_PRIVATE int sqlite3WalkerDepthIncrease(Walker*,Select*); |
| +SQLITE_PRIVATE void sqlite3WalkerDepthDecrease(Walker*,Select*); |
| + |
| #ifdef SQLITE_DEBUG |
| SQLITE_PRIVATE void sqlite3SelectWalkAssert2(Walker*, Select*); |
| #endif |
| @@ -96773,6 +96776,43 @@ SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){ |
| return WRC_Continue; |
| } |
| |
| +/* Increase the walkerDepth when entering a subquery, and |
| +** descrease when leaving the subquery. |
| +*/ |
| +SQLITE_PRIVATE int sqlite3WalkerDepthIncrease(Walker *pWalker, Select *pSelect){ |
| + UNUSED_PARAMETER(pSelect); |
| + pWalker->walkerDepth++; |
| + return WRC_Continue; |
| +} |
| +SQLITE_PRIVATE void sqlite3WalkerDepthDecrease(Walker *pWalker, Select *pSelect){ |
| + UNUSED_PARAMETER(pSelect); |
| + pWalker->walkerDepth--; |
| +} |
| + |
| + |
| +/* |
| +** No-op routine for the parse-tree walker. |
| +** |
| +** When this routine is the Walker.xExprCallback then expression trees |
| +** are walked without any actions being taken at each node. Presumably, |
| +** when this routine is used for Walker.xExprCallback then |
| +** Walker.xSelectCallback is set to do something useful for every |
| +** subquery in the parser tree. |
| +*/ |
| +SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){ |
| + UNUSED_PARAMETER2(NotUsed, NotUsed2); |
| + return WRC_Continue; |
| +} |
| + |
| +/* |
| +** No-op routine for the parse-tree walker for SELECT statements. |
| +** subquery in the parser tree. |
| +*/ |
| +SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker *NotUsed, Select *NotUsed2){ |
| + UNUSED_PARAMETER2(NotUsed, NotUsed2); |
| + return WRC_Continue; |
| +} |
| + |
| /************** End of walker.c **********************************************/ |
| /************** Begin file resolve.c *****************************************/ |
| /* |
| @@ -96801,6 +96841,8 @@ SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){ |
| ** |
| ** incrAggFunctionDepth(pExpr,n) is the main routine. incrAggDepth(..) |
| ** is a helper function - a callback for the tree walker. |
| +** |
| +** See also the sqlite3WindowExtraAggFuncDepth() routine in window.c |
| */ |
| static int incrAggDepth(Walker *pWalker, Expr *pExpr){ |
| if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.n; |
| @@ -102459,7 +102501,10 @@ expr_code_doover: |
| switch( op ){ |
| case TK_AGG_COLUMN: { |
| AggInfo *pAggInfo = pExpr->pAggInfo; |
| - struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg]; |
| + struct AggInfo_col *pCol; |
| + assert( pAggInfo!=0 ); |
| + assert( pExpr->iAgg>=0 && pExpr->iAgg<pAggInfo->nColumn ); |
| + pCol = &pAggInfo->aCol[pExpr->iAgg]; |
| if( !pAggInfo->directMode ){ |
| assert( pCol->iMem>0 ); |
| return pCol->iMem; |
| @@ -102753,7 +102798,10 @@ expr_code_doover: |
| } |
| case TK_AGG_FUNCTION: { |
| AggInfo *pInfo = pExpr->pAggInfo; |
| - if( pInfo==0 ){ |
| + if( pInfo==0 |
| + || NEVER(pExpr->iAgg<0) |
| + || NEVER(pExpr->iAgg>=pInfo->nFunc) |
| + ){ |
| assert( !ExprHasProperty(pExpr, EP_IntValue) ); |
| sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken); |
| }else{ |
| @@ -104492,15 +104540,6 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ |
| } |
| return WRC_Continue; |
| } |
| -static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){ |
| - UNUSED_PARAMETER(pSelect); |
| - pWalker->walkerDepth++; |
| - return WRC_Continue; |
| -} |
| -static void analyzeAggregatesInSelectEnd(Walker *pWalker, Select *pSelect){ |
| - UNUSED_PARAMETER(pSelect); |
| - pWalker->walkerDepth--; |
| -} |
| |
| /* |
| ** Analyze the pExpr expression looking for aggregate functions and |
| @@ -104514,8 +104553,8 @@ static void analyzeAggregatesInSelectEnd(Walker *pWalker, Select *pSelect){ |
| SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){ |
| Walker w; |
| w.xExprCallback = analyzeAggregate; |
| - w.xSelectCallback = analyzeAggregatesInSelect; |
| - w.xSelectCallback2 = analyzeAggregatesInSelectEnd; |
| + w.xSelectCallback = sqlite3WalkerDepthIncrease; |
| + w.xSelectCallback2 = sqlite3WalkerDepthDecrease; |
| w.walkerDepth = 0; |
| w.u.pNC = pNC; |
| w.pParse = 0; |
| @@ -133065,29 +133104,6 @@ static int selectExpander(Walker *pWalker, Select *p){ |
| return WRC_Continue; |
| } |
| |
| -/* |
| -** No-op routine for the parse-tree walker. |
| -** |
| -** When this routine is the Walker.xExprCallback then expression trees |
| -** are walked without any actions being taken at each node. Presumably, |
| -** when this routine is used for Walker.xExprCallback then |
| -** Walker.xSelectCallback is set to do something useful for every |
| -** subquery in the parser tree. |
| -*/ |
| -SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){ |
| - UNUSED_PARAMETER2(NotUsed, NotUsed2); |
| - return WRC_Continue; |
| -} |
| - |
| -/* |
| -** No-op routine for the parse-tree walker for SELECT statements. |
| -** subquery in the parser tree. |
| -*/ |
| -SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker *NotUsed, Select *NotUsed2){ |
| - UNUSED_PARAMETER2(NotUsed, NotUsed2); |
| - return WRC_Continue; |
| -} |
| - |
| #if SQLITE_DEBUG |
| /* |
| ** Always assert. This xSelectCallback2 implementation proves that the |
| @@ -150225,6 +150241,23 @@ static ExprList *exprListAppendList( |
| return pList; |
| } |
| |
| +/* |
| +** When rewriting a query, if the new subquery in the FROM clause |
| +** contains TK_AGG_FUNCTION nodes that refer to an outer query, |
| +** then we have to increase the Expr->op2 values of those nodes |
| +** due to the extra subquery layer that was added. |
| +** |
| +** See also the incrAggDepth() routine in resolve.c |
| +*/ |
| +static int sqlite3WindowExtraAggFuncDepth(Walker *pWalker, Expr *pExpr){ |
| + if( pExpr->op==TK_AGG_FUNCTION |
| + && pExpr->op2>=pWalker->walkerDepth |
| + ){ |
| + pExpr->op2++; |
| + } |
| + return WRC_Continue; |
| +} |
| + |
| /* |
| ** If the SELECT statement passed as the second argument does not invoke |
| ** any SQL window functions, this function is a no-op. Otherwise, it |
| @@ -150333,6 +150366,7 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ |
| p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); |
| if( p->pSrc ){ |
| Table *pTab2; |
| + Walker w; |
| p->pSrc->a[0].pSelect = pSub; |
| sqlite3SrcListAssignCursors(pParse, p->pSrc); |
| pSub->selFlags |= SF_Expanded; |
| @@ -150347,6 +150381,11 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ |
| pTab->tabFlags |= TF_Ephemeral; |
| p->pSrc->a[0].pTab = pTab; |
| pTab = pTab2; |
| + memset(&w, 0, sizeof(w)); |
| + w.xExprCallback = sqlite3WindowExtraAggFuncDepth; |
| + w.xSelectCallback = sqlite3WalkerDepthIncrease; |
| + w.xSelectCallback2 = sqlite3WalkerDepthDecrease; |
| + sqlite3WalkSelect(&w, pSub); |
| } |
| }else{ |
| sqlite3SelectDelete(db, pSub); |