Take extra care to avoid an OOB read caused by a corrupt b-tree page.

FossilOrigin-Name: 04925dee41a21ffca9a9f9df27d8165431668c42c2b33d08b077fdb28011170b
This commit is contained in:
dan 2017-10-19 15:17:38 +00:00
parent c1abf2d360
commit f2f72a0f9f
5 changed files with 129 additions and 15 deletions

@ -1,5 +1,5 @@
C Avoid\susing\ssnprintf\sas\sa\smember\svariable\sof\sa\sstruct\sin\ssqlite3ext.h.\sThis\ncauses\sproblems\son\sOSX.\sSimilar\sto\sfix\s[a1fd3aa8].
D 2017-10-18T15:02:01.361
C Take\sextra\scare\sto\savoid\san\sOOB\sread\scaused\sby\sa\scorrupt\sb-tree\spage.
D 2017-10-19T15:17:38.752
F Makefile.in e016061b23e60ac9ec27c65cb577292b6bde0307ca55abd874ab3487b3b1beb2
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 37740aba9c4bb359c627eadccf1cfd7be4f5f847078723777ea7763969e533b1
@ -403,7 +403,7 @@ F src/auth.c 6277d63837357549fe14e723490d6dc1a38768d71c795c5eb5c0f8a99f918f73
F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca
F src/btree.c 8565b061a6a6fad850230c73d6a7a8ffb88f3370e3352a8689a9a672160c5cc5
F src/btree.c 75229a5a47985997f861b428552acd14fe42b657f755cba5e0b1a007bd77b2ea
F src/btree.h 32ef5d3f25dc70ef1ee9cecf84a023c21378f06a57cd701d2e866e141b150f09
F src/btreeInt.h 55b702efce17e5d1941865464227d3802cfc9c7c832fac81d4c94dced47a71fc
F src/build.c 6ffe76970aeee4bc94e60cf0138269e67109061a853e13098c38a904dd66e673
@ -690,7 +690,7 @@ F test/corruptG.test adf79b669cbfd19e28c8191a610d083ae53a6d51
F test/corruptH.test 79801d97ec5c2f9f3c87739aa1ec2eb786f96454
F test/corruptI.test 075fe1d75aa1d84e2949be56b6264376c41502e4
F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4
F test/corruptK.test 814a59ec699d8546b4e29005fba3d16e933ef2fe
F test/corruptK.test 251ef631d095e882d455d2183961fa9ba879b4156e18e96c5d2b84aa7ef5f7a9
F test/cost.test 1eedbfd868f806f3fa08ff072b04cf270dcf61c8
F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c
F test/coveridxscan.test b629e896b14df2f000a99b8d170d80589c46562c
@ -1105,7 +1105,7 @@ F test/parser1.test 391b9bf9a229547a129c61ac345ed1a6f5eb1854
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
F test/permutations.test 53fb87f0a345259f884fa8b5fc62ee327b20be378ebe5149833b1b28c58a42f6
F test/permutations.test 490e3333b9b1aefb7ebc6e9ab2ae0e382b7dd8713ccc4a2786b0f75467c2ab6b
F test/pragma.test c31b5e98998c160a4c85b1e04f590655c67f2daa7f73854640cd120610e3ac15
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed
@ -1664,8 +1664,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 6a08c43431be18a08bdcbf33d327513f72fff72dac5d02103dab8399d8c3d668 b066d5a69f5391b2cef04b4e288f7d33e63a4ff54325b7e9fbd6aa42529c2f3c
R bae812ccbd328c244f2fa888e3ba625e
T +closed b066d5a69f5391b2cef04b4e288f7d33e63a4ff54325b7e9fbd6aa42529c2f3c
P cd0471ca9f75e7c8be74536ff4ec85b5d70f0d7994b680ed5f45b9f12a46cf46
R 14641e8822b464d39bf472f899e19240
T +closed 9dd591ef24b302a5fe2af0619d0cda6733348bacc541b3c0a134ac25981d4b2a
U dan
Z 4879d15d8231001302e10b2e0a3c2891
Z 576e55698c218b4128bbad5de39dc1b0

@ -1 +1 @@
cd0471ca9f75e7c8be74536ff4ec85b5d70f0d7994b680ed5f45b9f12a46cf46
04925dee41a21ffca9a9f9df27d8165431668c42c2b33d08b077fdb28011170b

@ -4824,7 +4824,7 @@ static const void *fetchPayload(
BtCursor *pCur, /* Cursor pointing to entry to read from */
u32 *pAmt /* Write the number of available bytes here */
){
u32 amt;
int amt;
assert( pCur!=0 && pCur->iPage>=0 && pCur->pPage);
assert( pCur->eState==CURSOR_VALID );
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
@ -4833,9 +4833,14 @@ static const void *fetchPayload(
assert( pCur->info.nSize>0 );
assert( pCur->info.pPayload>pCur->pPage->aData || CORRUPT_DB );
assert( pCur->info.pPayload<pCur->pPage->aDataEnd ||CORRUPT_DB);
amt = (int)(pCur->pPage->aDataEnd - pCur->info.pPayload);
if( pCur->info.nLocal<amt ) amt = pCur->info.nLocal;
*pAmt = amt;
amt = pCur->info.nLocal;
if( amt>(int)(pCur->pPage->aDataEnd - pCur->info.pPayload) ){
/* There is too little space on the page for the expected amount
** of local content. Database must be corrupt. */
assert( CORRUPT_DB );
amt = MAX(0, (int)(pCur->pPage->aDataEnd - pCur->info.pPayload));
}
*pAmt = (u32)amt;
return (void*)pCur->info.pPayload;
}

@ -107,6 +107,115 @@ do_catchsql_test 2.3 {
INSERT INTO t1 VALUES(randomblob(900));
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
proc hex2blob {hex} {
# Split on newlines:
set bytes [list]
foreach l [split $hex "\n"] {
if {[string is space $l]} continue
set L [list]
foreach b [split $l] {
if {[string is xdigit $b] && [string length $b]==2} {
lappend L [expr "0x$b"]
}
}
if {[llength $L]!=16} {
error "Badly formed hex (1)"
}
set bytes [concat $bytes $L]
}
binary format c* $bytes
}
reset_db
db func hex2blob hex2blob
do_execsql_test 3.1 {
PRAGMA page_size=1024;
CREATE TABLE t1(a, b, c);
CREATE TABLE t2(a, b, c);
CREATE TABLE t3(a, b, c);
CREATE TABLE t4(a, b, c);
CREATE TABLE t5(a, b, c);
}
do_execsql_test 3.2 {
UPDATE sqlite_dbpage SET data = hex2blob('
000: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
010: 04 00 01 01 20 40 20 20 00 00 3e d9 00 00 00 06 .... @ ..>.....
020: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................
030: 0f 00 00 00 00 00 00 00 00 00 00 01 00 00 83 00 ................
040: 00 00 00 00 00 00 00 00 00 00 00 00 00 38 00 00 .............8..
050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3e d9 ..............>.
060: 00 2d e6 07 0d 00 00 00 01 03 a0 00 03 e0 00 00 .-..............
070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0d0: 00 00 00 00 00 c1 00 00 00 00 00 00 00 00 00 00 ................
0e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
160: 00 83 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
180: 00 00 00 00 00 00 00 00 00 00 07 00 30 00 00 00 ............0...
190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
1a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
1b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
1c0: 02 00 00 00 00 00 00 00 00 00 00 02 00 00 00 00 ................
1d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
1e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
1f0: 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
220: 00 00 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
230: 0c 00 00 00 00 00 00 60 00 00 00 06 00 00 c3 00 .......`........
240: 00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
270: 00 00 00 18 00 00 00 00 00 00 00 00 00 00 00 00 ................
280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
290: 04 00 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
2a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
2b0: 00 00 00 00 83 00 8c 00 00 00 00 00 00 00 00 00 ................
2c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
2d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
2e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
2f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
310: 00 78 00 00 00 00 00 00 00 00 00 00 00 00 70 00 .x............p.
320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
340: 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 ................
350: 00 00 00 00 00 68 00 00 00 00 00 00 00 00 00 00 .....h..........
360: 00 00 00 00 00 03 00 00 00 00 00 00 00 00 00 00 ................
370: 00 00 00 00 00 00 00 00 00 00 00 00 00 08 00 00 ................
380: 00 00 00 00 70 00 00 00 00 00 00 00 00 00 00 00 ....p...........
390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
3a0: 5e 01 07 17 1b 1b 01 81 13 74 61 62 6c 65 73 65 ^........tablese
3b0: 6e 73 6f 32 73 73 65 6e 73 6f 72 73 02 43 52 45 nso2ssensors.CRE
3c0: 41 54 45 20 54 41 42 4c 45 20 73 65 6e 73 6f 72 ATE TABLE sensor
3d0: 73 20 0a 20 20 24 20 20 20 20 20 20 20 20 20 20 s . $
3e0: b8 6e 61 6d 65 21 74 65 78 74 2c 20 79 61 6c 20 .name!text, yal
3f0: 72 65 61 6c 2c 20 74 69 6d 65 20 74 65 78 74 29 real, time text)
') WHERE pgno=1
}
db close
sqlite3 db test.db
do_catchsql_test 3.3 {
PRAGMA integrity_check;
} {1 {database disk image is malformed}}

@ -194,7 +194,7 @@ test_suite "valgrind" -prefix "" -description {
} -files [
test_set $allquicktests -exclude *malloc* *ioerr* *fault* *_err* wal.test \
shell*.test crash8.test atof1.test selectG.test \
tkt-fc62af4523.test numindex1.test
tkt-fc62af4523.test numindex1.test corruptK.test
] -initialize {
set ::G(valgrind) 1
} -shutdown {