From ec79664bd4ed9d330ba0f4c01c0682aa6ed479b8 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Jul 28 2020 13:49:02 +0000 Subject: import sqlite-3.26.0-10.el8 --- diff --git a/SOURCES/sqlite-3.26-CVE-2019-13752.patch b/SOURCES/sqlite-3.26-CVE-2019-13752.patch new file mode 100644 index 0000000..b298a21 --- /dev/null +++ b/SOURCES/sqlite-3.26-CVE-2019-13752.patch @@ -0,0 +1,149 @@ +From 92b243715eea17997ed9707540757d0667ad9eb2 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +Date: Thu, 2 Jan 2020 09:54:41 +0100 +Subject: [PATCH] Improved detection of corrupt shadow tables in FTS3. Enable + the debugging special-inserts for FTS3 for both SQLITE_DEBUG and SQLITE_TEST. + +Resolves: CVE-2019-13752 +--- + ext/fts3/fts3.c | 2 +- + ext/fts3/fts3Int.h | 2 +- + ext/fts3/fts3_write.c | 42 +++++++++++++++++++++++++++--------------- + 3 files changed, 29 insertions(+), 17 deletions(-) + +diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c +index f6fb931..6d6bd46 100644 +--- a/ext/fts3/fts3.c ++++ b/ext/fts3/fts3.c +@@ -4304,7 +4304,7 @@ static int fts3EvalPhraseStart(Fts3Cursor *pCsr, int bOptOk, Fts3Phrase *p){ + int bIncrOk = (bOptOk + && pCsr->bDesc==pTab->bDescIdx + && p->nToken<=MAX_INCR_PHRASE_TOKENS && p->nToken>0 +-#ifdef SQLITE_TEST ++#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + && pTab->bNoIncrDoclist==0 + #endif + ); +diff --git a/ext/fts3/fts3Int.h b/ext/fts3/fts3Int.h +index 077bad7..6f5a7a0 100644 +--- a/ext/fts3/fts3Int.h ++++ b/ext/fts3/fts3Int.h +@@ -283,7 +283,7 @@ struct Fts3Table { + int mxSavepoint; /* Largest valid xSavepoint integer */ + #endif + +-#ifdef SQLITE_TEST ++#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + /* True to disable the incremental doclist optimization. This is controled + ** by special insert command 'test-no-incr-doclist'. */ + int bNoIncrDoclist; +diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c +index 8fc6589..ee668aa 100644 +--- a/ext/fts3/fts3_write.c ++++ b/ext/fts3/fts3_write.c +@@ -23,7 +23,7 @@ + #include + #include + #include +- ++#include + + #define FTS_MAX_APPENDABLE_HEIGHT 16 + +@@ -2021,6 +2021,11 @@ static int fts3NodeAddTerm( + nPrefix = fts3PrefixCompress(pTree->zTerm, pTree->nTerm, zTerm, nTerm); + nSuffix = nTerm-nPrefix; + ++ /* If nSuffix is zero or less, then zTerm/nTerm must be a prefix of ++ ** pWriter->zTerm/pWriter->nTerm. i.e. must be equal to or less than when ++ ** compared with BINARY collation. This indicates corruption. */ ++ if( nSuffix<=0 ) return FTS_CORRUPT_VTAB; ++ + nReq += sqlite3Fts3VarintLen(nPrefix)+sqlite3Fts3VarintLen(nSuffix)+nSuffix; + if( nReq<=p->nNodeSize || !pTree->zTerm ){ + +@@ -2309,9 +2314,11 @@ static int fts3SegWriterAdd( + /* Append the prefix-compressed term and doclist to the buffer. */ + nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nPrefix); + nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nSuffix); ++ assert( nSuffix>0 ); + memcpy(&pWriter->aData[nData], &zTerm[nPrefix], nSuffix); + nData += nSuffix; + nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nDoclist); ++ assert( nDoclist>0 ); + memcpy(&pWriter->aData[nData], aDoclist, nDoclist); + pWriter->nData = nData + nDoclist; + +@@ -2331,6 +2338,7 @@ static int fts3SegWriterAdd( + pWriter->zTerm = zNew; + } + assert( pWriter->zTerm==pWriter->zMalloc ); ++ assert( nTerm>0 ); + memcpy(pWriter->zTerm, zTerm, nTerm); + }else{ + pWriter->zTerm = (char *)zTerm; +@@ -2639,6 +2647,7 @@ static int fts3MsrBufferData( + pMsr->aBuffer = pNew; + } + ++ assert( nList>0 ); + memcpy(pMsr->aBuffer, pList, nList); + return SQLITE_OK; + } +@@ -3821,6 +3830,7 @@ static int fts3IncrmergePush( + ** be added to. */ + nPrefix = fts3PrefixCompress(pNode->key.a, pNode->key.n, zTerm, nTerm); + nSuffix = nTerm - nPrefix; ++ if( NEVER(nSuffix<=0) ) return FTS_CORRUPT_VTAB; + nSpace = sqlite3Fts3VarintLen(nPrefix); + nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; + +@@ -5300,7 +5310,7 @@ static int fts3DoIntegrityCheck( + ** meaningful value to insert is the text 'optimize'. + */ + static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){ +- int rc; /* Return Code */ ++ int rc = SQLITE_ERROR; /* Return Code */ + const char *zVal = (const char *)sqlite3_value_text(pVal); + int nVal = sqlite3_value_bytes(pVal); + +@@ -5316,21 +5326,23 @@ static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){ + rc = fts3DoIncrmerge(p, &zVal[6]); + }else if( nVal>10 && 0==sqlite3_strnicmp(zVal, "automerge=", 10) ){ + rc = fts3DoAutoincrmerge(p, &zVal[10]); +-#ifdef SQLITE_TEST +- }else if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){ +- p->nNodeSize = atoi(&zVal[9]); +- rc = SQLITE_OK; +- }else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 9) ){ +- p->nMaxPendingData = atoi(&zVal[11]); +- rc = SQLITE_OK; +- }else if( nVal>21 && 0==sqlite3_strnicmp(zVal, "test-no-incr-doclist=", 21) ){ +- p->bNoIncrDoclist = atoi(&zVal[21]); +- rc = SQLITE_OK; +-#endif ++#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + }else{ +- rc = SQLITE_ERROR; ++ int v; ++ if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){ ++ v = atoi(&zVal[9]); ++ if( v>=24 && v<=p->nPgsz-35 ) p->nNodeSize = v; ++ rc = SQLITE_OK; ++ }else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 9) ){ ++ v = atoi(&zVal[11]); ++ if( v>=64 && v<=FTS3_MAX_PENDING_DATA ) p->nMaxPendingData = v; ++ rc = SQLITE_OK; ++ }else if( nVal>21 && 0==sqlite3_strnicmp(zVal,"test-no-incr-doclist=",21) ){ ++ p->bNoIncrDoclist = atoi(&zVal[21]); ++ rc = SQLITE_OK; ++ } ++#endif + } +- + return rc; + } + +-- +2.19.1 + diff --git a/SOURCES/sqlite-3.26-CVE-2019-13753.patch b/SOURCES/sqlite-3.26-CVE-2019-13753.patch new file mode 100644 index 0000000..cc21b6d --- /dev/null +++ b/SOURCES/sqlite-3.26-CVE-2019-13753.patch @@ -0,0 +1,25 @@ +From 0b3ba64a9c7f785f6b3f1c1c15c5b0f1e41e0461 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +Date: Thu, 2 Jan 2020 10:25:58 +0100 +Subject: [PATCH] Remove a reachable NEVER() in FTS3. + +--- + ext/fts3/fts3_write.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c +index ee668aa..8624329 100644 +--- a/ext/fts3/fts3_write.c ++++ b/ext/fts3/fts3_write.c +@@ -3830,7 +3830,7 @@ static int fts3IncrmergePush( + ** be added to. */ + nPrefix = fts3PrefixCompress(pNode->key.a, pNode->key.n, zTerm, nTerm); + nSuffix = nTerm - nPrefix; +- if( NEVER(nSuffix<=0) ) return FTS_CORRUPT_VTAB; ++ if(nSuffix<=0 ) return FTS_CORRUPT_VTAB; + nSpace = sqlite3Fts3VarintLen(nPrefix); + nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; + +-- +2.19.1 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2019-13734.patch b/SOURCES/sqlite-3.26.0-CVE-2019-13734.patch new file mode 100644 index 0000000..9cb8e4c --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2019-13734.patch @@ -0,0 +1,107 @@ +From 5f4ce30babee8085fc36680c6103d9a06be49ef7 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +Date: Thu, 2 Jan 2020 11:58:39 +0100 +Subject: [PATCH] More improvements to shadow table corruption detection in + FTS3. + +--- + ext/fts3/fts3.c | 4 ++++ + ext/fts3/fts3Int.h | 10 ++++++++++ + ext/fts3/fts3_write.c | 14 +++++++++++--- + 3 files changed, 25 insertions(+), 3 deletions(-) + +diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c +index 6d6bd46..84fc8a5 100644 +--- a/ext/fts3/fts3.c ++++ b/ext/fts3/fts3.c +@@ -1460,6 +1460,10 @@ static int fts3InitVtab( + fts3DatabasePageSize(&rc, p); + p->nNodeSize = p->nPgsz-35; + ++#if defined(SQLITE_DEBUG)||defined(SQLITE_TEST) ++ p->nMergeCount = FTS3_MERGE_COUNT; ++#endif ++ + /* Declare the table schema to SQLite. */ + fts3DeclareVtab(&rc, p); + +diff --git a/ext/fts3/fts3Int.h b/ext/fts3/fts3Int.h +index 6f5a7a0..0d1b491 100644 +--- a/ext/fts3/fts3Int.h ++++ b/ext/fts3/fts3Int.h +@@ -287,9 +287,19 @@ struct Fts3Table { + /* True to disable the incremental doclist optimization. This is controled + ** by special insert command 'test-no-incr-doclist'. */ + int bNoIncrDoclist; ++ ++ /* Number of segments in a level */ ++ int nMergeCount; + #endif + }; + ++/* Macro to find the number of segments to merge */ ++#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) ++# define MergeCount(P) ((P)->nMergeCount) ++#else ++# define MergeCount(P) FTS3_MERGE_COUNT ++#endif ++ + /* + ** When the core wants to read from the virtual table, it creates a + ** virtual table cursor (an instance of the following structure) using +diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c +index 8624329..d57d265 100644 +--- a/ext/fts3/fts3_write.c ++++ b/ext/fts3/fts3_write.c +@@ -1152,7 +1152,7 @@ static int fts3AllocateSegdirIdx( + ** segment and allocate (newly freed) index 0 at level iLevel. Otherwise, + ** if iNext is less than FTS3_MERGE_COUNT, allocate index iNext. + */ +- if( iNext>=FTS3_MERGE_COUNT ){ ++ if( iNext>=MergeCount(p) ){ + fts3LogMerge(16, getAbsoluteLevel(p, iLangid, iIndex, iLevel)); + rc = fts3SegmentMerge(p, iLangid, iIndex, iLevel); + *piIdx = 0; +@@ -4259,6 +4259,10 @@ static int fts3IncrmergeLoad( + int i; + int nHeight = (int)aRoot[0]; + NodeWriter *pNode; ++ if( nHeight<1 || nHeight>FTS_MAX_APPENDABLE_HEIGHT ){ ++ sqlite3_reset(pSelect); ++ return FTS_CORRUPT_VTAB; ++ } + + pWriter->nLeafEst = (int)((iEnd - iStart) + 1)/FTS_MAX_APPENDABLE_HEIGHT; + pWriter->iStart = iStart; +@@ -5007,7 +5011,7 @@ static int fts3DoIncrmerge( + const char *zParam /* Nul-terminated string containing "A,B" */ + ){ + int rc; +- int nMin = (FTS3_MERGE_COUNT / 2); ++ int nMin = (MergeCount(p) / 2); + int nMerge = 0; + const char *z = zParam; + +@@ -5052,7 +5056,7 @@ static int fts3DoAutoincrmerge( + int rc = SQLITE_OK; + sqlite3_stmt *pStmt = 0; + p->nAutoincrmerge = fts3Getint(&zParam); +- if( p->nAutoincrmerge==1 || p->nAutoincrmerge>FTS3_MERGE_COUNT ){ ++ if( p->nAutoincrmerge==1 || p->nAutoincrmerge>MergeCount(p) ){ + p->nAutoincrmerge = 8; + } + if( !p->bHasStat ){ +@@ -5340,6 +5344,10 @@ static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){ + }else if( nVal>21 && 0==sqlite3_strnicmp(zVal,"test-no-incr-doclist=",21) ){ + p->bNoIncrDoclist = atoi(&zVal[21]); + rc = SQLITE_OK; ++ }else if( nVal>11 && 0==sqlite3_strnicmp(zVal,"mergecount=",11) ){ ++ v = atoi(&zVal[11]); ++ if( v>=4 && v<=FTS3_MERGE_COUNT && (v&1)==0 ) p->nMergeCount = v; ++ rc = SQLITE_OK; + } + #endif + } +-- +2.19.1 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2019-16168.patch b/SOURCES/sqlite-3.26.0-CVE-2019-16168.patch new file mode 100644 index 0000000..d968605 --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2019-16168.patch @@ -0,0 +1,65 @@ +From ab17169870e985b062e520ecf95e6c79ad784f38 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +Date: Thu, 23 Apr 2020 11:25:13 +0200 +Subject: [PATCH] fixed CVE-2019-16168 (rhbz#1826897) + +--- + src/analyze.c | 4 +++- + src/where.c | 1 + + test/analyzeC.test | 13 +++++++++++++ + 3 files changed, 17 insertions(+), 1 deletion(-) + +diff --git a/src/analyze.c b/src/analyze.c +index 5075b57..e47c0f5 100644 +--- a/src/analyze.c ++++ b/src/analyze.c +@@ -1497,7 +1497,9 @@ static void decodeIntArray( + if( sqlite3_strglob("unordered*", z)==0 ){ + pIndex->bUnordered = 1; + }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){ +- pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3)); ++ int sz = sqlite3Atoi(z+3); ++ if( sz<2 ) sz = 2; ++ pIndex->szIdxRow = sqlite3LogEst(sz); + }else if( sqlite3_strglob("noskipscan*", z)==0 ){ + pIndex->noSkipScan = 1; + } +diff --git a/src/where.c b/src/where.c +index 8e01660..1a4fa51 100644 +--- a/src/where.c ++++ b/src/where.c +@@ -2655,6 +2655,7 @@ static int whereLoopAddBtreeIndex( + ** it to pNew->rRun, which is currently set to the cost of the index + ** seek only. Then, if this is a non-covering index, add the cost of + ** visiting the rows in the main table. */ ++ assert( pSrc->pTab->szTabRow>0 ); + rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; + pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx); + if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ +diff --git a/test/analyzeC.test b/test/analyzeC.test +index 02faa9c..3595c9d 100644 +--- a/test/analyzeC.test ++++ b/test/analyzeC.test +@@ -132,6 +132,19 @@ do_execsql_test 4.3 { + SELECT count(a) FROM t1; + } {/.*INDEX t1ca.*/} + ++# 2019-08-15. ++# Ticket https://www.sqlite.org/src/tktview/e4598ecbdd18bd82945f602901 ++# The sz=N parameter in the sqlite_stat1 table needs to have a value of ++# 2 or more to avoid a division by zero in the query planner. ++# ++do_execsql_test 4.4 { ++ DROP TABLE IF EXISTS t44; ++ CREATE TABLE t44(a PRIMARY KEY); ++ INSERT INTO sqlite_stat1 VALUES('t44',null,'sz=0'); ++ ANALYZE sqlite_master; ++ SELECT 0 FROM t44 WHERE a IN(1,2,3); ++} {} ++ + + # The sz=NNN parameter works even if there is other extraneous text + # in the sqlite_stat1.stat column. +-- +2.24.1 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2019-19923.patch b/SOURCES/sqlite-3.26.0-CVE-2019-19923.patch new file mode 100644 index 0000000..ea95b19 --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2019-19923.patch @@ -0,0 +1,67 @@ +From 7d47517d579601bb6e59e33bf0896f0ed36aa0aa Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +Date: Mon, 20 Jan 2020 09:34:41 +0100 +Subject: [PATCH] Continue to back away from the LEFT JOIN optimization of + check-in + +by disallowing query flattening if the outer query is DISTINCT. Without this fix, +if an index scan is run on the table within the view on the right-hand side of the +LEFT JOIN, stale result registers might be accessed yielding incorrect results, +and/or an OP_IfNullRow opcode might be invoked on the un-opened table, resulting +in a NULL-pointer dereference. This problem was found by the Yongheng and Rui fuzzer. +--- + src/select.c | 8 ++++++-- + test/join.test | 13 +++++++++++++ + 2 files changed, 19 insertions(+), 2 deletions(-) + +diff --git a/src/select.c b/src/select.c +index c60ff27..0205a08 100644 +--- a/src/select.c ++++ b/src/select.c +@@ -3569,6 +3569,7 @@ static void substSelect( + ** (3b) the FROM clause of the subquery may not contain a virtual + ** table and + ** (3c) the outer query may not be an aggregate. ++** (3d) the outer query may not be DISTINCT. + ** + ** (4) The subquery can not be DISTINCT. + ** +@@ -3765,8 +3766,11 @@ static int flattenSubquery( + */ + if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){ + isLeftJoin = 1; +- if( pSubSrc->nSrc>1 || isAgg || IsVirtual(pSubSrc->a[0].pTab) ){ +- /* (3a) (3c) (3b) */ ++ if( pSubSrc->nSrc>1 /* (3a) */ ++ || isAgg /* (3b) */ ++ || IsVirtual(pSubSrc->a[0].pTab) /* (3c) */ ++ || (p->selFlags & SF_Distinct)!=0 /* (3d) */ ++ ){ + return 0; + } + } +diff --git a/test/join.test b/test/join.test +index 8c6f463..8c6a53d 100644 +--- a/test/join.test ++++ b/test/join.test +@@ -844,4 +844,17 @@ do_execsql_test join-15.110 { + ORDER BY a1, a2, a3, a4, a5; + } {1 {} {} {} {} 1 11 {} {} {} 1 12 {} {} {} 1 12 121 {} {} 1 13 {} {} {}} + ++# 2019-12-18 problem with a LEFT JOIN where the RHS is a view. ++# Detected by Yongheng and Rui. ++# Follows from the optimization attempt of check-in 41c27bc0ff1d3135 ++# on 2017-04-18 ++# ++reset_db ++do_execsql_test join-22.10 { ++ CREATE TABLE t0(a, b); ++ CREATE INDEX t0a ON t0(a); ++ INSERT INTO t0 VALUES(10,10),(10,11),(10,12); ++ SELECT DISTINCT c FROM t0 LEFT JOIN (SELECT a+1 AS c FROM t0) ORDER BY c ; ++} {11} ++ + finish_test +-- +2.19.1 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2019-19924.patch b/SOURCES/sqlite-3.26.0-CVE-2019-19924.patch new file mode 100644 index 0000000..df29238 --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2019-19924.patch @@ -0,0 +1,60 @@ +From 6b06304c2a46e17a6dc4402eadc75ccac24da893 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +Date: Fri, 17 Jan 2020 13:03:54 +0100 +Subject: [PATCH] When an error occurs while rewriting the parser tree for + window functions in the sqlite3WindowRewrite() routine, make sure that + pParse->nErr is set, and make sure that this shuts down any subsequent code + generation that might depend on the transformations that were implemented. + This fixes a problem discovered by the Yongheng and Rui fuzzer. + +--- + src/expr.c | 1 + + src/vdbeaux.c | 3 ++- + src/window.c | 5 +++++ + 3 files changed, 8 insertions(+), 1 deletion(-) + +diff --git a/src/expr.c b/src/expr.c +index d4eb9de..b081ca2 100644 +--- a/src/expr.c ++++ b/src/expr.c +@@ -344,6 +344,7 @@ static int codeCompare( + int addr; + CollSeq *p4; + ++ if( pParse->nErr ) return 0; + p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight); + p5 = binaryCompareP5(pLeft, pRight, jumpIfNull); + addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1, +diff --git a/src/vdbeaux.c b/src/vdbeaux.c +index f1496a3..b74141b 100644 +--- a/src/vdbeaux.c ++++ b/src/vdbeaux.c +@@ -1160,7 +1160,8 @@ void sqlite3VdbeSetP4KeyInfo(Parse *pParse, Index *pIdx){ + */ + static void vdbeVComment(Vdbe *p, const char *zFormat, va_list ap){ + assert( p->nOp>0 || p->aOp==0 ); +- assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed ); ++ assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed ++ || p->pParse->nErr>0 ); + if( p->nOp ){ + assert( p->aOp ); + sqlite3DbFree(p->db, p->aOp[p->nOp-1].zComment); +diff --git a/src/window.c b/src/window.c +index f5deae9..56c0145 100644 +--- a/src/window.c ++++ b/src/window.c +@@ -843,6 +843,11 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){ + if( db->mallocFailed ) rc = SQLITE_NOMEM; + } + ++ if( rc && pParse->nErr==0 ){ ++ assert( pParse->db->mallocFailed ); ++ return SQLITE_NOMEM; ++ } ++ + return rc; + } + +-- +2.19.1 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2019-19925.patch b/SOURCES/sqlite-3.26.0-CVE-2019-19925.patch new file mode 100644 index 0000000..bed5060 --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2019-19925.patch @@ -0,0 +1,50 @@ +From 1986c6384122947b10804cbc5c4d7af85e097404 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +Date: Mon, 20 Jan 2020 10:09:55 +0100 +Subject: [PATCH] Fix the zipfile extension so that INSERT works even if the + pathname of + +the file being inserted is a NULL. Bug discovered by the +Yongheng and Rui fuzzer. +--- + ext/misc/zipfile.c | 1 + + test/zipfile.test | 13 +++++++++++++ + 2 files changed, 14 insertions(+) + +diff --git a/ext/misc/zipfile.c b/ext/misc/zipfile.c +index e57dc38..6f48d0f 100644 +--- a/ext/misc/zipfile.c ++++ b/ext/misc/zipfile.c +@@ -1618,6 +1618,7 @@ static int zipfileUpdate( + + if( rc==SQLITE_OK ){ + zPath = (const char*)sqlite3_value_text(apVal[2]); ++ if( zPath==0 ) zPath = ""; + nPath = (int)strlen(zPath); + mTime = zipfileGetTime(apVal[4]); + } +diff --git a/test/zipfile.test b/test/zipfile.test +index 2bab066..5bca10b 100644 +--- a/test/zipfile.test ++++ b/test/zipfile.test +@@ -795,4 +795,17 @@ if {$tcl_platform(platform)!="windows"} { + } {. ./x1.txt ./x2.txt} + } + ++# 2019-12-18 Yongheng and Rui fuzzer ++# ++do_execsql_test 13.10 { ++ DROP TABLE IF EXISTS t0; ++ DROP TABLE IF EXISTS t1; ++ CREATE TABLE t0(a,b,c,d,e,f,g); ++ REPLACE INTO t0(c,b,f) VALUES(10,10,10); ++ CREATE VIRTUAL TABLE t1 USING zipfile('h.zip'); ++ REPLACE INTO t1 SELECT * FROM t0; ++ SELECT quote(name),quote(mode),quote(mtime),quote(sz),quote(rawdata), ++ quote(data),quote(method) FROM t1; ++} {'' 10 10 2 X'3130' X'3130' 0} ++ + finish_test +-- +2.19.1 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2019-19959.patch b/SOURCES/sqlite-3.26.0-CVE-2019-19959.patch new file mode 100644 index 0000000..ec1965c --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2019-19959.patch @@ -0,0 +1,63 @@ +From 16c5290d72cb8059e9dfe545613183b850fc44e4 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +Date: Mon, 20 Jan 2020 10:26:35 +0100 +Subject: [PATCH] Fix the zipfile() function in the zipfile extension so that + it is able to + +deal with goofy filenames that contain embedded zeros. +--- + ext/misc/zipfile.c | 4 ++-- + test/zipfile.test | 13 +++++++++++++ + 2 files changed, 15 insertions(+), 2 deletions(-) + +diff --git a/ext/misc/zipfile.c b/ext/misc/zipfile.c +index 6f48d0f..e6141ef 100644 +--- a/ext/misc/zipfile.c ++++ b/ext/misc/zipfile.c +@@ -1632,7 +1632,7 @@ static int zipfileUpdate( + zFree = sqlite3_mprintf("%s/", zPath); + if( zFree==0 ){ rc = SQLITE_NOMEM; } + zPath = (const char*)zFree; +- nPath++; ++ nPath = (int)strlen(zPath); + } + } + +@@ -2033,11 +2033,11 @@ void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){ + }else{ + if( zName[nName-1]!='/' ){ + zName = zFree = sqlite3_mprintf("%s/", zName); +- nName++; + if( zName==0 ){ + rc = SQLITE_NOMEM; + goto zipfile_step_out; + } ++ nName = (int)strlen(zName); + }else{ + while( nName>1 && zName[nName-2]=='/' ) nName--; + } +diff --git a/test/zipfile.test b/test/zipfile.test +index 5bca10b..e4b8088 100644 +--- a/test/zipfile.test ++++ b/test/zipfile.test +@@ -808,4 +808,17 @@ do_execsql_test 13.10 { + quote(data),quote(method) FROM t1; + } {'' 10 10 2 X'3130' X'3130' 0} + ++# 2019-12-23 Yongheng and Rui fuzzer ++# Run using valgrind to see the problem. ++# ++do_execsql_test 14.10 { ++ DROP TABLE t1; ++ CREATE TABLE t1(x char); ++ INSERT INTO t1(x) VALUES('1'); ++ INSERT INTO t1(x) SELECT zipfile(x, 'xyz') FROM t1; ++ INSERT INTO t1(x) SELECT zipfile(x, 'uvw') FROM t1; ++ SELECT count(*) FROM t1; ++ PRAGMA integrity_check; ++} {3 ok} ++ + finish_test +-- +2.19.1 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2019-20218.patch b/SOURCES/sqlite-3.26.0-CVE-2019-20218.patch new file mode 100644 index 0000000..cda14f1 --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2019-20218.patch @@ -0,0 +1,26 @@ +From 8fd3688e01f5839120d7477ca94e013f5809edcf Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +Date: Tue, 24 Mar 2020 11:33:04 +0100 +Subject: [PATCH] Do not attempt to unwind the WITH stack in the Parse object + following an error. + +--- + src/select.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/select.c b/src/select.c +index 0205a08..bbd13a4 100644 +--- a/src/select.c ++++ b/src/select.c +@@ -4910,7 +4910,7 @@ static int selectExpander(Walker *pWalker, Select *p){ + + /* Process NATURAL keywords, and ON and USING clauses of joins. + */ +- if( db->mallocFailed || sqliteProcessJoin(pParse, p) ){ ++ if( pParse->nErr || db->mallocFailed || sqliteProcessJoin(pParse, p) ){ + return WRC_Abort; + } + +-- +2.24.1 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2019-5018.patch b/SOURCES/sqlite-3.26.0-CVE-2019-5018.patch new file mode 100644 index 0000000..fde7e0a --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2019-5018.patch @@ -0,0 +1,281 @@ +Subject: [PATCH] Prevent aliases of window functions expressions from being + used as arguments to aggregate or other window functions. + +--- + src/resolve.c | 21 ++++++--- + src/sqliteInt.h | 2 + + test/windowerr.tcl | 59 ++++++++++++++++++++++++++ + test/windowerr.test | 99 ++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 176 insertions(+), 5 deletions(-) + create mode 100644 test/windowerr.tcl + create mode 100644 test/windowerr.test + +diff --git a/src/resolve.c b/src/resolve.c +index 0c7dfc0..cdcf4d9 100644 +--- a/src/resolve.c ++++ b/src/resolve.c +@@ -436,6 +436,10 @@ static int lookupName( + sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs); + return WRC_Abort; + } ++ if( (pNC->ncFlags&NC_AllowWin)==0 && ExprHasProperty(pOrig, EP_Win) ){ ++ sqlite3ErrorMsg(pParse, "misuse of aliased window function %s",zAs); ++ return WRC_Abort; ++ } + if( sqlite3ExprVectorSize(pOrig)!=1 ){ + sqlite3ErrorMsg(pParse, "row value misused"); + return WRC_Abort; +@@ -707,6 +711,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ + const char *zId; /* The function name. */ + FuncDef *pDef; /* Information about the function */ + u8 enc = ENC(pParse->db); /* The database encoding */ ++ int savedAllowFlags = (pNC->ncFlags & (NC_AllowAgg | NC_AllowWin)); + + assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); + zId = pExpr->u.zToken; +@@ -828,8 +833,11 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ + pNC->nErr++; + } + if( is_agg ){ ++ /* Window functions may not be arguments of aggregate functions. ++ ** Or arguments of other window functions. But aggregate functions ++ ** may be arguments for window functions. */ + #ifndef SQLITE_OMIT_WINDOWFUNC +- pNC->ncFlags &= ~(pExpr->y.pWin ? NC_AllowWin : NC_AllowAgg); ++ pNC->ncFlags &= ~(NC_AllowWin | (!pExpr->y.pWin ? NC_AllowAgg : 0)); + #else + pNC->ncFlags &= ~NC_AllowAgg; + #endif +@@ -850,7 +858,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ + pExpr->y.pWin->pNextWin = pSel->pWin; + pSel->pWin = pExpr->y.pWin; + } +- pNC->ncFlags |= NC_AllowWin; ++ pNC->ncFlags |= NC_HasWin; + }else + #endif /* SQLITE_OMIT_WINDOWFUNC */ + { +@@ -868,8 +876,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ + pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX); + + } +- pNC->ncFlags |= NC_AllowAgg; + } ++ pNC->ncFlags |= savedAllowFlags; + } + /* FIX ME: Compute pExpr->affinity based on the expected return + ** type of the function +@@ -1573,8 +1581,8 @@ int sqlite3ResolveExprNames( + Walker w; + + if( pExpr==0 ) return SQLITE_OK; +- savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg); +- pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg); ++ savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin); ++ pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin); + w.pParse = pNC->pParse; + w.xExprCallback = resolveExprStep; + w.xSelectCallback = resolveSelectStep; +@@ -1593,6 +1601,9 @@ int sqlite3ResolveExprNames( + if( pNC->ncFlags & NC_HasAgg ){ + ExprSetProperty(pExpr, EP_Agg); + } ++ if( pNC->ncFlags & NC_HasWin ){ ++ ExprSetProperty(pExpr, EP_Win); ++ } + pNC->ncFlags |= savedHasAgg; + return pNC->nErr>0 || w.pParse->nErr>0; + } +diff --git a/src/sqliteInt.h b/src/sqliteInt.h +index 5f5f3cc..b7d3571 100644 +--- a/src/sqliteInt.h ++++ b/src/sqliteInt.h +@@ -2517,6 +2517,7 @@ struct Expr { + #define EP_Alias 0x400000 /* Is an alias for a result set column */ + #define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */ + #define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */ ++#define EP_Win 0x8000000 /* Contains window functions */ + + /* + ** The EP_Propagate mask is a set of properties that automatically propagate +@@ -2773,6 +2774,7 @@ struct NameContext { + #define NC_MinMaxAgg 0x1000 /* min/max aggregates seen. See note above */ + #define NC_Complex 0x2000 /* True if a function or subquery seen */ + #define NC_AllowWin 0x4000 /* Window functions are allowed here */ ++#define NC_HasWin 0x8000 /* One or more window functions seen */ + + /* + ** An instance of the following object describes a single ON CONFLICT +diff --git a/test/windowerr.tcl b/test/windowerr.tcl +new file mode 100644 +index 0000000..80f464d +--- /dev/null ++++ b/test/windowerr.tcl +@@ -0,0 +1,59 @@ ++# 2018 May 19 ++# ++# The author disclaims copyright to this source code. In place of ++# a legal notice, here is a blessing: ++# ++# May you do good and not evil. ++# May you find forgiveness for yourself and forgive others. ++# May you share freely, never taking more than you give. ++# ++#*********************************************************************** ++# ++ ++source [file join [file dirname $argv0] pg_common.tcl] ++ ++#========================================================================= ++ ++start_test windowerr "2019 March 01" ++ifcapable !windowfunc ++ ++execsql_test 1.0 { ++ DROP TABLE IF EXISTS t1; ++ CREATE TABLE t1(a INTEGER, b INTEGER); ++ INSERT INTO t1 VALUES(1, 1); ++ INSERT INTO t1 VALUES(2, 2); ++ INSERT INTO t1 VALUES(3, 3); ++ INSERT INTO t1 VALUES(4, 4); ++ INSERT INTO t1 VALUES(5, 5); ++} ++ ++foreach {tn frame} { ++ 1 "ORDER BY a ROWS BETWEEN -1 PRECEDING AND 1 FOLLOWING" ++ 2 "ORDER BY a ROWS BETWEEN 1 PRECEDING AND -1 FOLLOWING" ++ ++ 3 "ORDER BY a RANGE BETWEEN -1 PRECEDING AND 1 FOLLOWING" ++ 4 "ORDER BY a RANGE BETWEEN 1 PRECEDING AND -1 FOLLOWING" ++ ++ 5 "ORDER BY a GROUPS BETWEEN -1 PRECEDING AND 1 FOLLOWING" ++ 6 "ORDER BY a GROUPS BETWEEN 1 PRECEDING AND -1 FOLLOWING" ++ ++ 7 "ORDER BY a,b RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING" ++ ++ 8 "PARTITION BY a RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING" ++} { ++ errorsql_test 1.$tn " ++ SELECT a, sum(b) OVER ( ++ $frame ++ ) FROM t1 ORDER BY 1 ++ " ++} ++errorsql_test 2.1 { ++ SELECT sum( sum(a) OVER () ) FROM t1; ++} ++ ++errorsql_test 2.2 { ++ SELECT sum(a) OVER () AS xyz FROM t1 ORDER BY sum(xyz); ++} ++ ++ ++finish_test +diff --git a/test/windowerr.test b/test/windowerr.test +new file mode 100644 +index 0000000..97dae64 +--- /dev/null ++++ b/test/windowerr.test +@@ -0,0 +1,99 @@ ++# 2019 March 01 ++# ++# The author disclaims copyright to this source code. In place of ++# a legal notice, here is a blessing: ++# ++# May you do good and not evil. ++# May you find forgiveness for yourself and forgive others. ++# May you share freely, never taking more than you give. ++# ++#*********************************************************************** ++# This file implements regression tests for SQLite library. ++# ++ ++#################################################### ++# DO NOT EDIT! THIS FILE IS AUTOMATICALLY GENERATED! ++#################################################### ++ ++set testdir [file dirname $argv0] ++source $testdir/tester.tcl ++set testprefix windowerr ++ ++ifcapable !windowfunc { finish_test ; return } ++do_execsql_test 1.0 { ++ DROP TABLE IF EXISTS t1; ++ CREATE TABLE t1(a INTEGER, b INTEGER); ++ INSERT INTO t1 VALUES(1, 1); ++ INSERT INTO t1 VALUES(2, 2); ++ INSERT INTO t1 VALUES(3, 3); ++ INSERT INTO t1 VALUES(4, 4); ++ INSERT INTO t1 VALUES(5, 5); ++} {} ++ ++# PG says ERROR: frame starting offset must not be negative ++do_test 1.1 { catch { execsql { ++ SELECT a, sum(b) OVER ( ++ ORDER BY a ROWS BETWEEN -1 PRECEDING AND 1 FOLLOWING ++ ) FROM t1 ORDER BY 1 ++} } } 1 ++ ++# PG says ERROR: frame ending offset must not be negative ++do_test 1.2 { catch { execsql { ++ SELECT a, sum(b) OVER ( ++ ORDER BY a ROWS BETWEEN 1 PRECEDING AND -1 FOLLOWING ++ ) FROM t1 ORDER BY 1 ++} } } 1 ++ ++# PG says ERROR: invalid preceding or following size in window function ++do_test 1.3 { catch { execsql { ++ SELECT a, sum(b) OVER ( ++ ORDER BY a RANGE BETWEEN -1 PRECEDING AND 1 FOLLOWING ++ ) FROM t1 ORDER BY 1 ++} } } 1 ++ ++# PG says ERROR: invalid preceding or following size in window function ++do_test 1.4 { catch { execsql { ++ SELECT a, sum(b) OVER ( ++ ORDER BY a RANGE BETWEEN 1 PRECEDING AND -1 FOLLOWING ++ ) FROM t1 ORDER BY 1 ++} } } 1 ++ ++# PG says ERROR: frame starting offset must not be negative ++do_test 1.5 { catch { execsql { ++ SELECT a, sum(b) OVER ( ++ ORDER BY a GROUPS BETWEEN -1 PRECEDING AND 1 FOLLOWING ++ ) FROM t1 ORDER BY 1 ++} } } 1 ++ ++# PG says ERROR: frame ending offset must not be negative ++do_test 1.6 { catch { execsql { ++ SELECT a, sum(b) OVER ( ++ ORDER BY a GROUPS BETWEEN 1 PRECEDING AND -1 FOLLOWING ++ ) FROM t1 ORDER BY 1 ++} } } 1 ++ ++# PG says ERROR: RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column ++do_test 1.7 { catch { execsql { ++ SELECT a, sum(b) OVER ( ++ ORDER BY a,b RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING ++ ) FROM t1 ORDER BY 1 ++} } } 1 ++ ++# PG says ERROR: RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column ++do_test 1.8 { catch { execsql { ++ SELECT a, sum(b) OVER ( ++ PARTITION BY a RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING ++ ) FROM t1 ORDER BY 1 ++} } } 1 ++ ++# PG says ERROR: aggregate function calls cannot contain window function calls ++do_test 2.1 { catch { execsql { ++ SELECT sum( sum(a) OVER () ) FROM t1; ++} } } 1 ++ ++# PG says ERROR: column "xyz" does not exist ++do_test 2.2 { catch { execsql { ++ SELECT sum(a) OVER () AS xyz FROM t1 ORDER BY sum(xyz); ++} } } 1 ++ ++finish_test +-- +2.24.1 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2020-13630.patch b/SOURCES/sqlite-3.26.0-CVE-2020-13630.patch new file mode 100644 index 0000000..17525f6 --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2020-13630.patch @@ -0,0 +1,88 @@ +Subject: [PATCH] Fix a use-after-free bug in the fts3 snippet() function. + +--- + ext/fts3/fts3.c | 1 + + test/fts3snippet2.test | 59 ++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 60 insertions(+) + create mode 100644 test/fts3snippet2.test + +diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c +index 84fc8a5..9ddd201 100644 +--- a/ext/fts3/fts3.c ++++ b/ext/fts3/fts3.c +@@ -5213,6 +5213,7 @@ static void fts3EvalNextRow( + fts3EvalNextRow(pCsr, pLeft, pRc); + } + } ++ pRight->bEof = pLeft->bEof = 1; + } + } + break; +diff --git a/test/fts3snippet2.test b/test/fts3snippet2.test +new file mode 100644 +index 0000000..607b01e +--- /dev/null ++++ b/test/fts3snippet2.test +@@ -0,0 +1,59 @@ ++# 2020-05-14 ++# ++# The author disclaims copyright to this source code. In place of ++# a legal notice, here is a blessing: ++# ++# May you do good and not evil. ++# May you find forgiveness for yourself and forgive others. ++# May you share freely, never taking more than you give. ++# ++#************************************************************************* ++# ++# The tests in this file test the FTS3 auxillary functions offsets(), ++# snippet() and matchinfo() work. At time of writing, running this file ++# provides full coverage of fts3_snippet.c. ++# ++ ++set testdir [file dirname $argv0] ++source $testdir/tester.tcl ++set testprefix fts3snippet ++ ++# If SQLITE_ENABLE_FTS3 is not defined, omit this file. ++ifcapable !fts3 { finish_test ; return } ++source $testdir/fts3_common.tcl ++ ++set sqlite_fts3_enable_parentheses 1 ++#------------------------------------------------------------------------- ++# Request a snippet from a query with more than 64 phrases. ++# ++reset_db ++do_execsql_test 1.0 { ++ CREATE VIRTUAL TABLE f USING fts3(b); ++ INSERT INTO f VALUES ( x'746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218'); ++} ++ ++do_execsql_test 1.1 { ++ SELECT length(snippet(f))>0 FROM f WHERE b MATCH x'1065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a010f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c2a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e0f42'; ++} {1} ++ ++reset_db ++do_execsql_test 2.0 { ++ CREATE VIRTUAL TABLE t0 USING fts3(col0 INTEGER PRIMARY KEY,col1 VARCHAR(8),col2 BINARY,col3 BINARY); ++ INSERT INTO t0 VALUES (1, '1234','aaaa','bbbb'); ++ SELECT snippet(t0) FROM t0 WHERE t0 MATCH x'0a4d4d4d4d320a4f52d70a310a310a4e4541520a0a31f6ce0a4f520a0a310a310a310a4f520a75fc2a242424' ; ++} {1} ++ ++reset_db ++do_execsql_test 2.1 { ++ CREATE VIRTUAL TABLE t0 USING fts3( ++ col0 INTEGER PRIMARY KEY,col1 VARCHAR(8),col2 BINARY,col3 BINARY ++ ); ++ INSERT INTO t0 VALUES ('one', '1234','aaaa','bbbb'); ++} ++do_execsql_test 2.2 { ++ SELECT snippet(t0) FROM t0 WHERE t0 MATCH ++ '(def AND (one NEAR abc)) OR one' ++} {one} ++ ++set sqlite_fts3_enable_parentheses 0 ++finish_test +-- +2.24.1 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2020-13631.patch b/SOURCES/sqlite-3.26.0-CVE-2020-13631.patch new file mode 100644 index 0000000..626e5be --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2020-13631.patch @@ -0,0 +1,97 @@ +Subject: [PATCH] Do not allow a virtual table to be renamed into the name of + one of its shadows. + +--- + src/alter.c | 5 ++++- + src/build.c | 28 ++++++++++++++++++++++------ + src/sqliteInt.h | 5 +++++ + 3 files changed, 31 insertions(+), 7 deletions(-) + +diff --git a/src/alter.c b/src/alter.c +index 1280e90..0fa24c0 100644 +--- a/src/alter.c ++++ b/src/alter.c +@@ -117,7 +117,10 @@ void sqlite3AlterRenameTable( + /* Check that a table or index named 'zName' does not already exist + ** in database iDb. If so, this is an error. + */ +- if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){ ++ if( sqlite3FindTable(db, zName, zDb) ++ || sqlite3FindIndex(db, zName, zDb) ++ || sqlite3IsShadowTableOf(db, pTab, zName) ++ ){ + sqlite3ErrorMsg(pParse, + "there is already another table or index with this name: %s", zName); + goto exit_rename_table; +diff --git a/src/build.c b/src/build.c +index e0fed8a..426428b 100644 +--- a/src/build.c ++++ b/src/build.c +@@ -1899,6 +1899,27 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ + recomputeColumnsNotIndexed(pPk); + } + ++ ++#ifndef SQLITE_OMIT_VIRTUALTABLE ++/* ++** Return true if pTab is a virtual table and zName is a shadow table name ++** for that virtual table. ++*/ ++int sqlite3IsShadowTableOf(sqlite3 *db, Table *pTab, const char *zName){ ++ int nName; /* Length of zName */ ++ ++ if( !IsVirtual(pTab) ) return 0; ++ nName = sqlite3Strlen30(pTab->zName); ++ if( sqlite3_strnicmp(zName, pTab->zName, nName)!=0 ) return 0; ++ if( zName[nName]!='_' ) return 0; ++ Module *pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]); ++ if( pMod==0 ) return 0; ++ if( pMod->pModule->iVersion<3 ) return 0; ++ if( pMod->pModule->xShadowName==0 ) return 0; ++ return pMod->pModule->xShadowName(zName+nName+1); ++} ++#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ ++ + #ifndef SQLITE_OMIT_VIRTUALTABLE + /* + ** Return true if zName is a shadow table name in the current database +@@ -1910,7 +1931,6 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ + static int isShadowTableName(sqlite3 *db, char *zName){ + char *zTail; /* Pointer to the last "_" in zName */ + Table *pTab; /* Table that zName is a shadow of */ +- Module *pMod; /* Module for the virtual table */ + + zTail = strrchr(zName, '_'); + if( zTail==0 ) return 0; +@@ -1919,11 +1939,7 @@ static int isShadowTableName(sqlite3 *db, char *zName){ + *zTail = '_'; + if( pTab==0 ) return 0; + if( !IsVirtual(pTab) ) return 0; +- pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]); +- if( pMod==0 ) return 0; +- if( pMod->pModule->iVersion<3 ) return 0; +- if( pMod->pModule->xShadowName==0 ) return 0; +- return pMod->pModule->xShadowName(zTail+1); ++ return sqlite3IsShadowTableOf(db, pTab, zName); + } + #else + # define isShadowTableName(x,y) 0 +diff --git a/src/sqliteInt.h b/src/sqliteInt.h +index b7d3571..76337f7 100644 +--- a/src/sqliteInt.h ++++ b/src/sqliteInt.h +@@ -4407,6 +4407,11 @@ void sqlite3AutoLoadExtensions(sqlite3*); + ); + # define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0) + #endif ++#ifndef SQLITE_OMIT_VIRTUALTABLE ++ int sqlite3IsShadowTableOf(sqlite3*,Table*,const char*); ++#else ++# define sqlite3IsShadowTableOf(A,B,C) 0 ++#endif + int sqlite3VtabEponymousTableInit(Parse*,Module*); + void sqlite3VtabEponymousTableClear(sqlite3*,Module*); + void sqlite3VtabMakeWritable(Parse*,Table*); +-- +2.24.1 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2020-13632.patch b/SOURCES/sqlite-3.26.0-CVE-2020-13632.patch new file mode 100644 index 0000000..f72b8d9 --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2020-13632.patch @@ -0,0 +1,67 @@ +Subject: [PATCH] Fix a null pointer deference that can occur on a strange + matchinfo() query. + +--- + ext/fts3/fts3_snippet.c | 2 +- + test/fts3matchinfo2.test | 35 +++++++++++++++++++++++++++++++++++ + 2 files changed, 36 insertions(+), 1 deletion(-) + create mode 100644 test/fts3matchinfo2.test + +diff --git a/ext/fts3/fts3_snippet.c b/ext/fts3/fts3_snippet.c +index a0771c0..5778620 100644 +--- a/ext/fts3/fts3_snippet.c ++++ b/ext/fts3/fts3_snippet.c +@@ -869,7 +869,7 @@ static void fts3ExprLHits( + iStart = pExpr->iPhrase * ((p->nCol + 31) / 32); + } + +- while( 1 ){ ++ if( pIter ) while( 1 ){ + int nHit = fts3ColumnlistCount(&pIter); + if( (pPhrase->iColumn>=pTab->nColumn || pPhrase->iColumn==iCol) ){ + if( p->flag==FTS3_MATCHINFO_LHITS ){ +diff --git a/test/fts3matchinfo2.test b/test/fts3matchinfo2.test +new file mode 100644 +index 0000000..d6b3ad0 +--- /dev/null ++++ b/test/fts3matchinfo2.test +@@ -0,0 +1,35 @@ ++# 2020-05-14 ++# ++# The author disclaims copyright to this source code. In place of ++# a legal notice, here is a blessing: ++# ++# May you do good and not evil. ++# May you find forgiveness for yourself and forgive others. ++# May you share freely, never taking more than you give. ++# ++#*********************************************************************** ++# This file implements regression tests for the FTS3 module. The focus ++# of this file is tables created with the "matchinfo=fts3" option. ++# ++ ++set testdir [file dirname $argv0] ++source $testdir/tester.tcl ++ ++# If SQLITE_ENABLE_FTS3 is not defined, omit this file. ++ifcapable !fts3 { finish_test ; return } ++ ++set sqlite_fts3_enable_parentheses 1 ++ ++# Crash case found by cyg0810 at gmail.com 2020-05-14. Reported to ++# chromium (which is not vulnerable) who kindly referred it to us. ++# ++do_execsql_test 1.0 { ++ CREATE TABLE t_content(col0 INTEGER); ++ CREATE VIRTUAL TABLE t0 USING fts3(col0 INTEGER PRIMARY KEY,col1 VARCHAR(8),col2 BINARY,col3 BINARY); ++ INSERT INTO t0 VALUES (1, '1234','aaaa','bbbb'); ++ SELECT hex(matchinfo(t0,'yxy')) FROM t0 WHERE t0 MATCH x'2b0a312b0a312a312a2a0b5d0a0b0b0a312a0a0b0b0a312a0b310a392a0b0a27312a2a0b5d0a312a0b310a31315d0b310a312a316d2a0b313b15bceaa50a312a0b0a27312a2a0b5d0a312a0b310a312b0b2a310a312a0b2a0b2a0b2e5d0a0bff313336e34a2a312a0b0a3c310b0a0b4b4b0b4b2a4bec40322b2a0b310a0a312a0a0a0a0a0a0a0a0a0b310a312a2a2a0b5d0a0b0b0a312a0b310a312a0b0a4e4541530b310a5df5ced70a0a0a0a0a4f520a0a0a0a0a0a0a312a0b0a4e4541520b310a5d616161610a0a0a0a4f520a0a0a0a0a0a312b0a312a312a0a0a0a0a0a0a004a0b0a310b220a0b0a310a4a22310a0b0a7e6fe0e0e030e0e0e0e0e01176e02000e0e0e0e0e01131320226310a0b0a310a4a22310a0b0a310a766f8b8b4ee0e0300ae0090909090909090909090909090909090909090909090909090909090909090947aaaa540b09090909090909090909090909090909090909090909090909090909090909fae0e0f2f22164e0e0f273e07fefefef7d6dfafafafa6d6d6d6d'; ++} {/000000.*0000000/} ++ ++ ++set sqlite_fts3_enable_parentheses 0 ++finish_test +\ No newline at end of file +-- +2.24.1 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2020-6405.patch b/SOURCES/sqlite-3.26.0-CVE-2020-6405.patch new file mode 100644 index 0000000..cf1fff5 --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2020-6405.patch @@ -0,0 +1,27 @@ +From 1668926bc3c7da0b2870a60382b179a0e3edb5de Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +Date: Thu, 26 Mar 2020 08:14:29 +0100 +Subject: [PATCH] Do not allow the constant-propagation optimization to apple + to ON/USING clause terms as it does not help and it might cause downstream + problems. + +--- + src/select.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/select.c b/src/select.c +index bbd13a4..88a43df 100644 +--- a/src/select.c ++++ b/src/select.c +@@ -4171,7 +4171,7 @@ static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){ + int i; + WhereConst *pConst; + if( pExpr->op!=TK_COLUMN ) return WRC_Continue; +- if( ExprHasProperty(pExpr, EP_FixedCol) ) return WRC_Continue; ++ if( ExprHasProperty(pExpr, EP_FixedCol|EP_FromJoin) ) return WRC_Continue; + pConst = pWalker->u.pConst; + for(i=0; inConst; i++){ + Expr *pColumn = pConst->apExpr[i*2]; +-- +2.24.1 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2020-9327.patch b/SOURCES/sqlite-3.26.0-CVE-2020-9327.patch new file mode 100644 index 0000000..24b1eb9 --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2020-9327.patch @@ -0,0 +1,106 @@ +From 2d788539b0018d34d3cabb328387ba6bec41ec42 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +Date: Thu, 26 Mar 2020 09:43:43 +0100 +Subject: [PATCH] NULL pointer dereference and segmentation fault because of + generated column optimizations + +Take care when checking the table of a TK_COLUMN expression node to +see if the table is a virtual table to first ensure that the +Expr.y.pTab pointer is not null due to generated column optimizations. +--- + src/expr.c | 13 ++++++++++--- + src/sqliteInt.h | 3 +++ + src/whereexpr.c | 12 ++++++++---- + 3 files changed, 21 insertions(+), 7 deletions(-) + +diff --git a/src/expr.c b/src/expr.c +index b081ca2..5f98f76 100644 +--- a/src/expr.c ++++ b/src/expr.c +@@ -4901,18 +4901,25 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ + case TK_LT: + case TK_LE: + case TK_GT: +- case TK_GE: ++ case TK_GE: { ++ Expr *pLeft = pExpr->pLeft; ++ Expr *pRight = pExpr->pRight; + testcase( pExpr->op==TK_EQ ); + testcase( pExpr->op==TK_NE ); + testcase( pExpr->op==TK_LT ); + testcase( pExpr->op==TK_LE ); + testcase( pExpr->op==TK_GT ); + testcase( pExpr->op==TK_GE ); +- if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->y.pTab)) +- || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->y.pTab)) ++ /* The y.pTab=0 assignment in wherecode.c always happens after the ++ ** impliesNotNullRow() test */ ++ if( (pLeft->op==TK_COLUMN && ALWAYS(pLeft->y.pTab!=0) ++ && IsVirtual(pLeft->y.pTab)) ++ || (pRight->op==TK_COLUMN && ALWAYS(pRight->y.pTab!=0) ++ && IsVirtual(pRight->y.pTab)) + ){ + return WRC_Prune; + } ++ } + default: + return WRC_Continue; + } +diff --git a/src/sqliteInt.h b/src/sqliteInt.h +index 051aa40..5f5f3cc 100644 +--- a/src/sqliteInt.h ++++ b/src/sqliteInt.h +@@ -2014,8 +2014,11 @@ struct Table { + */ + #ifndef SQLITE_OMIT_VIRTUALTABLE + # define IsVirtual(X) ((X)->nModuleArg) ++# define ExprIsVtab(X) \ ++ ((X)->op==TK_COLUMN && (X)->y.pTab!=0 && (X)->y.pTab->nModuleArg) + #else + # define IsVirtual(X) 0 ++# define ExprIsVtab(X) 0 + #endif + + /* +diff --git a/src/whereexpr.c b/src/whereexpr.c +index dbb7f0d..9d2813a 100644 +--- a/src/whereexpr.c ++++ b/src/whereexpr.c +@@ -382,7 +382,8 @@ static int isAuxiliaryVtabOperator( + ** MATCH(expression,vtab_column) + */ + pCol = pList->a[1].pExpr; +- if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){ ++ testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 ); ++ if( ExprIsVtab(pCol) ){ + for(i=0; iu.zToken, aOp[i].zOp)==0 ){ + *peOp2 = aOp[i].eOp2; +@@ -404,7 +405,8 @@ static int isAuxiliaryVtabOperator( + ** with function names in an arbitrary case. + */ + pCol = pList->a[0].pExpr; +- if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){ ++ testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 ); ++ if( ExprIsVtab(pCol) ){ + sqlite3_vtab *pVtab; + sqlite3_module *pMod; + void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**); +@@ -427,10 +429,12 @@ static int isAuxiliaryVtabOperator( + int res = 0; + Expr *pLeft = pExpr->pLeft; + Expr *pRight = pExpr->pRight; +- if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->y.pTab) ){ ++ testcase( pLeft->op==TK_COLUMN && pLeft->y.pTab==0 ); ++ if( ExprIsVtab(pLeft) ){ + res++; + } +- if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->y.pTab) ){ ++ testcase( pRight && pRight->op==TK_COLUMN && pRight->y.pTab==0 ); ++ if( pRight && ExprIsVtab(pRight) ){ + res++; + SWAP(Expr*, pLeft, pRight); + } +-- +2.24.1 + diff --git a/SOURCES/sqlite-3.26.0-zPath-covscan.patch b/SOURCES/sqlite-3.26.0-zPath-covscan.patch new file mode 100644 index 0000000..060cbda --- /dev/null +++ b/SOURCES/sqlite-3.26.0-zPath-covscan.patch @@ -0,0 +1,71 @@ +From 75525dbdf9b7ed003e343c42710e8b13f73a7607 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +Date: Thu, 23 Jan 2020 15:08:13 +0100 +Subject: [PATCH] Fix buffer underflows in the zipfile extension associated + with zero-length or NULL filename in the ZIP archive. But report on the + mailing list by Yongheng and Rui. + +--- + ext/misc/zipfile.c | 14 +++++++++----- + test/zipfile.test | 13 +++++++++++++ + 2 files changed, 22 insertions(+), 5 deletions(-) + +diff --git a/ext/misc/zipfile.c b/ext/misc/zipfile.c +index e6141ef..7fd4074 100644 +--- a/ext/misc/zipfile.c ++++ b/ext/misc/zipfile.c +@@ -1433,8 +1433,8 @@ static int zipfileGetMode( + ** identical, ignoring any trailing '/' character in either path. */ + static int zipfileComparePath(const char *zA, const char *zB, int nB){ + int nA = (int)strlen(zA); +- if( zA[nA-1]=='/' ) nA--; +- if( zB[nB-1]=='/' ) nB--; ++ if( nA>0 && zA[nA-1]=='/' ) nA--; ++ if( nB>0 && zB[nB-1]=='/' ) nB--; + if( nA==nB && memcmp(zA, zB, nA)==0 ) return 0; + return 1; + } +@@ -1628,11 +1628,15 @@ static int zipfileUpdate( + ** '/'. This appears to be required for compatibility with info-zip + ** (the unzip command on unix). It does not create directories + ** otherwise. */ +- if( zPath[nPath-1]!='/' ){ ++ if( nPath<=0 || zPath[nPath-1]!='/' ){ + zFree = sqlite3_mprintf("%s/", zPath); +- if( zFree==0 ){ rc = SQLITE_NOMEM; } + zPath = (const char*)zFree; +- nPath = (int)strlen(zPath); ++ if( zFree==0 ){ ++ rc = SQLITE_NOMEM; ++ nPath = 0; ++ }else{ ++ nPath = (int)strlen(zPath); ++ } + } + } + +diff --git a/test/zipfile.test b/test/zipfile.test +index e4b8088..9f07c0a 100644 +--- a/test/zipfile.test ++++ b/test/zipfile.test +@@ -821,4 +821,17 @@ do_execsql_test 14.10 { + PRAGMA integrity_check; + } {3 ok} + ++# 2019-12-26 More problems in zipfile from the Yongheng and Rui fuzzer ++# ++do_execsql_test 15.10 { ++ DROP TABLE IF EXISTS t1; ++ CREATE VIRTUAL TABLE t1 USING zipfile(null); ++ REPLACE INTO t1 VALUES(null,null,0,null,null,null,null); ++} {} ++do_execsql_test 15.20 { ++ DROP TABLE IF EXISTS t2; ++ CREATE VIRTUAL TABLE t2 USING zipfile(null); ++ REPLACE INTO t2 values(null,null,null,null,null,10,null); ++} {} ++ + finish_test +-- +2.19.1 + diff --git a/SPECS/sqlite.spec b/SPECS/sqlite.spec index 15cf024..526fe90 100644 --- a/SPECS/sqlite.spec +++ b/SPECS/sqlite.spec @@ -10,7 +10,7 @@ Summary: Library that implements an embeddable SQL database engine Name: sqlite Version: %{rpmver} -Release: 4%{?dist} +Release: 10%{?dist} License: Public Domain Group: Applications/Databases URL: http://www.sqlite.org/ @@ -37,6 +37,38 @@ Patch8: sqlite-3.18.0-sync2-dirsync.patch # Fix for CVE-2019-8457 (rhbz#1723338) # https://www.sqlite.org/src/info/90acdbfce9c08858 Patch9: sqlite-3.26.0-out-of-bounds-read.patch +# Fix for CVE-2019-13752 +Patch10: sqlite-3.26-CVE-2019-13752.patch +# Fix for CVE-2019-13753 +Patch11: sqlite-3.26-CVE-2019-13753.patch +# Fix for CVE-2019-13734 +Patch12: sqlite-3.26.0-CVE-2019-13734.patch +# Fix for CVE-2019-19924 +Patch13: sqlite-3.26.0-CVE-2019-19924.patch +# Fix for CVE-2019-19923 +Patch14: sqlite-3.26.0-CVE-2019-19923.patch +# Fix for CVE-2019-19925 +Patch15: sqlite-3.26.0-CVE-2019-19925.patch +# Fix for CVE-2019-19959 +Patch16: sqlite-3.26.0-CVE-2019-19959.patch +# Fix for issues found by covscan +Patch17: sqlite-3.26.0-zPath-covscan.patch +# Fix for CVE-2019-20218 +Patch18: sqlite-3.26.0-CVE-2019-20218.patch +# Fix for CVE-2020-6405 +Patch19: sqlite-3.26.0-CVE-2020-6405.patch +# Fix for CVE-2020-9327 +Patch20: sqlite-3.26.0-CVE-2020-9327.patch +# Fix for CVE-2019-16168 +Patch21: sqlite-3.26.0-CVE-2019-16168.patch +# Fix for CVE-2019-5018 +Patch22: sqlite-3.26.0-CVE-2019-5018.patch +# Fix for CVE-2020-13632 +Patch23: sqlite-3.26.0-CVE-2020-13632.patch +# Fix for CVE-2020-13631 +Patch24: sqlite-3.26.0-CVE-2020-13631.patch +# Fix for CVE-2020-13630 +Patch25: sqlite-3.26.0-CVE-2020-13630.patch BuildRequires: ncurses-devel readline-devel glibc-devel BuildRequires: autoconf @@ -143,6 +175,22 @@ This package contains the analysis program for %{name}. %endif %patch8 -p1 %patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 +%patch21 -p1 +%patch22 -p1 +%patch23 -p1 +%patch24 -p1 +%patch25 -p1 # Remove backup-file rm -f %{name}-doc-%{docver}/sqlite.css~ || : @@ -247,6 +295,34 @@ make test %endif %changelog +* Wed Jun 10 2020 Ondrej Dubaj - 3.26.0-10 +- Fixed CVE-2020-13632 (#1845572) +- Fixed CVE-2020-13631 (#1845474) +- Fixed CVE-2020-13630 (#1845153) + +* Tue Jun 02 2020 Ondrej Dubaj - 3.26.0-9 +- Fixed CVE-2019-5018 (#1721509) + +* Thu Apr 23 2020 Ondrej Dubaj - 3.26.0-8 +- Fixed CVE-2019-16168 (#1826897) + +* Tue Mar 24 2020 Ondrej Dubaj - 3.26.0-7 +- Fixed CVE-2019-20218 (#1791592) +- Fixed CVE-2020-6405 (#1804823) +- Fixed CVE-2020-0327 (#1816572) + +* Thu Jan 23 2020 Ondrej Dubaj - 3.26.0-6 +- Fixed issues found by covscan + +* Thu Jan 02 2020 Ondrej Dubaj - 3.26.0-5 +- Fixed CVE-2019-13752 (#1786529) +- Fixed CVE-2019-13753 (#1786535) +- Fixed CVE-2019-13734 (#1786509) +- Fixed CVE-2019-19924 (#1789776) +- Fixed CVE-2019-19923 (#1789812) +- Fixed CVE-2019-19925 (#1789808) +- Fixed CVE-2019-19959 (#1789823) + * Wed Jun 26 2019 Ondrej Dubaj - 3.26.0-4 - Fixed CVE-2019-8457 (#1723338)