From 00ce39458dba2c27644b138acf52b1ddd1993cc7 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 6 Dec 2009 03:35:51 +0000 Subject: [PATCH] Enhanced detection of database corruption in btree.c:allocateSpace(). FossilOrigin-Name: 5a511f98877f0f7f12d336b7831f3da901856b02 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/btree.c | 12 ++++++++++-- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index cf262eefdf..ab1ae10f57 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Fix\sto\scheck-in\s[f221f31eff]:\s\sMake\ssure\slocal\svariable\src\sis\sdeclared\seven\nwhen\scompiled\swithout\sSQLITE_DEBUG. -D 2009-12-05T18:34:09 +C Enhanced\sdetection\sof\sdatabase\scorruption\sin\sbtree.c:allocateSpace(). +D 2009-12-06T03:35:51 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in c5827ead754ab32b9585487177c93bb00b9497b3 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -111,7 +111,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 744e98359dfc79fed43e8dec911e33e108b06aae F src/bitvec.c 06ad2c36a9c3819c0b9cbffec7b15f58d5d834e0 F src/btmutex.c 96a12f50f7a17475155971a241d85ec5171573ff -F src/btree.c 92de746507c4721f669f07299a1a59767928fbc7 +F src/btree.c efdef3953c49e28f8b8fa9cc0ac5754cc1a7489a F src/btree.h 7944a9dac59eb3e541aad45fd2747f1051e7c63d F src/btreeInt.h 54f4245decd0409ea52cf9aee422d3d761d7ac10 F src/build.c a48e74d24897100017d39ceba5de255e53ec9488 @@ -779,14 +779,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P f221f31efff83651b9af295b98cfe98bcba3ad54 -R b549c27ca72ac44e6657d205834c76f6 +P 7a9a35327c55452e858335933ce11669fc888aeb +R 0f3ea22a321de0315884a4805815ec31 U drh -Z 95584794328928263ec6a21642e1a324 +Z 107d016b4cea97422dcf94676d1dec5c -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFLGqekoxKgR168RlERAu1uAJ904gXhoqKU7OrxFAbR2obwNiS6ggCeNNu1 -HULei/GriWsYUf7WTMJ/HfA= -=g6iZ +iD8DBQFLGyaaoxKgR168RlERAqRoAJ9BqTXTTVZfQIaYlvy+t0KsL1+C7ACfZ/dm +hnb7PcWLb+b0XHgfDg673P4= +=+6jS -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 15eb721fb3..89f0f2bfcb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7a9a35327c55452e858335933ce11669fc888aeb \ No newline at end of file +5a511f98877f0f7f12d336b7831f3da901856b02 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 3952f9c32d..385c511aa7 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1143,6 +1143,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ int top; /* First byte of cell content area */ int gap; /* First byte of gap between cell pointers and cell content */ int rc; /* Integer return code */ + int usableSize; /* Usable size of the page */ assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( pPage->pBt ); @@ -1150,7 +1151,8 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ assert( nByte>=0 ); /* Minimum cell size is 4 */ assert( pPage->nFree>=nByte ); assert( pPage->nOverflow==0 ); - assert( nBytepBt->usableSize-8 ); + usableSize = pPage->pBt->usableSize; + assert( nByte < usableSize-8 ); nFrag = data[hdr+7]; assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf ); @@ -1173,7 +1175,11 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ */ int pc, addr; for(addr=hdr+1; (pc = get2byte(&data[addr]))>0; addr=pc){ - int size = get2byte(&data[pc+2]); /* Size of free slot */ + int size; /* Size of the free slot */ + if( pc>usableSize-4 || pc=nByte ){ int x = size - nByte; testcase( x==4 ); @@ -1183,6 +1189,8 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ ** fragmented bytes within the page. */ memcpy(&data[addr], &data[pc], 2); data[hdr+7] = (u8)(nFrag + x); + }else if( size+pc > usableSize ){ + return SQLITE_CORRUPT_BKPT; }else{ /* The slot remains on the free-list. Reduce its size to account ** for the portion used by the new allocation. */