]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Take extra care to avoid an OOB read caused by a corrupt b-tree page.
authordan <dan@noemail.net>
Thu, 19 Oct 2017 15:17:38 +0000 (15:17 +0000)
committerdan <dan@noemail.net>
Thu, 19 Oct 2017 15:17:38 +0000 (15:17 +0000)
FossilOrigin-Name: 04925dee41a21ffca9a9f9df27d8165431668c42c2b33d08b077fdb28011170b

manifest
manifest.uuid
src/btree.c
test/corruptK.test
test/permutations.test

index 75ecef532121d15a0a00ba7a7e80eca0d86bad01..5c8ae4d13cc4ac34000cc51d1d50d08b2e3ef3a4 100644 (file)
--- a/manifest
+++ b/manifest
@@ -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
index 2f3fcd4b40c282abb77a08283077696f303be57c..26a2375f60253749278b9053c551cf2eda80e066 100644 (file)
@@ -1 +1 @@
-cd0471ca9f75e7c8be74536ff4ec85b5d70f0d7994b680ed5f45b9f12a46cf46
\ No newline at end of file
+04925dee41a21ffca9a9f9df27d8165431668c42c2b33d08b077fdb28011170b
\ No newline at end of file
index 89222197bc21c7f3cd0574b3af42fa57fd421ef6..ddcb6cfd35882b82ab39300be95aa6c58dabb067 100644 (file)
@@ -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;
 }
 
index b20c2d8bf0c2176f972d4a5b87dbee4119eea81a..b921176974944cce05471a931e2f1b81a9f942cb 100644 (file)
@@ -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}}
 
 
 
index 1e04265668dff176f7942e1e87a2047062cd2b6d..76fb72ace50d9e20ea42c51c9e1d1c8a184c0919 100644 (file)
@@ -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 {