From: dan Date: Thu, 10 Jun 2010 06:53:26 +0000 (+0000) Subject: Store the MemPage structure in memory following, instead of preceding, the page data... X-Git-Tag: version-3.7.2~280 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=026e598d0f2c94e0c8a4fb3eaf1aa343297aa74a;p=thirdparty%2Fsqlite.git Store the MemPage structure in memory following, instead of preceding, the page data for cached pages. This reduces the likelihood of a corrupt database page image causing SQLite to read past the end of a buffer. FossilOrigin-Name: 0ce42e76654d9ba52dac74c940d38b17866016ba --- diff --git a/manifest b/manifest index 6279c29d2f..d46b2c1200 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,5 @@ ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -C Remove\sa\scondition\sthat\smust\salways\sbe\strue.\s\sReplace\sit\swith\san\sassert(). -D 2010-06-10T01:07:42 +C Store\sthe\sMemPage\sstructure\sin\smemory\sfollowing,\sinstead\sof\spreceding,\sthe\spage\sdata\sfor\scached\spages.\sThis\sreduces\sthe\slikelihood\sof\sa\scorrupt\sdatabase\spage\simage\scausing\sSQLite\sto\sread\spast\sthe\send\sof\sa\sbuffer. +D 2010-06-10T06:53:27 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -160,7 +157,7 @@ F src/os_win.c 0cf1f571546f165001e2391b5d4a4a16d86977d3 F src/pager.c dde0b7447763299ebc4f27a7c3ab25b3b136c69f F src/pager.h 76466c3a5af56943537f68b1f16567101a0cd1d0 F src/parse.y ace5c7a125d9f2a410e431ee3209034105045f7e -F src/pcache.c ace8f6a5ecd4711cc66a1b23053be7109bd437cf +F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07 F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050 F src/pcache1.c 3a7c28f46a61b43ff0b5c087a7983c154f4b264c F src/pragma.c 423865323a4074f1e0d4ab02af0be014653e8863 @@ -313,7 +310,7 @@ F test/corrupt8.test 9992ef7f67cefc576b92373f6bf5ab8775280f51 F test/corrupt9.test 4aa1cb1ef091cb0e13e89a819c72911631b5176a F test/corruptA.test 38b4f81c16099f6d8fa8b37e188fde76b8243994 F test/corruptB.test d88b500f7994cb2eb9646410c263111e9831f889 -F test/corruptC.test e753c037cd4d92c760de760ddf6db7faea6a2fc2 +F test/corruptC.test c19fcc3693931f2334305d96497092ff6b8f9429 F test/corruptD.test 3ae6e2dc6e2226c6935a8a40d4b5ee3eba75f8c0 F test/corruptE.test 34de490791060d749c933aef3970839df3f63ea9 F test/count.test 454e1ce985c94d13efeac405ce54439f49336163 @@ -821,14 +818,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P ea05b7f929e4696175dbc3ded36dba8ed2a6b575 -R b2aa1ec382260251004c82b1180e6cb4 -U drh -Z c9d9a3c8cddce25be30d2d7e79616c72 ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.6 (GNU/Linux) - -iD8DBQFMEDrhoxKgR168RlERAoNcAJ9ApOQLwNGdKX9r0AgpaNELEJ1wfgCcDI4V -bkS2YGF3Gfz/u96PVSnmtbQ= -=FCD6 ------END PGP SIGNATURE----- +P 7abcd54ec09e8025193d1e0ea57775051d823801 +R 31070636553ae76b50ea1052e3aa5bdb +U dan +Z e8833716b224a38eb8684e00df026f78 diff --git a/manifest.uuid b/manifest.uuid index d3e0b47f60..898440cd6b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7abcd54ec09e8025193d1e0ea57775051d823801 \ No newline at end of file +0ce42e76654d9ba52dac74c940d38b17866016ba \ No newline at end of file diff --git a/src/pcache.c b/src/pcache.c index 5762938ed0..23ea0a7c7d 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -260,15 +260,17 @@ int sqlite3PcacheFetch( if( pPage ){ if( !pPage->pData ){ - memset(pPage, 0, sizeof(PgHdr) + pCache->szExtra); - pPage->pExtra = (void*)&pPage[1]; - pPage->pData = (void *)&((char *)pPage)[sizeof(PgHdr) + pCache->szExtra]; + memset(pPage, 0, sizeof(PgHdr)); + pPage->pData = (void *)&pPage[1]; + pPage->pExtra = (void*)&((char *)pPage->pData)[pCache->szPage]; + memset(pPage->pExtra, 0, pCache->szExtra); pPage->pCache = pCache; pPage->pgno = pgno; } assert( pPage->pCache==pCache ); assert( pPage->pgno==pgno ); - assert( pPage->pExtra==(void *)&pPage[1] ); + assert( pPage->pData==(void *)&pPage[1] ); + assert( pPage->pExtra==(void *)&((char *)&pPage[1])[pCache->szPage] ); if( 0==pPage->nRef ){ pCache->nRef++; diff --git a/test/corruptC.test b/test/corruptC.test index 32a54a18be..821f6e0089 100644 --- a/test/corruptC.test +++ b/test/corruptC.test @@ -276,6 +276,17 @@ do_test corruptC-2.14 { catchsql {DELETE FROM t1 WHERE rowid = (SELECT max(rowid) FROM t1)} } {1 {database disk image is malformed}} +# At one point this particular corrupt database was causing a buffer +# overread. Which caused a crash in a run of all.test once. +# +do_test corruptC-2.15 { + db close + copy_file test.bu test.db + hexio_write test.db 986 b9 + sqlite3 db test.db + catchsql {SELECT count(*) FROM sqlite_master;} +} {1 {malformed database schema (t1i1) - no such table: main.t1}} + # # Now test for a series of quasi-random seeds. # We loop over the entire file size and touch