From: dan Date: Wed, 1 Oct 2014 12:01:10 +0000 (+0000) Subject: Avoid ever writing before the start of an allocated buffer in the DIRECT_OVERFLOW_REA... X-Git-Tag: version-3.8.7~52 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9501a6451650d7dd19b616ce71a4b1fec45fdf64;p=thirdparty%2Fsqlite.git Avoid ever writing before the start of an allocated buffer in the DIRECT_OVERFLOW_READ code. Fix for [e3a290961a6]. FossilOrigin-Name: c3c15d20c6913811956a5041c959a56ca4eeb5eb --- diff --git a/manifest b/manifest index 4f1b85c92d..22b9dc1ea8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sthe\snew\ssyntax-tree\soutput\sroutines:\s\sOmit\sthe\s"END\sSELECT"\nmark\sand\sinstead\sterminate\sthe\sgraph\sat\sthe\slast\sitem.\s\sIncrease\sthe\smaximum\ntree\sdepth\sto\s100. -D 2014-09-30T19:04:41.396 +C Avoid\sever\swriting\sbefore\sthe\sstart\sof\san\sallocated\sbuffer\sin\sthe\sDIRECT_OVERFLOW_READ\scode.\sFix\sfor\s[e3a290961a6]. +D 2014-10-01T12:01:10.959 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -172,7 +172,7 @@ F src/auth.c d8abcde53426275dab6243b441256fcd8ccbebb2 F src/backup.c a31809c65623cc41849b94d368917f8bb66e6a7e F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5 -F src/btree.c ede8348a7d623257ee6c06ca4796ceaee13b8657 +F src/btree.c fa00618117fb6bb46c243452c56997c0d22d4fc9 F src/btree.h a79aa6a71e7f1055f01052b7f821bd1c2dce95c8 F src/btreeInt.h 1bd7957161a1346a914f1f09231610e777a8e58d F src/build.c bde83dd5cf812e310a7e5ad2846790a14745bef4 @@ -749,6 +749,7 @@ F test/orderby5.test 8f08a54836d21fb7c70245360751aedd1c2286fb F test/orderby6.test 8b38138ab0972588240b3fca0985d2e400432859 F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3 +F test/ovfl.test 4f7ca651cba5c059a12d8c67dddd49bec5747799 F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71 F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f @@ -1200,7 +1201,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b6b289182f6590288ebc7b9efbcb29b6b4480538 -R cfd4c6e5c7836f29218c39baf2122e42 -U drh -Z 3bfcd52f8fd5ecba827fd0c1ccf2615c +P 5ce05757aac80b99c3b2141cd301809f8e28e661 +R 8b86b2d12e4b9100e4b861428290f6cc +U dan +Z 9b09f2a5bed05af5296fa69f0721cad2 diff --git a/manifest.uuid b/manifest.uuid index f78de65f58..8b1c98cc6b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5ce05757aac80b99c3b2141cd301809f8e28e661 \ No newline at end of file +c3c15d20c6913811956a5041c959a56ca4eeb5eb \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 503a2fb5d0..12dcb44cba 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4022,6 +4022,7 @@ static int accessPayload( MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */ BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */ #ifdef SQLITE_DIRECT_OVERFLOW_READ + unsigned char * const pBufStart = pBuf; int bEnd; /* True if reading to end of data */ #endif @@ -4149,6 +4150,7 @@ static int accessPayload( ** 4) there is no open write-transaction, and ** 5) the database is not a WAL database, ** 6) all data from the page is being read. + ** 7) at least 4 bytes have already been read into the output buffer ** ** then data can be read directly from the database file into the ** output buffer, bypassing the page-cache altogether. This speeds @@ -4160,9 +4162,11 @@ static int accessPayload( && pBt->inTransaction==TRANS_READ /* (4) */ && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (3) */ && pBt->pPage1->aData[19]==0x01 /* (5) */ + && &pBuf[-4]>=pBufStart /* (7) */ ){ u8 aSave[4]; u8 *aWrite = &pBuf[-4]; + assert( aWrite>=pBufStart ); /* hence (7) */ memcpy(aSave, aWrite, 4); rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1)); nextPage = get4byte(aWrite); diff --git a/test/ovfl.test b/test/ovfl.test new file mode 100644 index 0000000000..075b1e43dd --- /dev/null +++ b/test/ovfl.test @@ -0,0 +1,49 @@ +# 2014 October 01 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is testing the SQLITE_DIRECT_OVERFLOW_READ logic. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix ovfl + +# Populate table t2: +# +# CREATE TABLE t1(c1 TEXT, c2 TEXT); +# +# with 2000 rows. In each row, c2 spans multiple overflow pages. The text +# value of c1 ranges in size from 1 to 2000 bytes. The idea is to create +# at least one row where the first byte of c2 is also the first byte of +# an overflow page. This was at one point exposing an obscure bug in the +# SQLITE_DIRECT_OVERFLOW_READ logic. +# +do_test 1.1 { + set c2 [string repeat abcdefghij 200] + execsql { + PRAGMA cache_size = 10; + CREATE TABLE t1(c1 TEXT, c2 TEXT); + BEGIN; + } + for {set i 1} {$i <= 2000} {incr i} { + set c1 [string repeat . $i] + execsql { INSERT INTO t1 VALUES($c1, $c2) } + } + execsql COMMIT +} {} + +do_execsql_test 1.2 { + SELECT sum(length(c2)) FROM t1; +} [expr 2000 * 2000] + +finish_test + +