From: drh <> Date: Sat, 20 Aug 2022 19:33:04 +0000 (+0000) Subject: Enhance the enforcement of SQLITE_VTAB_DIRECTONLY so that it applies to X-Git-Tag: version-3.40.0~232 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=00378fde230fe91bdf3885b1e10d779ee96948c5;p=thirdparty%2Fsqlite.git Enhance the enforcement of SQLITE_VTAB_DIRECTONLY so that it applies to DML statements within triggers. Do not allow DML stratements against virtual tables within triggers unless either the virtual table is SQLITE_VTAB_INNOCUOUS or PRAGMA trusted_schema is ON. FossilOrigin-Name: 9433ea4070f52135be64569057f439e7bdb4b3f425d87167c9ebda50011210c1 --- diff --git a/manifest b/manifest index 9c87b644f1..fd6c9da95f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\s".dump"\scommand\sof\sthe\sCLI,\sif\sa\sschema\sstatement\sends\swith\san\nunterminated\scomment,\stry\sto\sterminate\sthat\scomment\sprior\sto\sappending\nthe\s";"\sat\sthe\send.\s\s[forum:/forumpost/d7be961c5c|Forum\spost\sd7be961c5c]. -D 2022-08-17T20:18:34.624 +C Enhance\sthe\senforcement\sof\sSQLITE_VTAB_DIRECTONLY\sso\sthat\sit\sapplies\sto\nDML\sstatements\swithin\striggers.\s\sDo\snot\sallow\sDML\sstratements\sagainst\nvirtual\stables\swithin\striggers\sunless\seither\sthe\svirtual\stable\sis\nSQLITE_VTAB_INNOCUOUS\sor\sPRAGMA\strusted_schema\sis\sON. +D 2022-08-20T19:33:04.530 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -538,7 +538,7 @@ F src/ctime.c 93e4b5f4faf6d3f688988a116773259a4fbfb4ddac0e9bf9d0ae0429390c2543 F src/date.c 94ce83b4cd848a387680a5f920c9018c16655db778c4d36525af0a0f34679ac5 F src/dbpage.c 5808e91bc27fa3981b028000f8fadfdc10ce9e59a34ce7dc4e035a69be3906ec F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d -F src/delete.c 13eca2beee5b758ed033a11230971310cc4a58fcd8f6bc33cad4f677c985e96c +F src/delete.c cba80ff7370f9d49e147470ef15f05cf00359f0725256a3703b422b6f376e270 F src/expr.c 0f72468b64eef40c280fd6b273c19f3b221444b00f535c7ba6f34faa657e63da F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c d965ede15d8360c09ed59348940649ee647b192e784466837d7aefa836d1d91e @@ -1999,8 +1999,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 62f934bff495850d0763e07ffa44a557f066ecba9d039363f32287213cba819f -R f81b87acda08a2789d4e7c27b7b89cff +P 96e112da1ac56767cf49f26132833745b6020d2c60f5c36f86ca84f87ad30c81 +R b2aaecc820aeeb861481321e6e0d526f U drh -Z 0ac82790ca7f9e87feb2c5a2f457751d +Z 057552ff6703cfb91f8abf2e3faed7e1 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0d1833b114..f007df01e9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -96e112da1ac56767cf49f26132833745b6020d2c60f5c36f86ca84f87ad30c81 \ No newline at end of file +9433ea4070f52135be64569057f439e7bdb4b3f425d87167c9ebda50011210c1 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 3d0e055be2..056d6f3bef 100644 --- a/src/delete.c +++ b/src/delete.c @@ -61,18 +61,42 @@ void sqlite3CodeChangeCount(Vdbe *v, int regCounter, const char *zColName){ ** 1) It is a virtual table and no implementation of the xUpdate method ** has been provided ** -** 2) It is a system table (i.e. sqlite_schema), this call is not +** 2) A trigger is currently being coded and the table is a virtual table +** that is SQLITE_VTAB_DIRECTONLY or if PRAGMA trusted_schema=OFF and +** the table is not SQLITE_VTAB_INNOCUOUS. +** +** 3) It is a system table (i.e. sqlite_schema), this call is not ** part of a nested parse and writable_schema pragma has not ** been specified ** -** 3) The table is a shadow table, the database connection is in +** 4) The table is a shadow table, the database connection is in ** defensive mode, and the current sqlite3_prepare() ** is for a top-level SQL statement. */ +static int vtabIsReadOnly(Parse *pParse, Table *pTab){ + if( sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 ){ + return 1; + } + + /* Within triggers: + ** * Do not allow DELETE, INSERT, or UPDATE of SQLITE_VTAB_DIRECTONLY + ** virtual tables + ** * Only allow DELETE, INSERT, or UPDATE of non-SQLITE_VTAB_INNOCUOUS + ** virtual tables if PRAGMA trusted_schema=ON. + */ + if( pParse->pToplevel!=0 + && pTab->u.vtab.p->eVtabRisk > + ((pParse->db->flags & SQLITE_TrustedSchema)!=0) + ){ + sqlite3ErrorMsg(pParse, "unsafe use of virtual table \"%s\"", + pTab->zName); + } + return 0; +} static int tabIsReadOnly(Parse *pParse, Table *pTab){ sqlite3 *db; if( IsVirtual(pTab) ){ - return sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0; + return vtabIsReadOnly(pParse, pTab); } if( (pTab->tabFlags & (TF_Readonly|TF_Shadow))==0 ) return 0; db = pParse->db; @@ -84,9 +108,11 @@ static int tabIsReadOnly(Parse *pParse, Table *pTab){ } /* -** Check to make sure the given table is writable. If it is not -** writable, generate an error message and return 1. If it is -** writable return 0; +** Check to make sure the given table is writable. +** +** If pTab is not writable -> generate an error message and return 1. +** If pTab is writable but other errors have occurred -> return 1. +** If pTab is writable and no prior errors -> return 0; */ int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){ if( tabIsReadOnly(pParse, pTab) ){