From: drh Date: Tue, 3 Jan 2012 21:33:26 +0000 (+0000) Subject: Experimental changes to prevent buffer overreads when parsing a corrupt X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fheads%2Fno-overread;p=thirdparty%2Fsqlite.git Experimental changes to prevent buffer overreads when parsing a corrupt database file. FossilOrigin-Name: 9e5add51eead8e2e938870df0d0071854cadf414 --- diff --git a/manifest b/manifest index 10533ad79f..b283941f02 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sfilenames\spassed\sinto\ssqlite3OsOpen()\salways\shave\sthe\sextra\nzero-terminators\sneeded\sby\ssqlite3_uri_parameter(). -D 2012-01-03T14:50:45.695 +C Experimental\schanges\sto\sprevent\sbuffer\soverreads\swhen\sparsing\sa\scorrupt\ndatabase\sfile. +D 2012-01-03T21:33:26.558 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -125,7 +125,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 80d713109d295cc3a674f55cfe6446afb9b024ad F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 8f683b1fcfd9ac92efa781c9c56c537e080a7117 +F src/btree.c 30dd27d35ab4982d91901f1b89902ece0d74dda9 F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce F src/btreeInt.h 6e57bacaa4feb7dd56719678133e63a7c289c6e7 F src/build.c 8915bb6d72ead998f94c2756ea8d143c77709b70 @@ -986,7 +986,10 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 03d8362cd2cadab8e1cc5b18a3194152f2bd0a84 -R bab430cac57fc8357d76990e6c780f64 +P d73e93cfdc9441ade77b796dcdcf6eeb753cb398 +R ea533e4f6be9c90c4fd282e6bca1d593 +T *branch * no-overread +T *sym-no-overread * +T -sym-trunk * U drh -Z 242be7d816ac09f954d1b623be157dd8 +Z 2215f4dcb6f284947211bca4b2dda076 diff --git a/manifest.uuid b/manifest.uuid index 9f17d9d5af..603e49f01b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d73e93cfdc9441ade77b796dcdcf6eeb753cb398 \ No newline at end of file +9e5add51eead8e2e938870df0d0071854cadf414 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 7c043ccf75..e8d4ac72a7 100644 --- a/src/btree.c +++ b/src/btree.c @@ -901,10 +901,17 @@ static void btreeParseCellPtr( ){ u16 n; /* Number bytes in cell content header */ u32 nPayload; /* Number of bytes of cell payload */ + u8 cellBuf[20]; assert( sqlite3_mutex_held(pPage->pBt->mutex) ); pInfo->pCell = pCell; + if( pCell >= pPage->aDataEnd - sizeof(cellBuf) && pCell < pPage->aDataEnd ){ + int x = pPage->aDataEnd - pCell; + memcpy(cellBuf, pCell, x); + memset(&cellBuf[x], 0, sizeof(cellBuf)-x); + pCell = cellBuf; + } assert( pPage->leaf==0 || pPage->leaf==1 ); n = pPage->childPtrSize; assert( n==4-4*pPage->leaf ); @@ -977,8 +984,9 @@ static void btreeParseCell( ** the space used by the cell pointer. */ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ - u8 *pIter = &pCell[pPage->childPtrSize]; + u8 *pX = pCell; u32 nSize; + u8 cellBuf[25]; #ifdef SQLITE_DEBUG /* The value returned by this function should always be the same as @@ -989,10 +997,17 @@ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ btreeParseCellPtr(pPage, pCell, &debuginfo); #endif + if( pX >= pPage->aDataEnd - sizeof(cellBuf) && pX < pPage->aDataEnd ){ + int x = pPage->aDataEnd - pX; + memcpy(cellBuf, pCell, x); + memset(&cellBuf[x], 0, sizeof(cellBuf)-x); + pX = pCell = cellBuf; + } + pX += pPage->childPtrSize; if( pPage->intKey ){ u8 *pEnd; if( pPage->hasData ){ - pIter += getVarint32(pIter, nSize); + pX += getVarint32(pX, nSize); }else{ nSize = 0; } @@ -1000,10 +1015,10 @@ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ /* pIter now points at the 64-bit integer key value, a variable length ** integer. The following block moves pIter to point at the first byte ** past the end of the key value. */ - pEnd = &pIter[9]; - while( (*pIter++)&0x80 && pItermaxLocal ); @@ -1018,7 +1033,7 @@ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ } nSize += 4; } - nSize += (u32)(pIter - pCell); + nSize += (u32)(pX - pCell); /* The minimum size of any cell is 4 bytes. */ if( nSize<4 ){