Blame SOURCES/sqlite-3.26.0-CVE-2020-9327.patch

7d97b9
From 2d788539b0018d34d3cabb328387ba6bec41ec42 Mon Sep 17 00:00:00 2001
7d97b9
From: Ondrej Dubaj <odubaj@redhat.com>
7d97b9
Date: Thu, 26 Mar 2020 09:43:43 +0100
7d97b9
Subject: [PATCH] NULL pointer dereference and segmentation fault because of
7d97b9
 generated column optimizations
7d97b9
7d97b9
Take care when checking the table of a TK_COLUMN expression node to
7d97b9
see if the table is a virtual table to first ensure that the
7d97b9
Expr.y.pTab pointer is not null due to generated column optimizations.
7d97b9
---
7d97b9
 src/expr.c      | 13 ++++++++++---
7d97b9
 src/sqliteInt.h |  3 +++
7d97b9
 src/whereexpr.c | 12 ++++++++----
7d97b9
 3 files changed, 21 insertions(+), 7 deletions(-)
7d97b9
7d97b9
diff --git a/src/expr.c b/src/expr.c
7d97b9
index b081ca2..5f98f76 100644
7d97b9
--- a/src/expr.c
7d97b9
+++ b/src/expr.c
7d97b9
@@ -4901,18 +4901,25 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
7d97b9
     case TK_LT:
7d97b9
     case TK_LE:
7d97b9
     case TK_GT:
7d97b9
-    case TK_GE:
7d97b9
+    case TK_GE: {
7d97b9
+      Expr *pLeft = pExpr->pLeft;
7d97b9
+      Expr *pRight = pExpr->pRight;
7d97b9
       testcase( pExpr->op==TK_EQ );
7d97b9
       testcase( pExpr->op==TK_NE );
7d97b9
       testcase( pExpr->op==TK_LT );
7d97b9
       testcase( pExpr->op==TK_LE );
7d97b9
       testcase( pExpr->op==TK_GT );
7d97b9
       testcase( pExpr->op==TK_GE );
7d97b9
-      if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->y.pTab))
7d97b9
-       || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->y.pTab))
7d97b9
+      /* The y.pTab=0 assignment in wherecode.c always happens after the
7d97b9
+      ** impliesNotNullRow() test */
7d97b9
+      if( (pLeft->op==TK_COLUMN && ALWAYS(pLeft->y.pTab!=0)
7d97b9
+                               && IsVirtual(pLeft->y.pTab))
7d97b9
+       || (pRight->op==TK_COLUMN && ALWAYS(pRight->y.pTab!=0)
7d97b9
+                               && IsVirtual(pRight->y.pTab))
7d97b9
       ){
7d97b9
        return WRC_Prune;
7d97b9
       }
7d97b9
+    }
7d97b9
     default:
7d97b9
       return WRC_Continue;
7d97b9
   }
7d97b9
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
7d97b9
index 051aa40..5f5f3cc 100644
7d97b9
--- a/src/sqliteInt.h
7d97b9
+++ b/src/sqliteInt.h
7d97b9
@@ -2014,8 +2014,11 @@ struct Table {
7d97b9
 */
7d97b9
 #ifndef SQLITE_OMIT_VIRTUALTABLE
7d97b9
 #  define IsVirtual(X)      ((X)->nModuleArg)
7d97b9
+#  define ExprIsVtab(X)  \
7d97b9
+              ((X)->op==TK_COLUMN && (X)->y.pTab!=0 && (X)->y.pTab->nModuleArg)
7d97b9
 #else
7d97b9
 #  define IsVirtual(X)      0
7d97b9
+#  define ExprIsVtab(X)     0
7d97b9
 #endif
7d97b9
 
7d97b9
 /*
7d97b9
diff --git a/src/whereexpr.c b/src/whereexpr.c
7d97b9
index dbb7f0d..9d2813a 100644
7d97b9
--- a/src/whereexpr.c
7d97b9
+++ b/src/whereexpr.c
7d97b9
@@ -382,7 +382,8 @@ static int isAuxiliaryVtabOperator(
7d97b9
     **       MATCH(expression,vtab_column)
7d97b9
     */
7d97b9
     pCol = pList->a[1].pExpr;
7d97b9
-    if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){
7d97b9
+    testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 );
7d97b9
+    if( ExprIsVtab(pCol) ){
7d97b9
       for(i=0; i
7d97b9
         if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
7d97b9
           *peOp2 = aOp[i].eOp2;
7d97b9
@@ -404,7 +405,8 @@ static int isAuxiliaryVtabOperator(
7d97b9
     ** with function names in an arbitrary case.
7d97b9
     */
7d97b9
     pCol = pList->a[0].pExpr;
7d97b9
-    if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){
7d97b9
+    testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 );
7d97b9
+    if( ExprIsVtab(pCol) ){
7d97b9
       sqlite3_vtab *pVtab;
7d97b9
       sqlite3_module *pMod;
7d97b9
       void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**);
7d97b9
@@ -427,10 +429,12 @@ static int isAuxiliaryVtabOperator(
7d97b9
     int res = 0;
7d97b9
     Expr *pLeft = pExpr->pLeft;
7d97b9
     Expr *pRight = pExpr->pRight;
7d97b9
-    if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->y.pTab) ){
7d97b9
+    testcase( pLeft->op==TK_COLUMN && pLeft->y.pTab==0 );
7d97b9
+    if( ExprIsVtab(pLeft) ){
7d97b9
       res++;
7d97b9
     }
7d97b9
-    if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->y.pTab) ){
7d97b9
+    testcase( pRight && pRight->op==TK_COLUMN && pRight->y.pTab==0 );
7d97b9
+    if( pRight && ExprIsVtab(pRight) ){
7d97b9
       res++;
7d97b9
       SWAP(Expr*, pLeft, pRight);
7d97b9
     }
7d97b9
-- 
7d97b9
2.24.1
7d97b9