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 index f2ddcae..9cb8e4c 100644 --- a/SOURCES/sqlite-3.26.0-CVE-2019-13734.patch +++ b/SOURCES/sqlite-3.26.0-CVE-2019-13734.patch @@ -1,6 +1,6 @@ -From 414660066ee2f1670a9f09a11ab41533015b2f3a Mon Sep 17 00:00:00 2001 +From 5f4ce30babee8085fc36680c6103d9a06be49ef7 Mon Sep 17 00:00:00 2001 From: Ondrej Dubaj -Date: Thu, 2 Jan 2020 15:04:42 +0100 +Date: Thu, 2 Jan 2020 11:58:39 +0100 Subject: [PATCH] More improvements to shadow table corruption detection in FTS3. @@ -11,7 +11,7 @@ Subject: [PATCH] More improvements to shadow table corruption detection in 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c -index f6fb931..caa742f 100644 +index 6d6bd46..84fc8a5 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -1460,6 +1460,10 @@ static int fts3InitVtab( @@ -26,7 +26,7 @@ index f6fb931..caa742f 100644 fts3DeclareVtab(&rc, p); diff --git a/ext/fts3/fts3Int.h b/ext/fts3/fts3Int.h -index 077bad7..12392c0 100644 +index 6f5a7a0..0d1b491 100644 --- a/ext/fts3/fts3Int.h +++ b/ext/fts3/fts3Int.h @@ -287,9 +287,19 @@ struct Fts3Table { @@ -50,7 +50,7 @@ index 077bad7..12392c0 100644 ** 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 8fc6589..e4b9640 100644 +index 8624329..d57d265 100644 --- a/ext/fts3/fts3_write.c +++ b/ext/fts3/fts3_write.c @@ -1152,7 +1152,7 @@ static int fts3AllocateSegdirIdx( @@ -62,7 +62,7 @@ index 8fc6589..e4b9640 100644 fts3LogMerge(16, getAbsoluteLevel(p, iLangid, iIndex, iLevel)); rc = fts3SegmentMerge(p, iLangid, iIndex, iLevel); *piIdx = 0; -@@ -4249,6 +4249,10 @@ static int fts3IncrmergeLoad( +@@ -4259,6 +4259,10 @@ static int fts3IncrmergeLoad( int i; int nHeight = (int)aRoot[0]; NodeWriter *pNode; @@ -73,7 +73,7 @@ index 8fc6589..e4b9640 100644 pWriter->nLeafEst = (int)((iEnd - iStart) + 1)/FTS_MAX_APPENDABLE_HEIGHT; pWriter->iStart = iStart; -@@ -4997,7 +5001,7 @@ static int fts3DoIncrmerge( +@@ -5007,7 +5011,7 @@ static int fts3DoIncrmerge( const char *zParam /* Nul-terminated string containing "A,B" */ ){ int rc; @@ -82,7 +82,7 @@ index 8fc6589..e4b9640 100644 int nMerge = 0; const char *z = zParam; -@@ -5042,7 +5046,7 @@ static int fts3DoAutoincrmerge( +@@ -5052,7 +5056,7 @@ static int fts3DoAutoincrmerge( int rc = SQLITE_OK; sqlite3_stmt *pStmt = 0; p->nAutoincrmerge = fts3Getint(&zParam); @@ -91,17 +91,17 @@ index 8fc6589..e4b9640 100644 p->nAutoincrmerge = 8; } if( !p->bHasStat ){ -@@ -5326,6 +5330,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) ){ -+ int v = atoi(&zVal[11]); -+ if( v>=4 && v<=FTS3_MERGE_COUNT && (v&1)==0 ) p->nMergeCount = v; -+ rc = SQLITE_OK; +@@ -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 - }else{ - rc = SQLITE_ERROR; + } -- 2.19.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-out-of-bounds-read.patch b/SOURCES/sqlite-3.26.0-out-of-bounds-read.patch new file mode 100644 index 0000000..1edc762 --- /dev/null +++ b/SOURCES/sqlite-3.26.0-out-of-bounds-read.patch @@ -0,0 +1,89 @@ +From eca47c8481b0c2f09a7818ed2bce0ad27b1dae27 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +Date: Wed, 26 Jun 2019 12:25:10 +0200 +Subject: [PATCH] Fixed out of bounds heap read in function rtreenode() + + Enhance the rtreenode() function of rtree (used for + testing) so that it uses the newer sqlite3_str object + for better performance and improved error reporting. + Test cases added to TH3. + + Resolves: #1723338 + Version: 3.26.0-4 +--- + ext/rtree/rtree.c | 35 ++++++++++++++++------------------- + 1 file changed, 16 insertions(+), 19 deletions(-) + +diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c +index 4b044cb..87d0de0 100644 +--- a/ext/rtree/rtree.c ++++ b/ext/rtree/rtree.c +@@ -3711,49 +3711,46 @@ rtreeInit_fail: + ** *2 coordinates. + */ + static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ +- char *zText = 0; + RtreeNode node; + Rtree tree; + int ii; ++ int nData; ++ int errCode; ++ sqlite3_str *pOut; + + UNUSED_PARAMETER(nArg); + memset(&node, 0, sizeof(RtreeNode)); + memset(&tree, 0, sizeof(Rtree)); + tree.nDim = (u8)sqlite3_value_int(apArg[0]); ++ if( tree.nDim<1 || tree.nDim>5 ) return; + tree.nDim2 = tree.nDim*2; + tree.nBytesPerCell = 8 + 8 * tree.nDim; + node.zData = (u8 *)sqlite3_value_blob(apArg[1]); ++ nData = sqlite3_value_bytes(apArg[1]); ++ if( nData<4 ) return; ++ if( nData0 ) sqlite3_str_append(pOut, " ", 1); ++ sqlite3_str_appendf(pOut, "{%lld", cell.iRowid); + for(jj=0; jj +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 db9d19a..fb381f2 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: 6%{?dist} License: Public Domain Group: Applications/Databases URL: http://www.sqlite.org/ @@ -34,8 +34,25 @@ Patch6: sqlite-3.8.10.1-tcl-regress-tests.patch Patch7: sqlite-3.16-datetest-2.2c.patch # Modify sync2.test to pass with DIRSYNC turned off Patch8: sqlite-3.18.0-sync2-dirsync.patch -# Fixed CVE-2019-13734 -Patch9: sqlite-3.26.0-CVE-2019-13734.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 fr issues found by covscan +Patch17: sqlite-3.26.0-zPath-covscan.patch BuildRequires: ncurses-devel readline-devel glibc-devel BuildRequires: autoconf @@ -142,6 +159,14 @@ 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 # Remove backup-file rm -f %{name}-doc-%{docver}/sqlite.css~ || : @@ -246,8 +271,20 @@ make test %endif %changelog -* Thu Jan 02 2020 Ondrej Dubaj - 3.26.0-4 -- Fixed CVE-2019-13734 (#1786508) +* 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) * Thu Jan 03 2019 Petr Kubat - 3.26.0-3 - Rebuild to pick up latest test sources by the CI