From: dan Date: Thu, 27 Nov 2014 11:36:36 +0000 (+0000) Subject: Fix a buffer overread during compilation of CREATE VIRTUAL TABLE statements that... X-Git-Tag: version-3.8.8~135 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d89b834f54b4026944df0668dbc5fe7803033a8f;p=thirdparty%2Fsqlite.git Fix a buffer overread during compilation of CREATE VIRTUAL TABLE statements that featured an explicit database name but no virtual table arguments. For example, "CREATE VIRTUAL TABLE main.ft USING fts4". FossilOrigin-Name: f095cde579e7417306e11b5c1d2dd90b6bb547d5 --- diff --git a/manifest b/manifest index 06e08e13af..273e715897 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\stest\scases\sfor\sthe\sbalancer. -D 2014-11-27T04:23:19.652 +C Fix\sa\sbuffer\soverread\sduring\scompilation\sof\sCREATE\sVIRTUAL\sTABLE\sstatements\sthat\sfeatured\san\sexplicit\sdatabase\sname\sbut\sno\svirtual\stable\sarguments.\sFor\sexample,\s"CREATE\sVIRTUAL\sTABLE\smain.ft\sUSING\sfts4". +D 2014-11-27T11:36:36.295 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -238,7 +238,7 @@ F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 81712116e826b0089bb221b018929536b2b5406f F src/table.c f142bba7903e93ca8d113a5b8877a108ad1a27dc F src/tclsqlite.c 0a874655dd39a9875e39c5d3c464db662171d228 -F src/test1.c 6b0469b8e06c77b1de1d3e4a3834cf26edea9cc7 +F src/test1.c a0bce4f47da65b76c80e5f8bf9a5ef174603866a F src/test2.c 98049e51a17dc62606a99a9eb95ee477f9996712 F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df @@ -300,7 +300,7 @@ F src/vdbeblob.c 4af4bfb71f6df7778397b4a0ebc1879793276778 F src/vdbemem.c 31d8eabb0cd78bfeab4e5124c7363c3e9e54db9f F src/vdbesort.c 42c166f7ca78cb643c7f4e4bdfa83c59d363d1a6 F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010 -F src/vtab.c 2a30791bbd7926b589401bd09c3abb33de563793 +F src/vtab.c c08ec66f45919eaa726bf88aa53eb08379d607f9 F src/wal.c 486e644b3b8aa5ad066f625bc428aa8ff7001405 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 @@ -1091,7 +1091,7 @@ F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 F test/view.test f311691d696a5cc27e3c1b875cec1b0866b4ccd9 -F test/vtab1.test b631d147b198cfd7903ab5fed028eb2a3d321dc6 +F test/vtab1.test 1cef14310144718812351a61c5cfb4ba8494a171 F test/vtab2.test 7bcffc050da5c68f4f312e49e443063e2d391c0d F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e F test/vtab4.test 942f8b8280b3ea8a41dae20e7822d065ca1cb275 @@ -1223,7 +1223,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 f242394e079dd185aad90f2aee902a5edf27e150 -R dee46347027ae53917346a5c99ff404e -U drh -Z 45538c84f085c10577fd84190398d06f +P 358ea818f7ea5aa55bafaf4057e9fc7a5fd77c11 +R a4b8cae126976a974aa80f7f44ce5b7f +U dan +Z 67582253c41fc622f4b8d67b4605ed6a diff --git a/manifest.uuid b/manifest.uuid index 19339500a5..e316358ddb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -358ea818f7ea5aa55bafaf4057e9fc7a5fd77c11 \ No newline at end of file +f095cde579e7417306e11b5c1d2dd90b6bb547d5 \ No newline at end of file diff --git a/src/test1.c b/src/test1.c index ca3b54a513..1c43861547 100644 --- a/src/test1.c +++ b/src/test1.c @@ -3638,6 +3638,7 @@ static int test_prepare_v2( ){ sqlite3 *db; const char *zSql; + char *zCopy = 0; /* malloc() copy of zSql */ int bytes; const char *zTail = 0; sqlite3_stmt *pStmt = 0; @@ -3653,7 +3654,21 @@ static int test_prepare_v2( zSql = Tcl_GetString(objv[2]); if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR; - rc = sqlite3_prepare_v2(db, zSql, bytes, &pStmt, objc>=5 ? &zTail : 0); + /* Instead of using zSql directly, make a copy into a buffer obtained + ** directly from malloc(). The idea is to make it easier for valgrind + ** to spot buffer overreads. */ + if( bytes>=0 ){ + zCopy = malloc(bytes); + memcpy(zCopy, zSql, bytes); + }else{ + int n = strlen(zSql) + 1; + zCopy = malloc(n); + memcpy(zCopy, zSql, n); + } + rc = sqlite3_prepare_v2(db, zCopy, bytes, &pStmt, objc>=5 ? &zTail : 0); + free(zCopy); + zTail = &zSql[(zTail - zCopy)]; + assert(rc==SQLITE_OK || pStmt==0); Tcl_ResetResult(interp); if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; diff --git a/src/vtab.c b/src/vtab.c index 334de9aacb..00d0882b04 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -332,7 +332,12 @@ void sqlite3VtabBeginParse( addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName)); addModuleArgument(db, pTable, 0); addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName)); - pParse->sNameToken.n = (int)(&pModuleName->z[pModuleName->n] - pName1->z); + assert( (pParse->sNameToken.z==pName2->z && pName2->z!=0) + || (pParse->sNameToken.z==pName1->z && pName2->z==0) + ); + pParse->sNameToken.n = (int)( + &pModuleName->z[pModuleName->n] - pParse->sNameToken.z + ); #ifndef SQLITE_OMIT_AUTHORIZATION /* Creating a virtual table invokes the authorization callback twice. diff --git a/test/vtab1.test b/test/vtab1.test index 0542ee6fdd..2929b1e54d 100644 --- a/test/vtab1.test +++ b/test/vtab1.test @@ -1395,4 +1395,46 @@ do_execsql_test 21.3 { SELECT * FROM t9v WHERE a=b; } {2 2 2} +#------------------------------------------------------------------------- +# At one point executing a CREATE VIRTUAL TABLE statement that specified +# a database name but no virtual table arguments was causing an internal +# buffer overread. Valgrind would report errors while running the following +# tests. Specifically: +# +# CREATE VIRTUAL TABLE t1 USING fts4; -- Ok - no db name. +# CREATE VIRTUAL TABLE main.t1 USING fts4(x); -- Ok - has vtab arguments. +# CREATE VIRTUAL TABLE main.t1 USING fts4; -- Had the problem. +# +ifcapable fts3 { + forcedelete test.db2 + set nm [string repeat abcdefghij 100] + do_execsql_test 22.1 { + ATTACH 'test.db2' AS $nm + } + + execsql "SELECT * FROM sqlite_master" + do_execsql_test 22.2 "CREATE VIRTUAL TABLE ${nm}.t1 USING fts4" + + do_test 22.3.1 { + set sql "CREATE VIRTUAL TABLE ${nm}.t2 USING fts4" + set stmt [sqlite3_prepare_v2 db $sql -1 dummy] + sqlite3_step $stmt + } {SQLITE_DONE} + + do_test 22.3.2 { + sqlite3_finalize $stmt + } {SQLITE_OK} + + do_test 22.4.1 { + set sql "CREATE VIRTUAL TABLE ${nm}.t3 USING fts4" + set n [string length $sql] + set stmt [sqlite3_prepare db "${sql}xyz" $n dummy] + sqlite3_step $stmt + } {SQLITE_DONE} + + do_test 22.4.2 { + sqlite3_finalize $stmt + } {SQLITE_OK} +} + finish_test