diff -Nru sqlite3-3.11.0/debian/changelog sqlite3-3.11.0/debian/changelog --- sqlite3-3.11.0/debian/changelog 2019-06-18 12:42:50.000000000 +0000 +++ sqlite3-3.11.0/debian/changelog 2019-11-28 16:40:07.000000000 +0000 @@ -1,3 +1,18 @@ +sqlite3 (3.11.0-1ubuntu1.3) xenial-security; urgency=medium + + * SECURITY UPDATE: Severe division by zero + - debian/patches/CVE-2019-16168.patch: fix in + src/analyze.c, src/where.c, test/analyzeC.test. + - CVE-2019-16168 + * SECURITY UPDATE: Heap corruption exploit + - debian/patches/CVE-2019-5827-*.patch: fix in + ext/fts3*, ext/rtree/geopoly.c, src/build.c, + src/expr.c, src/main.c, src/test_fs.c, src/util.c, + src/vdbeaux.c, src/vdbesort.c, src/vtab.c. + - CVE-2019-5827 + + -- Leonidas S. Barbosa Thu, 28 Nov 2019 13:39:43 -0300 + sqlite3 (3.11.0-1ubuntu1.2) xenial-security; urgency=medium * SECURITY UPDATE: Denial of service diff -Nru sqlite3-3.11.0/debian/patches/CVE-2019-16168.patch sqlite3-3.11.0/debian/patches/CVE-2019-16168.patch --- sqlite3-3.11.0/debian/patches/CVE-2019-16168.patch 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.11.0/debian/patches/CVE-2019-16168.patch 2019-11-28 16:39:12.000000000 +0000 @@ -0,0 +1,57 @@ +Description: Ensure that the optional "sz=N" parameter that can be manually added to the end of an sqlite_stat1 entry does not have an N value that is too small +Origin: https://www.sqlite.org/src/info/98357d8c1263920b + + + +Index: sqlite3-3.11.0/src/analyze.c +=================================================================== +--- sqlite3-3.11.0.orig/src/analyze.c ++++ sqlite3-3.11.0/src/analyze.c +@@ -1463,7 +1463,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; + } +Index: sqlite3-3.11.0/src/where.c +=================================================================== +--- sqlite3-3.11.0.orig/src/where.c ++++ sqlite3-3.11.0/src/where.c +@@ -2365,6 +2365,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 ){ +Index: sqlite3-3.11.0/test/analyzeC.test +=================================================================== +--- sqlite3-3.11.0.orig/test/analyzeC.test ++++ sqlite3-3.11.0/test/analyzeC.test +@@ -132,6 +132,20 @@ 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. diff -Nru sqlite3-3.11.0/debian/patches/CVE-2019-5827-1.patch sqlite3-3.11.0/debian/patches/CVE-2019-5827-1.patch --- sqlite3-3.11.0/debian/patches/CVE-2019-5827-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.11.0/debian/patches/CVE-2019-5827-1.patch 2019-11-28 16:39:29.000000000 +0000 @@ -0,0 +1,155 @@ +Description: Integer overflow in SQLite via WebSQL +Origin: https://www.sqlite.org/src/info/07ee06fd390bfebe AND https://www.sqlite.org/src/info/0b6ae032c28e7fe3 +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=928770 + +Index: sqlite3-3.11.0/ext/fts3/fts3_snippet.c +=================================================================== +--- sqlite3-3.11.0.orig/ext/fts3/fts3_snippet.c ++++ sqlite3-3.11.0/ext/fts3/fts3_snippet.c +@@ -130,10 +130,11 @@ struct StrBuffer { + */ + static MatchinfoBuffer *fts3MIBufferNew(int nElem, const char *zMatchinfo){ + MatchinfoBuffer *pRet; +- int nByte = sizeof(u32) * (2*nElem + 1) + sizeof(MatchinfoBuffer); +- int nStr = (int)strlen(zMatchinfo); ++ sqlite3_int64 nByte = sizeof(u32) * (2*(sqlite3_int64)nElem + 1) ++ + sizeof(MatchinfoBuffer); ++ sqlite3_int64 nStr = strlen(zMatchinfo); + +- pRet = sqlite3_malloc(nByte + nStr+1); ++ pRet = sqlite3_malloc64(nByte + nStr+1); + if( pRet ){ + memset(pRet, 0, nByte); + pRet->aMatchinfo[0] = (u8*)(&pRet->aMatchinfo[1]) - (u8*)pRet; +Index: sqlite3-3.11.0/ext/fts3/fts3_test.c +=================================================================== +--- sqlite3-3.11.0.orig/ext/fts3/fts3_test.c ++++ sqlite3-3.11.0/ext/fts3/fts3_test.c +@@ -441,14 +441,14 @@ static int testTokenizerNext( + }else{ + /* Advance to the end of the token */ + const char *pToken = p; +- int nToken; ++ sqlite3_int64 nToken; + while( ppCsr->nBuffer ){ + sqlite3_free(pCsr->aBuffer); +- pCsr->aBuffer = sqlite3_malloc(nToken); ++ pCsr->aBuffer = sqlite3_malloc64(nToken); + } + if( pCsr->aBuffer==0 ){ + rc = SQLITE_NOMEM; +Index: sqlite3-3.11.0/ext/fts3/fts3_tokenize_vtab.c +=================================================================== +--- sqlite3-3.11.0.orig/ext/fts3/fts3_tokenize_vtab.c ++++ sqlite3-3.11.0/ext/fts3/fts3_tokenize_vtab.c +@@ -346,7 +346,7 @@ static int fts3tokFilterMethod( + if( idxNum==1 ){ + const char *zByte = (const char *)sqlite3_value_text(apVal[0]); + int nByte = sqlite3_value_bytes(apVal[0]); +- pCsr->zInput = sqlite3_malloc(nByte+1); ++ pCsr->zInput = sqlite3_malloc64(nByte+1); + if( pCsr->zInput==0 ){ + rc = SQLITE_NOMEM; + }else{ +Index: sqlite3-3.11.0/ext/fts3/fts3_tokenizer.c +=================================================================== +--- sqlite3-3.11.0.orig/ext/fts3/fts3_tokenizer.c ++++ sqlite3-3.11.0/ext/fts3/fts3_tokenizer.c +@@ -187,8 +187,8 @@ int sqlite3Fts3InitTokenizer( + int iArg = 0; + z = &z[n+1]; + while( z0 ){ +- int nByte = sizeof(Fts3SegReader) + (nElem+1)*sizeof(Fts3HashElem *); +- pReader = (Fts3SegReader *)sqlite3_malloc(nByte); ++ sqlite3_int64 nByte; ++ nByte = sizeof(Fts3SegReader) + (nElem+1)*sizeof(Fts3HashElem *); ++ pReader = (Fts3SegReader *)sqlite3_malloc64(nByte); + if( !pReader ){ + rc = SQLITE_NOMEM; + }else{ +@@ -3344,7 +3345,7 @@ static void fts3InsertDocsize( + int rc; /* Result code from subfunctions */ + + if( *pRC ) return; +- pBlob = sqlite3_malloc( 10*p->nColumn ); ++ pBlob = sqlite3_malloc64( 10*(sqlite3_int64)p->nColumn ); + if( pBlob==0 ){ + *pRC = SQLITE_NOMEM; + return; +@@ -3394,7 +3395,7 @@ static void fts3UpdateDocTotals( + const int nStat = p->nColumn+2; + + if( *pRC ) return; +- a = sqlite3_malloc( (sizeof(u32)+10)*nStat ); ++ a = sqlite3_malloc64( (sizeof(u32)+10)*(sqlite3_int64)nStat ); + if( a==0 ){ + *pRC = SQLITE_NOMEM; + return; +@@ -3514,8 +3515,8 @@ static int fts3DoRebuild(Fts3Table *p){ + } + + if( rc==SQLITE_OK ){ +- int nByte = sizeof(u32) * (p->nColumn+1)*3; +- aSz = (u32 *)sqlite3_malloc(nByte); ++ sqlite3_int64 nByte = sizeof(u32) * ((sqlite3_int64)p->nColumn+1)*3; ++ aSz = (u32 *)sqlite3_malloc64(nByte); + if( aSz==0 ){ + rc = SQLITE_NOMEM; + }else{ +@@ -3581,12 +3582,12 @@ static int fts3IncrmergeCsr( + ){ + int rc; /* Return Code */ + sqlite3_stmt *pStmt = 0; /* Statement used to read %_segdir entry */ +- int nByte; /* Bytes allocated at pCsr->apSegment[] */ ++ sqlite3_int64 nByte; /* Bytes allocated at pCsr->apSegment[] */ + + /* Allocate space for the Fts3MultiSegReader.aCsr[] array */ + memset(pCsr, 0, sizeof(*pCsr)); + nByte = sizeof(Fts3SegReader *) * nSeg; +- pCsr->apSegment = (Fts3SegReader **)sqlite3_malloc(nByte); ++ pCsr->apSegment = (Fts3SegReader **)sqlite3_malloc64(nByte); + + if( pCsr->apSegment==0 ){ + rc = SQLITE_NOMEM; +@@ -5561,7 +5562,7 @@ int sqlite3Fts3UpdateMethod( + } + + /* Allocate space to hold the change in document sizes */ +- aSzDel = sqlite3_malloc( sizeof(aSzDel[0])*(p->nColumn+1)*2 ); ++ aSzDel = sqlite3_malloc64(sizeof(aSzDel[0])*((sqlite3_int64)p->nColumn+1)*2); + if( aSzDel==0 ){ + rc = SQLITE_NOMEM; + goto update_out; +Index: sqlite3-3.11.0/ext/fts5/fts5_tokenize.c +=================================================================== +--- sqlite3-3.11.0.orig/ext/fts5/fts5_tokenize.c ++++ sqlite3-3.11.0/ext/fts5/fts5_tokenize.c +@@ -345,7 +345,7 @@ static int fts5UnicodeCreate( + memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar)); + p->bRemoveDiacritic = 1; + p->nFold = 64; +- p->aFold = sqlite3_malloc(p->nFold * sizeof(char)); ++ p->aFold = sqlite3_malloc64(p->nFold * sizeof(char)); + if( p->aFold==0 ){ + rc = SQLITE_NOMEM; + } diff -Nru sqlite3-3.11.0/debian/patches/CVE-2019-5827-2.patch sqlite3-3.11.0/debian/patches/CVE-2019-5827-2.patch --- sqlite3-3.11.0/debian/patches/CVE-2019-5827-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.11.0/debian/patches/CVE-2019-5827-2.patch 2019-11-28 16:39:37.000000000 +0000 @@ -0,0 +1,190 @@ +Description: Integer overflow in SQLite via WebSQL +Origin: https://www.sqlite.org/src/info/0b6ae032c28e7fe3 +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=928770 +diff --git a/src/build.c b/src/build.c +index edd7a19..4fe274e 100644 +--- a/src/build.c ++++ b/src/build.c +@@ -3525,9 +3525,9 @@ void *sqlite3ArrayAllocate( + int *pIdx /* Write the index of a new slot here */ + ){ + char *z; +- int n = *pnEntry; ++ sqlite3_int64 n = *pnEntry; + if( (n & (n-1))==0 ){ +- int sz = (n==0) ? 1 : 2*n; ++ sqlite3_int64 sz = (n==0) ? 1 : 2*n; + void *pNew = sqlite3DbRealloc(db, pArray, sz*szEntry); + if( pNew==0 ){ + *pIdx = -1; +@@ -3631,7 +3631,7 @@ SrcList *sqlite3SrcListEnlarge( + /* Allocate additional space if needed */ + if( (u32)pSrc->nSrc+nExtra>pSrc->nAlloc ){ + SrcList *pNew; +- int nAlloc = pSrc->nSrc+nExtra; ++ sqlite3_int64 nAlloc = 2*(sqlite3_int64)pSrc->nSrc+nExtra; + int nGot; + pNew = sqlite3DbRealloc(db, pSrc, + sizeof(*pSrc) + (nAlloc-1)*sizeof(pSrc->a[0]) ); +@@ -4364,7 +4364,7 @@ With *sqlite3WithAdd( + } + + if( pWith ){ +- int nByte = sizeof(*pWith) + (sizeof(pWith->a[1]) * pWith->nCte); ++ sqlite3_int64 nByte = sizeof(*pWith) + (sizeof(pWith->a[1]) * pWith->nCte); + pNew = sqlite3DbRealloc(db, pWith, nByte); + }else{ + pNew = sqlite3DbMallocZero(db, sizeof(*pWith)); +diff --git a/src/expr.c b/src/expr.c +index 8d96ba1..44709ee 100644 +--- a/src/expr.c ++++ b/src/expr.c +@@ -1154,7 +1154,7 @@ ExprList *sqlite3ExprListAppend( + }else if( (pList->nExpr & (pList->nExpr-1))==0 ){ + struct ExprList_item *a; + assert( pList->nExpr>0 ); +- a = sqlite3DbRealloc(db, pList->a, pList->nExpr*2*sizeof(pList->a[0])); ++ a = sqlite3DbRealloc(db, pList->a, (sqlite3_int64)pList->nExpr*2*sizeof(pList->a[0])); + if( a==0 ){ + goto no_mem; + } +diff --git a/src/main.c b/src/main.c +index 922af13..a8f7f7e 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -678,7 +678,7 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ + pStart = 0; + }else if( pBuf==0 ){ + sqlite3BeginBenignMalloc(); +- pStart = sqlite3Malloc( sz*cnt ); /* IMP: R-61949-35727 */ ++ pStart = sqlite3Malloc( sz*(sqlite3_int64)cnt ); /* IMP: R-61949-35727 */ + sqlite3EndBenignMalloc(); + if( pStart ) cnt = sqlite3MallocSize(pStart)/sz; + }else{ +diff --git a/src/test_fs.c b/src/test_fs.c +index 45db0b5..a1a7be5 100644 +--- a/src/test_fs.c ++++ b/src/test_fs.c +@@ -735,7 +735,7 @@ static int fsColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ + fstat(fd, &sbuf); + + if( sbuf.st_size>=pCur->nAlloc ){ +- int nNew = sbuf.st_size*2; ++ sqlite3_int64 nNew = sbuf.st_size*2; + char *zNew; + if( nNew<1024 ) nNew = 1024; + +diff --git a/src/vdbeaux.c b/src/vdbeaux.c +index 29a9422..4a8ee94 100644 +--- a/src/vdbeaux.c ++++ b/src/vdbeaux.c +@@ -115,9 +115,11 @@ static int growOpArray(Vdbe *v, int nOp){ + ** operation (without SQLITE_TEST_REALLOC_STRESS) is to double the current + ** size of the op array or add 1KB of space, whichever is smaller. */ + #ifdef SQLITE_TEST_REALLOC_STRESS +- int nNew = (p->nOpAlloc>=512 ? p->nOpAlloc*2 : p->nOpAlloc+nOp); ++ sqlite3_int64 nNew = (p->nOpAlloc>=512 ? 2*(sqlite3_int64)p->nOpAlloc ++ : (sqlite3_int64)p->nOpAlloc+nOp); + #else +- int nNew = (p->nOpAlloc ? p->nOpAlloc*2 : (int)(1024/sizeof(Op))); ++ sqlite3_int64 nNew = (p->nOpAlloc ? 2*(sqlite3_int64)p->nOpAlloc ++ : (sqlite3_int64)1024/sizeof(Op)); + UNUSED_PARAMETER(nOp); + #endif + +@@ -721,7 +723,7 @@ void sqlite3VdbeScanStatus( + LogEst nEst, /* Estimated number of output rows */ + const char *zName /* Name of table or index being scanned */ + ){ +- int nByte = (p->nScan+1) * sizeof(ScanStatus); ++ sqlite3_int64 nByte = (p->nScan+1) * sizeof(ScanStatus); + ScanStatus *aNew; + aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte); + if( aNew ){ +diff --git a/src/vdbesort.c b/src/vdbesort.c +index 380772e..1f3efa0 100644 +--- a/src/vdbesort.c ++++ b/src/vdbesort.c +@@ -537,7 +537,7 @@ static int vdbePmaReadBlob( + /* Extend the p->aAlloc[] allocation if required. */ + if( p->nAllocnAlloc*2); ++ sqlite3_int64 nNew = MAX(128, 2*(sqlite3_int64)p->nAlloc); + while( nByte>nNew ) nNew = nNew*2; + aNew = sqlite3Realloc(p->aAlloc, nNew); + if( !aNew ) return SQLITE_NOMEM; +@@ -1822,7 +1822,7 @@ int sqlite3VdbeSorterWrite( + if( nMin>pSorter->nMemory ){ + u8 *aNew; + int iListOff = (u8*)pSorter->list.pList - pSorter->list.aMemory; +- int nNew = pSorter->nMemory * 2; ++ sqlite3_int64 nNew = 2 * (sqlite3_int64)pSorter->nMemory; + while( nNew < nMin ) nNew = nNew*2; + if( nNew > pSorter->mxPmaSize ) nNew = pSorter->mxPmaSize; + if( nNew < nMin ) nNew = nMin; +diff --git a/src/vtab.c b/src/vtab.c +index e8794e6..423e49e 100644 +--- a/src/vtab.c ++++ b/src/vtab.c +@@ -285,9 +285,13 @@ void sqlite3VtabClear(sqlite3 *db, Table *p){ + ** string will be freed automatically when the table is + ** deleted. + */ +-static void addModuleArgument(sqlite3 *db, Table *pTable, char *zArg){ +- int nBytes = sizeof(char *)*(2+pTable->nModuleArg); ++static void addModuleArgument(Parse *pParse, Table *pTable, char *zArg){ ++ sqlite3_int64 nBytes = sizeof(char *)*(2+pTable->nModuleArg); + char **azModuleArg; ++ sqlite3 *db = pParse->db; ++ if( pTable->nModuleArg+3>=db->aLimit[SQLITE_LIMIT_COLUMN] ){ ++ sqlite3ErrorMsg(pParse, "too many columns on %s", pTable->zName); ++ } + azModuleArg = sqlite3DbRealloc(db, pTable->azModuleArg, nBytes); + if( azModuleArg==0 ){ + sqlite3DbFree(db, zArg); +@@ -326,9 +330,9 @@ void sqlite3VtabBeginParse( + + pTable->tabFlags |= TF_Virtual; + pTable->nModuleArg = 0; +- addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName)); +- addModuleArgument(db, pTable, 0); +- addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName)); ++ addModuleArgument(pParse, pTable, sqlite3NameFromToken(db, pModuleName)); ++ addModuleArgument(pParse, pTable, 0); ++ addModuleArgument(pParse, pTable, sqlite3DbStrDup(db, pTable->zName)); + assert( (pParse->sNameToken.z==pName2->z && pName2->z!=0) + || (pParse->sNameToken.z==pName1->z && pName2->z==0) + ); +@@ -359,7 +363,7 @@ static void addArgumentToVtab(Parse *pParse){ + const char *z = (const char*)pParse->sArg.z; + int n = pParse->sArg.n; + sqlite3 *db = pParse->db; +- addModuleArgument(db, pParse->pNewTable, sqlite3DbStrNDup(db, z, n)); ++ addModuleArgument(pParse, pParse->pNewTable, sqlite3DbStrNDup(db, z, n)); + } + } + +@@ -652,7 +656,8 @@ static int growVTrans(sqlite3 *db){ + /* Grow the sqlite3.aVTrans array if required */ + if( (db->nVTrans%ARRAY_INCR)==0 ){ + VTable **aVTrans; +- int nBytes = sizeof(sqlite3_vtab *) * (db->nVTrans + ARRAY_INCR); ++ sqlite3_int64 nBytes = sizeof(sqlite3_vtab*)* ++ ((sqlite3_int64)db->nVTrans + ARRAY_INCR); + aVTrans = sqlite3DbRealloc(db, (void *)db->aVTrans, nBytes); + if( !aVTrans ){ + return SQLITE_NOMEM; +@@ -1126,9 +1131,9 @@ int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){ + pTab->tabFlags |= TF_Virtual; + pTab->nModuleArg = 0; + pTab->iPKey = -1; +- addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName)); +- addModuleArgument(db, pTab, 0); +- addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName)); ++ addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName)); ++ addModuleArgument(pParse, pTab, 0); ++ addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName)); + rc = vtabCallConstructor(db, pTab, pMod, pModule->xConnect, &zErr); + if( rc ){ + sqlite3ErrorMsg(pParse, "%s", zErr); diff -Nru sqlite3-3.11.0/debian/patches/series sqlite3-3.11.0/debian/patches/series --- sqlite3-3.11.0/debian/patches/series 2019-06-18 13:07:17.000000000 +0000 +++ sqlite3-3.11.0/debian/patches/series 2019-11-28 16:39:37.000000000 +0000 @@ -20,3 +20,6 @@ CVE-2019-9936.patch CVE-2019-9937.patch CVE-2019-8457-string-interface.patch +CVE-2019-16168.patch +CVE-2019-5827-1.patch +CVE-2019-5827-2.patch