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
This commit is contained in:
drh 2022-08-20 19:33:04 +00:00
parent 78ed74ef8e
commit 00378fde23
3 changed files with 39 additions and 13 deletions

@ -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.

@ -1 +1 @@
96e112da1ac56767cf49f26132833745b6020d2c60f5c36f86ca84f87ad30c81
9433ea4070f52135be64569057f439e7bdb4b3f425d87167c9ebda50011210c1

@ -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) ){