Check for whether or not it is safe to use non-innocuous functions as the

function is being coded, not when its name is resolved.

FossilOrigin-Name: 1da802d54b689a462e1fe899c6ffa08ef14d34f36728b14b055b5a76b1edc274
This commit is contained in:
drh 2020-01-08 17:28:19 +00:00
parent 15f3eacfc0
commit 0dfa5255bc
8 changed files with 105 additions and 35 deletions

View File

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

View File

@ -1 +1 @@
0138652b6c2f21fd67e59a23a396a5b9d6a16ee9b44701cddfc49b23fddfce5b
1da802d54b689a462e1fe899c6ffa08ef14d34f36728b14b055b5a76b1edc274

View 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

View 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);
}
}
}

View 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*);

View 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 {}}

View 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';

44
test/trustschema1.test Normal file
View File

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