diff --git a/SOURCES/sqlite-3.7.14-printf-overflow.patch b/SOURCES/sqlite-3.7.14-printf-overflow.patch new file mode 100644 index 0000000..5049915 --- /dev/null +++ b/SOURCES/sqlite-3.7.14-printf-overflow.patch @@ -0,0 +1,130 @@ +# Fix for stack buffer overflow in src/printf.c, backpotred from upstream +# Bugzilla: rhbz#1212357 +# Original fix: https://www.sqlite.org/src/info/aeca95ac77f6f320 + +diff -up sqlite-src-3071700/src/printf.c.old sqlite-src-3071700/src/printf.c +--- sqlite-src-3071700/src/printf.c.old 2015-07-03 10:54:17.644940587 +0200 ++++ sqlite-src-3071700/src/printf.c 2015-07-03 11:52:50.704122467 +0200 +@@ -233,14 +233,17 @@ void sqlite3VXPrintf( + width = va_arg(ap,int); + if( width<0 ){ + flag_leftjustify = 1; +- width = -width; ++ width = width >= -2147483647 ? -width : 0; + } + c = *++fmt; + }else{ ++ unsigned wx = 0; + while( c>='0' && c<='9' ){ +- width = width*10 + c - '0'; ++ wx = wx*10 + c - '0'; + c = *++fmt; + } ++ testcase( wx>0x7fffffff ); ++ width = wx & 0x7fffffff; + } + /* Get the precision */ + if( c=='.' ){ +@@ -248,13 +251,18 @@ void sqlite3VXPrintf( + c = *++fmt; + if( c=='*' ){ + precision = va_arg(ap,int); +- if( precision<0 ) precision = -precision; + c = *++fmt; ++ if( precision<0 ) { ++ precision = precision >= -2147483647 ? -precision : -1; ++ } + }else{ ++ unsigned px = 0; + while( c>='0' && c<='9' ){ +- precision = precision*10 + c - '0'; ++ px = px*10 + c - '0'; + c = *++fmt; + } ++ testcase( px>0x7fffffff ); ++ precision = px & 0x7fffffff; + } + }else{ + precision = -1; +@@ -418,7 +426,8 @@ void sqlite3VXPrintf( + for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1); + #else + /* It makes more sense to use 0.5 */ +- for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1){} ++ testcase( precision>0xfff ); ++ for(idx=precision&0xfff, rounder=0.5; idx>0; idx--, rounder*=0.1){} + #endif + if( xtype==etFLOAT ) realvalue += rounder; + /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */ +@@ -474,8 +483,10 @@ void sqlite3VXPrintf( + }else{ + e2 = exp; + } +- if( e2+precision+width > etBUFSIZE - 15 ){ +- bufpt = zExtra = sqlite3Malloc( e2+precision+width+15 ); ++ if( e2+(i64)precision+(i64)width > etBUFSIZE - 15 ){ ++ bufpt = zExtra = sqlite3Malloc( ++ e2+(i64)precision+(i64)width+15 ++ ); + if( bufpt==0 ){ + pAccum->mallocFailed = 1; + return; + +diff -up sqlite-src-3071700/test/printf.test.old sqlite-src-3071700/test/printf.test +--- sqlite-src-3071700/test/printf.test.old 2015-07-03 10:32:28.552140602 +0200 ++++ sqlite-src-3071700/test/printf.test 2015-07-03 10:35:15.858079592 +0200 +@@ -472,6 +472,18 @@ do_test printf-1.16.7 { + sqlite3_mprintf_int {abc: (%#6d) (%#6x) (%#6o) :xyz}\ + 0xff676981 0xff676981 0xff676981 + } {abc: (-9999999) (0xff676981) (037731664601) :xyz} ++do_test printf-1.17.1 { ++ sqlite3_mprintf_int {abd: %2147483647d %2147483647x %2147483647o} 1 1 1 ++} {} ++do_test printf-1.17.2 { ++ sqlite3_mprintf_int {abd: %*d %x} 2147483647 1 1 ++} {} ++do_test printf-1.17.3 { ++ sqlite3_mprintf_int {abd: %*d %x} -2147483648 1 1 ++} {abd: 1 1} ++do_test printf-1.17.4 { ++ sqlite3_mprintf_int {abd: %.2147483648d %x %x} 1 1 1 ++} {/.*/} + do_test printf-2.1.1.1 { + sqlite3_mprintf_double {abc: (%*.*f) :xyz} 1 1 0.001 + } {abc: (0.0) :xyz} +@@ -526,6 +538,9 @@ do_test printf-2.1.2.8 { + do_test printf-2.1.2.9 { + sqlite3_mprintf_double {abc: %d %d (%1.1g) :xyz} 1 1 1.0e-20 + } {abc: 1 1 (1e-20) :xyz} ++do_test printf-2.1.2.10 { ++ sqlite3_mprintf_double {abc: %*.*f} 2000000000 1000000000 1.0e-20 ++} {abc: } + do_test printf-2.1.3.1 { + sqlite3_mprintf_double {abc: (%*.*f) :xyz} 1 1 1.0 + } {abc: (1.0) :xyz} +@@ -3466,6 +3481,15 @@ do_test printf-3.5 { + do_test printf-3.6 { + sqlite3_mprintf_str {%d %d A String: (%-30s)} 1 2 {This is the string} + } [format {%d %d A String: (%-30s)} 1 2 {This is the string}] ++do_test printf-3.7 { ++ sqlite3_mprintf_str {%d A String: (%*s)} 1 2147483647 {This is the string} ++} [] ++do_test printf-3.8 { ++ sqlite3_mprintf_str {%d A String: (%*s)} 1 -2147483648 {This is the string} ++} {1 A String: (This is the string)} ++do_test printf-3.9 { ++ sqlite3_mprintf_str {%d A String: (%.*s)} 1 -2147483648 {This is the string} ++} {1 A String: (This is the string)} + do_test snprintf-3.11 { + sqlite3_snprintf_str 2 {x%d %d %s} 10 10 {This is the string} + } {x} +@@ -3685,6 +3709,9 @@ do_test printf-13.5 { + do_test printf-13.6 { + sqlite3_mprintf_hexdouble %.20f fff8000000000000 + } {NaN} ++do_test printf-13.7 { ++ sqlite3_mprintf_hexdouble %2147483648.10000f 4693b8b5b5056e17 ++} {/100000000000000000000000000000000.00/} + + do_test printf-14.1 { + sqlite3_mprintf_str {abc-%y-123} 0 0 {not used} diff --git a/SOURCES/sqlite-3.7.17-collation-sequence.patch b/SOURCES/sqlite-3.7.17-collation-sequence.patch new file mode 100644 index 0000000..0f4abb0 --- /dev/null +++ b/SOURCES/sqlite-3.7.17-collation-sequence.patch @@ -0,0 +1,177 @@ +# Fix a problem causing collation sequence names to be dequoted multiple times +# under some circumstances. +# Upstream original patch: https://www.sqlite.org/src/info/eddc05e7bb31fae7 + +diff -up sqlite-src-3071700/src/expr.c.old sqlite-src-3071700/src/expr.c +--- sqlite-src-3071700/src/expr.c.old 2015-07-23 10:26:11.220420294 +0200 ++++ sqlite-src-3071700/src/expr.c 2015-07-23 10:26:47.468601833 +0200 +@@ -65,9 +65,9 @@ char sqlite3ExprAffinity(Expr *pExpr){ + ** If a memory allocation error occurs, that fact is recorded in pParse->db + ** and the pExpr parameter is returned unchanged. + */ +-Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr *pExpr, Token *pCollName){ ++Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr *pExpr, Token *pCollName, int dequote){ + if( pCollName->n>0 ){ +- Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, 1); ++ Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote); + if( pNew ){ + pNew->pLeft = pExpr; + pNew->flags |= EP_Collate; +@@ -81,7 +81,7 @@ Expr *sqlite3ExprAddCollateString(Parse + assert( zC!=0 ); + s.z = zC; + s.n = sqlite3Strlen30(s.z); +- return sqlite3ExprAddCollateToken(pParse, pExpr, &s); ++ return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0); + } + + /* +diff -up sqlite-src-3071700/src/parse.y.old sqlite-src-3071700/src/parse.y +--- sqlite-src-3071700/src/parse.y.old 2015-07-23 10:27:00.595682612 +0200 ++++ sqlite-src-3071700/src/parse.y 2015-07-23 10:27:47.850973405 +0200 +@@ -818,7 +818,7 @@ expr(A) ::= VARIABLE(X). { + spanSet(&A, &X, &X); + } + expr(A) ::= expr(E) COLLATE ids(C). { +- A.pExpr = sqlite3ExprAddCollateToken(pParse, E.pExpr, &C); ++ A.pExpr = sqlite3ExprAddCollateToken(pParse, E.pExpr, &C, 1); + A.zStart = E.zStart; + A.zEnd = &C.z[C.n]; + } +@@ -1143,14 +1143,14 @@ uniqueflag(A) ::= . {A = OE_None; + idxlist_opt(A) ::= . {A = 0;} + idxlist_opt(A) ::= LP idxlist(X) RP. {A = X;} + idxlist(A) ::= idxlist(X) COMMA nm(Y) collate(C) sortorder(Z). { +- Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C); ++ Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C, 1); + A = sqlite3ExprListAppend(pParse,X, p); + sqlite3ExprListSetName(pParse,A,&Y,1); + sqlite3ExprListCheckLength(pParse, A, "index"); + if( A ) A->a[A->nExpr-1].sortOrder = (u8)Z; + } + idxlist(A) ::= nm(Y) collate(C) sortorder(Z). { +- Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C); ++ Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C, 1); + A = sqlite3ExprListAppend(pParse,0, p); + sqlite3ExprListSetName(pParse, A, &Y, 1); + sqlite3ExprListCheckLength(pParse, A, "index"); +diff -up sqlite-src-3071700/src/sqliteInt.h.old sqlite-src-3071700/src/sqliteInt.h +--- sqlite-src-3071700/src/sqliteInt.h.old 2015-07-23 10:34:54.516598956 +0200 ++++ sqlite-src-3071700/src/sqliteInt.h 2015-07-23 10:35:12.908712134 +0200 +@@ -3103,7 +3103,7 @@ int sqlite3ReadSchema(Parse *pParse); + CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); + CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); + CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); +-Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, Token*); ++Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, Token*, int); + Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*); + Expr *sqlite3ExprSkipCollate(Expr*); + int sqlite3CheckCollSeq(Parse *, CollSeq *); +diff -up sqlite-src-3071700/src/where.c.old sqlite-src-3071700/src/where.c +--- sqlite-src-3071700/src/where.c.old 2015-07-23 10:35:22.365770330 +0200 ++++ sqlite-src-3071700/src/where.c 2015-07-23 10:38:03.460761652 +0200 +@@ -1389,7 +1389,7 @@ static void exprAnalyze( + Expr *pNewExpr2; + int idxNew1; + int idxNew2; +- Token sCollSeqName; /* Name of collating sequence */ ++ const char *zCollSeqName; /* Name of collating sequence */ + + pLeft = pExpr->x.pList->a[1].pExpr; + pStr2 = sqlite3ExprDup(db, pStr1, 0); +@@ -1411,11 +1411,10 @@ static void exprAnalyze( + } + *pC = c + 1; + } +- sCollSeqName.z = noCase ? "NOCASE" : "BINARY"; +- sCollSeqName.n = 6; ++ zCollSeqName = noCase ? "NOCASE" : "BINARY"; + pNewExpr1 = sqlite3ExprDup(db, pLeft, 0); + pNewExpr1 = sqlite3PExpr(pParse, TK_GE, +- sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName), ++ sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName), + pStr1, 0); + idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC); + testcase( idxNew1==0 ); +@@ -1421,7 +1421,7 @@ static void exprAnalyze( + exprAnalyze(pSrc, pWC, idxNew1); + pNewExpr2 = sqlite3ExprDup(db, pLeft, 0); + pNewExpr2 = sqlite3PExpr(pParse, TK_LT, +- sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName), ++ sqlite3ExprAddCollateString(pParse,pNewExpr2,zCollSeqName), + pStr2, 0); + idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC); + testcase( idxNew2==0 ); +diff -up sqlite-src-3071700/test/collate1.test.old sqlite-src-3071700/test/collate1.test +--- sqlite-src-3071700/test/collate1.test.old 2015-07-23 10:38:58.858102547 +0200 ++++ sqlite-src-3071700/test/collate1.test 2015-07-23 10:40:30.474666325 +0200 +@@ -10,12 +10,13 @@ + # + #*********************************************************************** + # This file implements regression tests for SQLite library. The +-# focus of this script is page cache subsystem. ++# focus of this script is testing collation sequences. + # + # $Id: collate1.test,v 1.5 2007/02/01 23:02:46 drh Exp $ + + set testdir [file dirname $argv0] + source $testdir/tester.tcl ++set testprefix collate1 + + # + # Tests are roughly organised as follows: +@@ -305,4 +306,54 @@ do_test collate1-4.5 { + } + } {} + ++#------------------------------------------------------------------------- ++# Fix problems with handling collation sequences named '"""'. ++# ++do_execsql_test 6.1 { ++ SELECT """"""""; ++} {\"\"\"} ++ ++do_catchsql_test 6.2 { ++ CREATE TABLE x1(a); ++ SELECT a FROM x1 ORDER BY a COLLATE """"""""; ++} {1 {no such collation sequence: """}} ++ ++do_catchsql_test 6.3 { ++ SELECT a FROM x1 ORDER BY 1 COLLATE """"""""; ++} {1 {no such collation sequence: """}} ++ ++do_catchsql_test 6.4 { ++ SELECT 0 UNION SELECT 0 ORDER BY 1 COLLATE """"""""; ++} {1 {no such collation sequence: """}} ++ ++db collate {"""} [list string compare -nocase] ++ ++do_execsql_test 6.5 { ++ PRAGMA foreign_keys = ON; ++ CREATE TABLE p1(a PRIMARY KEY COLLATE '"""'); ++ CREATE TABLE c1(x, y REFERENCES p1); ++} {} ++ ++do_execsql_test 6.6 { ++ INSERT INTO p1 VALUES('abc'); ++ INSERT INTO c1 VALUES(1, 'ABC'); ++} ++ ++ifcapable foreignkey { ++ do_catchsql_test 6.7 { ++ DELETE FROM p1 WHERE rowid = 1 ++ } {1 {foreign key constraint failed}} ++} ++ ++do_execsql_test 6.8 { ++ INSERT INTO p1 VALUES('abb'); ++ INSERT INTO p1 VALUES('wxz'); ++ INSERT INTO p1 VALUES('wxy'); ++ ++ INSERT INTO c1 VALUES(2, 'abb'); ++ INSERT INTO c1 VALUES(3, 'wxz'); ++ INSERT INTO c1 VALUES(4, 'WXY'); ++ SELECT x, y FROM c1 ORDER BY y COLLATE """"""""; ++} {2 abb 1 ABC 4 WXY 3 wxz} ++ + finish_test diff --git a/SOURCES/sqlite-3.7.17-large-pages.patch b/SOURCES/sqlite-3.7.17-large-pages.patch new file mode 100644 index 0000000..fb30142 --- /dev/null +++ b/SOURCES/sqlite-3.7.17-large-pages.patch @@ -0,0 +1,399 @@ +Backport of upstream commit db7d62c8d5: + +Avoid attempting to mmap memory from an offset that is not a multiple of +the system page size on systems with page sizes larger than 32KB. + +https://www.sqlite.org/src/info/db7d62c8d58eb1e8654a762c9b199ae4e2759038 + +Index: src/os_unix.c +================================================================== +--- src/os_unix.c ++++ src/os_unix.c +@@ -321,10 +321,11 @@ + return geteuid() ? 0 : fchown(fd,uid,gid); + } + + /* Forward reference */ + static int openDirectory(const char*, int*); ++static int unixGetpagesize(void); + + /* + ** Many system calls are accessed through pointer-to-functions so that + ** they may be overridden at runtime to facilitate fault injection during + ** testing and sandboxing. The following array holds the names and pointers +@@ -443,10 +444,13 @@ + { "mremap", (sqlite3_syscall_ptr)mremap, 0 }, + #else + { "mremap", (sqlite3_syscall_ptr)0, 0 }, + #endif + #define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent) ++ ++ { "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 }, ++#define osGetpagesize ((int(*)(void))aSyscall[24].pCurrent) + + }; /* End of the overrideable system calls */ + + /* + ** This is the xSetSystemCall() method of sqlite3_vfs for all of the +@@ -4103,10 +4107,40 @@ + #endif + + return rc; + } + ++/* ++** Return the system page size. ++** ++** This function should not be called directly by other code in this file. ++** Instead, it should be called via macro osGetpagesize(). ++*/ ++static int unixGetpagesize(void){ ++#if defined(_BSD_SOURCE) ++ return getpagesize(); ++#else ++ return (int)sysconf(_SC_PAGESIZE); ++#endif ++} ++ ++/* ++** Return the minimum number of 32KB shm regions that should be mapped at ++** a time, assuming that each mapping must be an integer multiple of the ++** current system page-size. ++** ++** Usually, this is 1. The exception seems to be systems that are configured ++** to use 64KB pages - in this case each mapping must cover at least two ++** shm regions. ++*/ ++static int unixShmRegionPerMap(void){ ++ int shmsz = 32*1024; /* SHM region size */ ++ int pgsz = osGetpagesize(); /* System page size */ ++ assert( ((pgsz-1)&pgsz)==0 ); /* Page size must be a power of 2 */ ++ if( pgszpInode->pShmNode; + assert( unixMutexHeld() ); + if( p && p->nRef==0 ){ ++ int nShmPerMap = unixShmRegionPerMap(); + int i; + assert( p->pInode==pFd->pInode ); + sqlite3_mutex_free(p->mutex); +- for(i=0; inRegion; i++){ ++ for(i=0; inRegion; i+=nShmPerMap){ + if( p->h>=0 ){ + osMunmap(p->apRegion[i], p->szRegion); + }else{ + sqlite3_free(p->apRegion[i]); + } +@@ -4324,10 +4359,12 @@ + ){ + unixFile *pDbFd = (unixFile*)fd; + unixShm *p; + unixShmNode *pShmNode; + int rc = SQLITE_OK; ++ int nShmPerMap = unixShmRegionPerMap(); ++ int nReqRegion; + + /* If the shared-memory file has not yet been opened, open it now. */ + if( pDbFd->pShm==0 ){ + rc = unixOpenSharedMemory(pDbFd); + if( rc!=SQLITE_OK ) return rc; +@@ -4339,13 +4376,16 @@ + assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); + assert( pShmNode->pInode==pDbFd->pInode ); + assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 ); + assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 ); + +- if( pShmNode->nRegion<=iRegion ){ ++ /* Minimum number of regions required to be mapped. */ ++ nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap; ++ ++ if( pShmNode->nRegionszRegion = szRegion; + + if( pShmNode->h>=0 ){ +@@ -4390,21 +4430,23 @@ + } + } + + /* Map the requested memory region into this processes address space. */ + apNew = (char **)sqlite3_realloc( +- pShmNode->apRegion, (iRegion+1)*sizeof(char *) ++ pShmNode->apRegion, nReqRegion*sizeof(char *) + ); + if( !apNew ){ + rc = SQLITE_IOERR_NOMEM; + goto shmpage_out; + } + pShmNode->apRegion = apNew; +- while(pShmNode->nRegion<=iRegion){ ++ while( pShmNode->nRegionh>=0 ){ +- pMem = osMmap(0, szRegion, ++ pMem = osMmap(0, nMap, + pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, + MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion + ); + if( pMem==MAP_FAILED ){ + rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename); +@@ -4416,12 +4458,15 @@ + rc = SQLITE_NOMEM; + goto shmpage_out; + } + memset(pMem, 0, szRegion); + } +- pShmNode->apRegion[pShmNode->nRegion] = pMem; +- pShmNode->nRegion++; ++ ++ for(i=0; iapRegion[pShmNode->nRegion+i] = &((char*)pMem)[szRegion*i]; ++ } ++ pShmNode->nRegion += nShmPerMap; + } + } + + shmpage_out: + if( pShmNode->nRegion>iRegion ){ +@@ -4631,25 +4676,10 @@ + #endif + } + + #if SQLITE_MAX_MMAP_SIZE>0 + /* +-** Return the system page size. +-*/ +-static int unixGetPagesize(void){ +-#if HAVE_MREMAP +- return 512; +-#elif defined(_BSD_SOURCE) +- return getpagesize(); +-#else +- return (int)sysconf(_SC_PAGESIZE); +-#endif +-} +-#endif /* SQLITE_MAX_MMAP_SIZE>0 */ +- +-#if SQLITE_MAX_MMAP_SIZE>0 +-/* + ** Attempt to set the size of the memory mapping maintained by file + ** descriptor pFd to nNew bytes. Any existing mapping is discarded. + ** + ** If successful, this function sets the following variables: + ** +@@ -4680,12 +4712,16 @@ + assert( MAP_FAILED!=0 ); + + if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE; + + if( pOrig ){ +- const int szSyspage = unixGetPagesize(); ++#if HAVE_MREMAP ++ i64 nReuse = pFd->mmapSize; ++#else ++ const int szSyspage = osGetpagesize(); + i64 nReuse = (pFd->mmapSize & ~(szSyspage-1)); ++#endif + u8 *pReq = &pOrig[nReuse]; + + /* Unmap any pages of the existing mapping that cannot be reused. */ + if( nReuse!=nOrig ){ + osMunmap(pReq, nOrig-nReuse); +@@ -7427,11 +7463,11 @@ + }; + unsigned int i; /* Loop counter */ + + /* Double-check that the aSyscall[] array has been constructed + ** correctly. See ticket [bb3a86e890c8e96ab] */ +- assert( ArraySize(aSyscall)==24 ); ++ assert( ArraySize(aSyscall)==25 ); + + /* Register all VFSes defined in the aVfs[] array */ + for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ + sqlite3_vfs_register(&aVfs[i], i==0); + } + +Index: src/test_syscall.c +================================================================== +--- src/test_syscall.c ++++ src/test_syscall.c +@@ -65,10 +65,15 @@ + ** Return true if the named system call exists. Or false otherwise. + ** + ** test_syscall list + ** Return a list of all system calls. The list is constructed using + ** the xNextSystemCall() VFS method. ++** ++** test_syscall pagesize PGSZ ++** If PGSZ is a power of two greater than 256, install a wrapper around ++** OS function getpagesize() that reports the system page size as PGSZ. ++** Or, if PGSZ is less than zero, remove any wrapper already installed. + */ + + #include "sqliteInt.h" + #include "sqlite3.h" + #include "tcl.h" +@@ -87,11 +92,13 @@ + + static struct TestSyscallGlobal { + int bPersist; /* 1 for persistent errors, 0 for transient */ + int nCount; /* Fail after this many more calls */ + int nFail; /* Number of failures that have occurred */ +-} gSyscall = { 0, 0 }; ++ int pgsz; ++ sqlite3_syscall_ptr orig_getpagesize; ++} gSyscall = { 0, 0, 0, 0, 0 }; + + static int ts_open(const char *, int, int); + static int ts_close(int fd); + static int ts_access(const char *zPath, int mode); + static char *ts_getcwd(char *zPath, size_t nPath); +@@ -647,10 +654,49 @@ + + pVfs = sqlite3_vfs_find(0); + Tcl_SetObjResult(interp, Tcl_NewStringObj(pVfs->zName, -1)); + return TCL_OK; + } ++ ++static int ts_getpagesize(void){ ++ return gSyscall.pgsz; ++} ++ ++static int test_syscall_pagesize( ++ void * clientData, ++ Tcl_Interp *interp, ++ int objc, ++ Tcl_Obj *CONST objv[] ++){ ++ sqlite3_vfs *pVfs = sqlite3_vfs_find(0); ++ int pgsz; ++ if( objc!=3 ){ ++ Tcl_WrongNumArgs(interp, 2, objv, "PGSZ"); ++ return TCL_ERROR; ++ } ++ if( Tcl_GetIntFromObj(interp, objv[2], &pgsz) ){ ++ return TCL_ERROR; ++ } ++ ++ if( pgsz<0 ){ ++ if( gSyscall.orig_getpagesize ){ ++ pVfs->xSetSystemCall(pVfs, "getpagesize", gSyscall.orig_getpagesize); ++ } ++ }else{ ++ if( pgsz<512 || (pgsz & (pgsz-1)) ){ ++ Tcl_AppendResult(interp, "pgsz out of range", 0); ++ return TCL_ERROR; ++ } ++ gSyscall.orig_getpagesize = pVfs->xGetSystemCall(pVfs, "getpagesize"); ++ gSyscall.pgsz = pgsz; ++ pVfs->xSetSystemCall( ++ pVfs, "getpagesize", (sqlite3_syscall_ptr)ts_getpagesize ++ ); ++ } ++ ++ return TCL_OK; ++} + + static int test_syscall( + void * clientData, + Tcl_Interp *interp, + int objc, +@@ -666,10 +712,11 @@ + { "reset", test_syscall_reset }, + { "errno", test_syscall_errno }, + { "exists", test_syscall_exists }, + { "list", test_syscall_list }, + { "defaultvfs", test_syscall_defaultvfs }, ++ { "pagesize", test_syscall_pagesize }, + { 0, 0 } + }; + int iCmd; + int rc; + + +Index: test/syscall.test +================================================================== +--- test/syscall.test ++++ test/syscall.test +@@ -59,10 +59,11 @@ + foreach s { + open close access getcwd stat fstat ftruncate + fcntl read pread write pwrite fchmod fallocate + pread64 pwrite64 unlink openDirectory mkdir rmdir + statvfs fchown umask mmap munmap mremap ++ getpagesize + } { + if {[test_syscall exists $s]} {lappend syscall_list $s} + } + do_test 3.1 { lsort [test_syscall list] } [lsort $syscall_list] + + +ADDED test/wal64k.test +Index: test/wal64k.test +================================================================== +--- test/wal64k.test ++++ test/wal64k.test +@@ -0,0 +1,47 @@ ++# 2010 April 13 ++# ++# 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. The ++# focus of this file is testing the operation of the library in ++# "PRAGMA journal_mode=WAL" mode. ++# ++ ++set testdir [file dirname $argv0] ++source $testdir/tester.tcl ++set testprefix wal64k ++ ++ifcapable !wal {finish_test ; return } ++ ++db close ++test_syscall pagesize 65536 ++sqlite3 db test.db ++ ++do_execsql_test 1.0 { ++ PRAGMA journal_mode = WAL; ++ CREATE TABLE t1(x); ++ CREATE INDEX i1 ON t1(x); ++} {wal} ++do_test 1.1 { file size test.db-shm } {65536} ++ ++do_test 1.2 { ++ execsql BEGIN ++ while {[file size test.db-shm]==65536} { ++ execsql { INSERT INTO t1 VALUES( randstr(900,1100) ) } ++ } ++ execsql COMMIT ++ file size test.db-shm ++} {131072} ++ ++integrity_check 1.3 ++ ++db close ++test_syscall pagesize -1 ++finish_test ++ + diff --git a/SOURCES/sqlite-3.7.17-vdbe-free.patch b/SOURCES/sqlite-3.7.17-vdbe-free.patch new file mode 100644 index 0000000..2462aa3 --- /dev/null +++ b/SOURCES/sqlite-3.7.17-vdbe-free.patch @@ -0,0 +1,31 @@ +# Ensure that comparison operators do not mess up the MEM_Dyn flag on registers +# when reverting affinity changes. +# Upstream original patch: https://www.sqlite.org/src/info/02e3c88fbf6abdcf + +diff -up sqlite-src-3071700/src/vdbe.c.old sqlite-src-3071700/src/vdbe.c +--- sqlite-src-3071700/src/vdbe.c.old 2015-07-23 11:54:21.781280736 +0200 ++++ sqlite-src-3071700/src/vdbe.c 2015-07-23 11:58:24.829703086 +0200 +@@ -1852,7 +1852,13 @@ case OP_Ge: { /* same as TK_ + affinity = pOp->p5 & SQLITE_AFF_MASK; + if( affinity ){ + applyAffinity(pIn1, affinity, encoding); ++ testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) ); ++ flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask); ++ + applyAffinity(pIn3, affinity, encoding); ++ testcase( (flags3&MEM_Dyn) != (pIn3->flags&MEM_Dyn) ); ++ flags3 = (pIn3->flags & ~MEM_TypeMask) | (flags3 & MEM_TypeMask); ++ + if( db->mallocFailed ) goto no_mem; + } + +@@ -1881,7 +1887,9 @@ case OP_Ge: { /* same as TK_ + } + + /* Undo any changes made by applyAffinity() to the input registers. */ ++ assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) ); + pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (flags1&MEM_TypeMask); ++ assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) ); + pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (flags3&MEM_TypeMask); + break; + } diff --git a/SPECS/sqlite.spec b/SPECS/sqlite.spec index dae5dcc..25dc555 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}.1 License: Public Domain Group: Applications/Databases URL: http://www.sqlite.org/ @@ -32,6 +32,13 @@ Patch4: sqlite-3.7.15-no-malloc-usable-size.patch Patch5: sqlite-3.7.16-man-missing-options.patch # Fix for test failure on aarch64 Patch6: sqlite-3.7.17-real-cast.patch +# Fix for 64k pages +Patch7: sqlite-3.7.17-large-pages.patch +# Fixes for CVE-2015-3415 CVE-2015-3414 CVE-2015-3416 sqlite: various flaws +# https://bugzilla.redhat.com/show_bug.cgi?id=1244732 +Patch8: sqlite-3.7.17-collation-sequence.patch +Patch9: sqlite-3.7.17-vdbe-free.patch +Patch10: sqlite-3.7.14-printf-overflow.patch BuildRequires: ncurses-devel readline-devel glibc-devel BuildRequires: autoconf @@ -107,6 +114,10 @@ This package contains the tcl modules for %{name}. %patch4 -p1 -b .no-malloc-usable-size %patch5 -p1 -b .man-missing-options %patch6 -p1 -b .largest-integer +%patch7 -p0 -b .large-pages +%patch8 -p1 -b .collation +%patch9 -p1 -b .vdbe-free +%patch10 -p1 -b .printf-overflow # Remove cgi-script erroneously included in sqlite-doc-3070500 rm -f %{name}-doc-%{realver}/search @@ -197,6 +208,19 @@ rm -rf $RPM_BUILD_ROOT %endif %changelog +* Thu Jul 23 2015 Jan Stanek 3.7.17-6.1 +- Fixes for CVE-2015-3415 CVE-2015-3414 CVE-2015-3416 + Resolves: rhbz#1244731 + +* Tue Oct 21 2014 Dan HorĂ¡k - 3.7.17-6 +- Release bump for ppc64le + +* Tue Aug 19 2014 Jan Stanek - 3.7.17-5 +- Release bump + +* Thu Jul 10 2014 Yaakov Selkowitz - 3.7.17-4.1 +- Backport 64k page fix from latest upstream (#1118151) + * Fri Jan 24 2014 Daniel Mach - 3.7.17-4 - Mass rebuild 2014-01-24