]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Check for whether or not it is safe to use non-innocuous functions as the
authordrh <drh@noemail.net>
Wed, 8 Jan 2020 17:28:19 +0000 (17:28 +0000)
committerdrh <drh@noemail.net>
Wed, 8 Jan 2020 17:28:19 +0000 (17:28 +0000)
function is being coded, not when its name is resolved.

FossilOrigin-Name: 1da802d54b689a462e1fe899c6ffa08ef14d34f36728b14b055b5a76b1edc274

manifest
manifest.uuid
src/expr.c
src/resolve.c
src/sqliteInt.h
test/fts3atoken.test
test/func.test
test/trustschema1.test [new file with mode: 0644]

index 1a814157838291a1b8b93a0f8ac40a777b658cf4..dd4d4bcc905cfa47edb13c65c98c6ee27ea77399 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Provide\sthe\s-innocuous\soption\sto\sthe\s"db\sfunc"\smethod\sin\sthe\sTCL\sinterface.
-D 2020-01-08T15:44:10.295
+C Check\sfor\swhether\sor\snot\sit\sis\ssafe\sto\suse\snon-innocuous\sfunctions\sas\sthe\nfunction\sis\sbeing\scoded,\snot\swhen\sits\sname\sis\sresolved.
+D 2020-01-08T17:28:19.750
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -481,7 +481,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041
 F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
 F src/dbstat.c 0f55297469d4244ab7df395849e1af98eb5e95816af7c661e7d2d8402dea23da
 F src/delete.c a5c59b9c0251cf7682bc52af0d64f09b1aefc6781a63592c8f1136f7b73c66e4
-F src/expr.c 631b1f24d07114066c756984b8bc7be64529afb2ea3a5da4e3e262792f320dfa
+F src/expr.c bea12b33808867bb8f336d4bd70ebedfef72bb96bd453adcb068e578417b5e46
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
 F src/fkey.c 92a248ec0fa4ed8ab60c98d9b188ce173aaf218f32e7737ba77deb2a684f9847
 F src/func.c 259496e4856bd0a3215d16804992f3339f3e8db29f129a5a7285c341488bbe9c
@@ -527,14 +527,14 @@ F src/pragma.h 9f86a3a3a0099e651189521c8ad03768df598974e7bbdc21c7f9bb6125592fbd
 F src/prepare.c 6049beb71385f017af6fc320d2c75a4e50b75e280c54232442b785fbb83df057
 F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4
 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
-F src/resolve.c 894397f372b5c23fb68e0c534d3682f45285f228bb335d713344a7ed37f0ba45
+F src/resolve.c 5200d014fa78412f6189777cde3ac71b2dde55260c620be095610afe03fe9354
 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
 F src/select.c fbae5d6db63959aa1ecb34efe93caf5399444ca3c78d6f1ef4620b0ee5c37707
 F src/shell.c.in 43d3cfbee97d78ca5782dc53e4c1e22d3cc15c91beff20889dc60551f47eab9f
 F src/sqlite.h.in 06452043348e35cf6108345a35574a2faa4d1c2829beefb1e73c73d6bfb2fa80
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 72af51aa4e912e14cd495fb6e7fac65f0940db80ed950d90911aff292cc47ce2
-F src/sqliteInt.h 8c1fcdad7418c87cd482d2868610ed299e0201091e247598495e92e9c5d8e884
+F src/sqliteInt.h 0ca99e207087851fd27c6e1314fc52d273caa424ff2bafa3f1daf6d5eb63b35a
 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
 F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278
 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -930,7 +930,7 @@ F test/fts3al.test 07d64326e79bbdbab20ee87fc3328fbf01641c9f
 F test/fts3am.test 218aa6ba0dfc50c7c16b2022aac5c6be593d08d8
 F test/fts3an.test a49ccadc07a2f7d646ec1b81bc09da2d85a85b18
 F test/fts3ao.test 266989148fec6d9f1bb6c5382f7aa3dcea0e9cd444576e28dd2b9287ac7dd220
-F test/fts3atoken.test 2b2b0d7943eccf76e7a4887b557d4abcbb9279fbbb88e2bc2eba31c1817d11c7
+F test/fts3atoken.test dc2078ce464914efe3a8dfc545dd034a0fc14f2ab425c240471d5a5f1c721400
 F test/fts3auto.test bfe0857bd0b69d68dd685a931b58486411a69f5794a7f6d6fe808bfa31a99614
 F test/fts3aux1.test 7a170e172afdbceb67f5baa05941fd4fbf56af42f61daa3d140f4b4bf4cb68f6
 F test/fts3aux2.test 2459e7fa3e22734aed237d1e2ae192f5541c4d8b218956ad2d90754977bf907f
@@ -998,7 +998,7 @@ F test/fts4rename.test 15fd9985c2bce6dea20da2245b22029ec89bd4710ed317c4c53abbe3c
 F test/fts4umlaut.test fcaca4471de7e78c9d1f7e8976e3e8704d7d8ad979d57a739d00f3f757380429
 F test/fts4unicode.test ceca76422abc251818cb25dabe33d3c3970da5f7c90e1540f190824e6b3a7c95
 F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
-F test/func.test 7d425f9a6eaa2c50baa751bef6b0c6c6af1751e0e0e1eb4863d426bb4c886788
+F test/func.test 93d692f6427bd01b39c6ddb1e2d728f5264abefdbdd56e2f95c9dc1fa7dbcb53
 F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
 F test/func3.test 2bb0f31ab7baaed690b962a88544d7be6b34fa389364bc36a44e441ed3e3f1e6
 F test/func4.test 6beacdfcb0e18c358e6c2dcacf1b65d1fa80955f
@@ -1592,6 +1592,7 @@ F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650
 F test/triggerE.test ede2e4bce4ba802337bd69d39447fa04a938e06d84a8bfc53c76850fc36ed86d
 F test/triggerF.test 5d76f0a8c428ff87a4d5ed52da06f6096a2c787a1e21b846111dfac4123de3ad
 F test/triggerG.test d5caeef6144ede2426dd13211fd72248241ff2ebc68e12a4c0bf30f5faa21499
+F test/trustschema1.test b337ef2d006c3c02ca822eca45bbc10d711ba96d12486cb0fa8e7beb5e0d7660
 F test/tt3_checkpoint.c 9e75cf7c1c364f52e1c47fd0f14c4340a9db0fe1
 F test/tt3_index.c 39eec10a35f57672225be4d182862152896dee4a
 F test/tt3_lookaside1.c 0377e202c3c2a50d688cb65ba203afeda6fafeb9
@@ -1854,7 +1855,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P a679122ca8ec95d5c8afba3a1a50170db9dd519a3810e56877b8f56e858d0175
-R 9fbba3111d220dbea3ef9c5770ac6cef
+P 0138652b6c2f21fd67e59a23a396a5b9d6a16ee9b44701cddfc49b23fddfce5b
+R ce4061dc1b633cb47a4ee9d471ef9c80
 U drh
-Z fc531ff60387ab6488432d4541dd29bf
+Z 1c75c43008bf3984bb39f61126a3891e
index 0381fd8065136a6ee90373bf91943a5adadaee03..3ce3dd07e0ade272554cb8d8866ec10aac1e835d 100644 (file)
@@ -1 +1 @@
-0138652b6c2f21fd67e59a23a396a5b9d6a16ee9b44701cddfc49b23fddfce5b
\ No newline at end of file
+1da802d54b689a462e1fe899c6ffa08ef14d34f36728b14b055b5a76b1edc274
\ No newline at end of file
index 4e8703e552832daadd6d6039ceeaea191bbe20f0..7d712ad674778d6dbe471f8cd92df58fb1e35106 100644 (file)
@@ -973,6 +973,41 @@ Expr *sqlite3ExprFunction(
   return pNew;
 }
 
+/*
+** Check to see if a function is usable according to current access
+** rules:
+**
+**    SQLITE_FUNC_DIRECT    -     Only usable from top-level SQL
+**
+**    SQLITE_FUNC_UNSAFE    -     Usable if TRUSTED_SCHEMA or from
+**                                top-level SQL
+**
+** If the function is not usable, create an error.
+*/
+void sqlite3ExprFunctionUsable(
+  Parse *pParse,         /* Parsing and code generating context */
+  Expr *pExpr,           /* The function invocation */
+  FuncDef *pDef          /* The function being invoked */
+){
+  assert( !IN_RENAME_OBJECT );
+  if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0
+   && ExprHasProperty(pExpr, EP_FromDDL)
+  ){
+    if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0
+     || (pParse->db->flags & SQLITE_TrustedSchema)==0
+    ){
+      /* Functions prohibited in triggers and views if:
+      **     (1) tagged with SQLITE_DIRECTONLY
+      **     (2) not tagged with SQLITE_INNOCUOUS (which means it
+      **         is tagged with SQLITE_FUNC_UNSAFE) and 
+      **         SQLITE_DBCONFIG_TRUSTED_SCHEMA is off (meaning
+      **         that the schema is possibly tainted).
+      */
+      sqlite3ErrorMsg(pParse, "unsafe use of %s()", pDef->zName);
+    }
+  }
+}
+
 /*
 ** Assign a variable number to an expression that encodes a wildcard
 ** in the original SQL statement.  
@@ -4073,9 +4108,12 @@ expr_code_doover:
         break;
       }
       if( pDef->funcFlags & SQLITE_FUNC_INLINE ){
+        assert( (pDef->funcFlags & SQLITE_FUNC_UNSAFE)==0 );
+        assert( (pDef->funcFlags & SQLITE_FUNC_DIRECT)==0 );
         return exprCodeInlineFunction(pParse, pFarg,
              SQLITE_PTR_TO_INT(pDef->pUserData), target);
       }
+      sqlite3ExprFunctionUsable(pParse, pExpr, pDef);
 
       for(i=0; i<nFarg; i++){
         if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){
@@ -5740,6 +5778,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
             }else{
               pItem->iDistinct = -1;
             }
+            sqlite3ExprFunctionUsable(pParse, pExpr, pItem->pFunc);
           }
         }
         /* Make pExpr point to the appropriate pAggInfo->aFunc[] entry
index 929c8743f595ca52c4faddebe395755f40baf20b..16546ada4b61e0cec3b80c68deafcce95a5d6804 100644 (file)
@@ -876,33 +876,18 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
         }else{
           assert( (NC_SelfRef & 0xff)==NC_SelfRef ); /* Must fit in 8 bits */
           pExpr->op2 = pNC->ncFlags & NC_SelfRef;
+          if( pExpr->op2 ) ExprSetProperty(pExpr, EP_FromDDL);
         }
         if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0
          && pParse->nested==0
          && (pParse->db->mDbFlags & DBFLAG_InternalFunc)==0
         ){
           /* Internal-use-only functions are disallowed unless the
-          ** SQL is being compiled using sqlite3NestedParse() */
+          ** SQL is being compiled using sqlite3NestedParse() or
+          ** the SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test-control has be
+          ** used to activate internal functionsn for testing purposes */
           no_such_func = 1;
           pDef = 0;
-        }else
-        if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0
-         && ExprHasProperty(pExpr, EP_FromDDL)
-         && !IN_RENAME_OBJECT
-        ){
-          if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0
-           || (pParse->db->flags & SQLITE_TrustedSchema)==0
-          ){
-            /* Functions prohibited in triggers and views if:
-            **     (1) tagged with SQLITE_DIRECTONLY
-            **     (2) not tagged with SQLITE_INNOCUOUS (which means it
-            **         is tagged with SQLITE_FUNC_UNSAFE) and 
-            **         SQLITE_DBCONFIG_UNTRUSTED_SCHEMA is off (meaning
-            **         that the schema is fully trustworthy).
-            */
-            sqlite3ErrorMsg(pParse, "%s() prohibited in triggers and views",
-                            pDef->zName);
-          }
         }
       }
 
index 455403637a9d598e5f785fcd3bfb4a776b50d98a..e56a4b3d5444d669129e685d9cf281e89c828e5f 100644 (file)
@@ -4056,6 +4056,7 @@ void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
 Expr *sqlite3ExprAnd(Parse*,Expr*, Expr*);
 Expr *sqlite3ExprSimplifiedAndOr(Expr*);
 Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int);
+void sqlite3ExprFunctionUsable(Parse*,Expr*,FuncDef*);
 void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
 void sqlite3ExprDelete(sqlite3*, Expr*);
 void sqlite3ExprUnmapAndDelete(Parse*, Expr*);
index 5694dfb9f0e9efae7b320bae653c9e69a5ee9da1..4981480b5e82cb33355dd02f82f6f18c668315ca 100644 (file)
@@ -138,7 +138,7 @@ do_catchsql_test fts3atoken-1.10 {
 } {0 {}}
 do_catchsql_test fts3atoken-1.11 {
   SELECT * FROM v110;
-} {1 {fts3_tokenizer() prohibited in triggers and views}}
+} {1 {unsafe use of fts3_tokenizer()}}
 do_catchsql_test fts3atoken-1.12 {
   CREATE TABLE t110(a,b);
   CREATE TRIGGER r110 AFTER INSERT ON t110 BEGIN
@@ -147,7 +147,7 @@ do_catchsql_test fts3atoken-1.12 {
 } {0 {}}
 do_catchsql_test fts3atoken-1.13 {
   INSERT INTO t110(a,b) VALUES(1,2);
-} {1 {fts3_tokenizer() prohibited in triggers and views}}
+} {1 {unsafe use of fts3_tokenizer()}}
 do_catchsql_test fts3atoken-1.14 {
   SELECT * FROM t110;
 } {0 {}}
index 3bfb1fe8ac1a0d4bbf316ec600964bf41e2731f0..585ae1a14ff23b306d1ab7cdc9fdbf906f9a8bfa 100644 (file)
@@ -1430,7 +1430,7 @@ do_test func-33.1 {
 do_catchsql_test func-33.2 {
   CREATE VIEW v33(y) AS SELECT testdirectonly(15);
   SELECT * FROM v33;
-} {1 {testdirectonly() prohibited in triggers and views}}
+} {1 {unsafe use of testdirectonly()}}
 do_execsql_test func-33.3 {
   SELECT * FROM (SELECT testdirectonly(15)) AS v33;
 } {30}
@@ -1441,7 +1441,7 @@ do_execsql_test func-33.4 {
 do_catchsql_test func-33.5 {
   WITH c(x) AS (SELECT * FROM v33)
   SELECT * FROM c;
-} {1 {testdirectonly() prohibited in triggers and views}}
+} {1 {unsafe use of testdirectonly()}}
 do_execsql_test func-33.10 {
   CREATE TABLE t33a(a,b);
   CREATE TABLE t33b(x,y);
@@ -1451,7 +1451,7 @@ do_execsql_test func-33.10 {
 } {}
 do_catchsql_test func-33.11 {
   INSERT INTO t33a VALUES(1,2);
-} {1 {testdirectonly() prohibited in triggers and views}}
+} {1 {unsafe use of testdirectonly()}}
 do_execsql_test func-33.20 {
   ALTER TABLE t33a RENAME COLUMN a TO aaa;
   SELECT sql FROM sqlite_master WHERE name='r1';
diff --git a/test/trustschema1.test b/test/trustschema1.test
new file mode 100644 (file)
index 0000000..d536645
--- /dev/null
@@ -0,0 +1,44 @@
+# 2020-01-08
+#
+# 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.
+#
+#***********************************************************************
+# 
+# Test cases for managing execution of code snippets found in untrusted
+# schemas.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set testprefix trustschema1
+
+
+proc f1 {x} {return $x}
+do_test 1.100 {
+  db function f1 -innocuous -deterministic f1
+  db function f2 -deterministic f1
+  db function f3 -directonly -deterministic f1
+  db eval {
+    CREATE TABLE t1(a, b AS (f1(a+1)), c AS (f2(a+2)));
+    INSERT INTO t1 VALUES(100),(200);
+  }
+} {}
+do_catchsql_test 1.110 {
+  SELECT a, b, c FROM t1;
+} {0 {100 101 102 200 201 202}}
+do_execsql_test 1.120 {
+  PRAGMA trusted_schema=OFF;
+} {}
+do_catchsql_test 1.130 {
+  SELECT a, b FROM t1;
+} {0 {100 101 200 201}}
+do_catchsql_test 1.140 {
+  SELECT a, b, c FROM t1;
+} {1 {unsafe use of f2()}}
+
+finish_test