Fix a case where SQLite may write past the end of a buffer as a result of a corrupted database file.

FossilOrigin-Name: 43321a556031942389ca11b033c1eae46ac6141b
This commit is contained in:
dan 2009-08-14 17:01:22 +00:00
parent 04616bb703
commit 4361e79f14
4 changed files with 41 additions and 22 deletions

View File

@ -1,8 +1,5 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
C Fix\sto\sthe\s"publish.sh"\sscript\sthat\swas\sbroken\sby\sthe\sprevious\scheck-in.
D 2009-08-14T16:15:17
C Fix\sa\scase\swhere\sSQLite\smay\swrite\spast\sthe\send\sof\sa\sbuffer\sas\sa\sresult\sof\sa\scorrupted\sdatabase\sfile.
D 2009-08-14T17:01:22
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 0f7761c5d1c62ae7a841e3393ffaff1fa0f5c00a
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@ -109,7 +106,7 @@ F src/auth.c 802a9439dfa0b8c208b10055cba400e82ef18025
F src/backup.c 6f1c2d9862c8a3feb7739dfcca02c1f5352e37f3
F src/bitvec.c e08f6c1a9551b88081fc737916c6c3fd5029a6cf
F src/btmutex.c 0f43a75bb5b8147b386e8e1c3e71ba734e3863b7
F src/btree.c 97d32ef9e00bd9d321fe1c53a3b6651928d8ea06
F src/btree.c 49212ddaee8d7d12b4f1e17b9de62f7ea91ca59d
F src/btree.h 577448a890c2ab9b21e6ab74f073526184bceebe
F src/btreeInt.h 1c86297e69380f6577e7ae67452597dd8d5c2705
F src/build.c a15de7c5d020a778b641fca0b2510126843f4b30
@ -284,7 +281,7 @@ F test/collateA.test b8218ab90d1fa5c59dcf156efabb1b2599c580d6
F test/colmeta.test 087c42997754b8c648819832241daf724f813322
F test/colname.test 08948a4809d22817e0e5de89c7c0a8bd90cb551b
F test/conflict.test 0ed68b11f22721052d880ee80bd528a0e0828236
F test/corrupt.test 04e717ebb644f1b30b142cb5f30797747ef5f02f
F test/corrupt.test f89c25681f60e06631e5cb203d06622f2f84e1e9
F test/corrupt2.test a571e30ea4e82318f319a24b6cc55935ce862079
F test/corrupt3.test 263e8bb04e2728df832fddf6973cf54c91db0c32
F test/corrupt4.test acdb01afaedf529004b70e55de1a6f5a05ae7fff
@ -746,14 +743,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746
P 302dabe98f50b472bccd65c58504bc8a330049c4
R 688485e18fb292248000129c5e459fb9
U drh
Z 522909aad95eede72dbcce585a963740
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
iD8DBQFKhY2YoxKgR168RlERAq9JAJ4uarnaf+/3F5G6GKq4PSOL6msAYACdEo74
T/jOErN31rwT4iOZlFOpYFw=
=nn3U
-----END PGP SIGNATURE-----
P 34c21210eb03bd1230cde5d08039a8a656f35674
R f46a5a69fe608d04233707dc2ffff1a9
U dan
Z baaa9683a6aa9b1a09c65002a4959fa5

View File

@ -1 +1 @@
34c21210eb03bd1230cde5d08039a8a656f35674
43321a556031942389ca11b033c1eae46ac6141b

View File

@ -1409,13 +1409,14 @@ static int btreeInitPage(MemPage *pPage){
while( pc>0 ){
u16 next, size;
if( pc<iCellFirst || pc>iCellLast ){
/* Free block is off the page */
/* Start of free block is off the page */
return SQLITE_CORRUPT_BKPT;
}
next = get2byte(&data[pc]);
size = get2byte(&data[pc+2]);
if( next>0 && next<=pc+size+3 ){
/* Free blocks must be in ascending order */
if( (next>0 && next<=pc+size+3) || pc+size>usableSize ){
/* Free blocks must be in ascending order. And the last byte of
** the free-block must lie on the database page. */
return SQLITE_CORRUPT_BKPT;
}
nFree = nFree + size;

View File

@ -226,4 +226,32 @@ do_test corrupt-5.2 {
catchsql { SELECT * FROM sqlite_master }
} {1 {database disk image is malformed}}
do_test corrupt-6.1 {
db close
file delete -force test.db test.db-journal
sqlite3 db test.db
execsql {
PRAGMA page_size = 1024; CREATE TABLE t1(x);
}
# The root page of t1 is 1024 bytes in size. The header is 8 bytes, and
# each of the cells inserted by the following INSERT statements consume
# 16 bytes (including the 2 byte cell-offset array entry). So the page
# can contain up to 63 cells.
for {set i 0} {$i < 63} {incr i} {
execsql { INSERT INTO t1 VALUES( randomblob(10) ) }
}
# Free the cell stored right at the end of the page (at offset pgsz-14).
execsql { DELETE FROM t1 WHERE rowid=1 }
set rootpage [db one {SELECT rootpage FROM sqlite_master WHERE name = 't1'}]
db close
set offset [expr ($rootpage * 1024)-14+2]
hexio_write test.db $offset 00FF
sqlite3 db test.db
catchsql { INSERT INTO t1 VALUES( randomblob(10) ) }
} {}
finish_test