]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Experimental changes to prevent buffer overreads when parsing a corrupt no-overread
authordrh <drh@noemail.net>
Tue, 3 Jan 2012 21:33:26 +0000 (21:33 +0000)
committerdrh <drh@noemail.net>
Tue, 3 Jan 2012 21:33:26 +0000 (21:33 +0000)
database file.

FossilOrigin-Name: 9e5add51eead8e2e938870df0d0071854cadf414

manifest
manifest.uuid
src/btree.c

index 10533ad79f3a8f8f13273a8dde9cf20578879674..b283941f02663f074f96e3fe458ee5f35f6d8092 100644 (file)
--- 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
index 9f17d9d5afb61e43bdb43a3bdd1f36a3ea2c8fd4..603e49f01b475bd0f3ff1e0ba2f8ae2f60b62fb6 100644 (file)
@@ -1 +1 @@
-d73e93cfdc9441ade77b796dcdcf6eeb753cb398
\ No newline at end of file
+9e5add51eead8e2e938870df0d0071854cadf414
\ No newline at end of file
index 7c043ccf759094ef7de49366d935afb962c7dcca..e8d4ac72a7776990814b4e00b2b2f6ac5c34e64c 100644 (file)
@@ -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 && pIter<pEnd );
+    pEnd = &pX[9];
+    while( (*pX++)&0x80 && pX<pEnd );
   }else{
-    pIter += getVarint32(pIter, nSize);
+    pX += getVarint32(pX, nSize);
   }
 
   testcase( nSize==pPage->maxLocal );
@@ -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 ){