From b945bcdaf178eabb320aa4609a31ec74233e3115 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 31 Dec 2019 22:52:10 +0000 Subject: [PATCH 01/22] Experimental branch with new sqlite3_db_config() options that could possible enhance security for applications reading potentially compromised database files. FossilOrigin-Name: 96a2db2612f2e47bbec0e374a242820c88f03c42ccbf8467abccaef41469bae2 --- manifest | 23 +++++++++++++---------- manifest.uuid | 2 +- src/main.c | 4 ++++ src/resolve.c | 10 ++++++++++ src/shell.c.in | 18 ++++++++++-------- src/sqlite.h.in | 31 ++++++++++++++++++++++++++++++- src/sqliteInt.h | 23 +++++++++++++++++------ 7 files changed, 85 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index c162495ecf..d00d6abea2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Also\sset\sthe\sSQLITE_DIRECTONLY\sflag\son\sthe\sload_extension()\sfunction. -D 2019-12-31T18:39:23.702 +C Experimental\sbranch\swith\snew\ssqlite3_db_config()\soptions\sthat\scould\spossible\nenhance\ssecurity\sfor\sapplications\sreading\spotentially\scompromised\sdatabase\nfiles. +D 2019-12-31T22:52:10.121 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -492,7 +492,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 97afb0bf06d7fd7b820f6de3e42cf60beb5cd10131828c29b131b2614bbb1f39 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c d74f5e7bd51f3c9d283442473eb65aef359664efd6513591c03f01881c4ae2da -F src/main.c 868ae7db7a54fe859bf2ca8b7a4f24e9fa03a6134abfb7c9801d08411ef5dacb +F src/main.c b75192ececab87f3342088546a8738b22ffc727865d61902ef93de9dc057669c F src/malloc.c 550021fcae36f0ffe9f8563d83e6385f9df307a854d55d7d0abb7241ee8dbcc6 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -526,14 +526,14 @@ F src/pragma.h ec3b31eac9b1df040f1cc8cb3d89bc06605c3b4cb3d76f833de8d6d6c3f77f04 F src/prepare.c 6049beb71385f017af6fc320d2c75a4e50b75e280c54232442b785fbb83df057 F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c e231da7dd307f99772c40e76096abaf05c6fedcb4f1f045de23a61c194df6da6 +F src/resolve.c 8513df170ff6069828fbfcb7a59d84521b30b2ee19a2f57a391cc59baf381a55 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 2a753ec714703c32e4aade5b0115033bbee8a377b215cb0fbe88ab2fa4b3e028 -F src/shell.c.in 4a3a9e1c11847b1904f2b01d087af1c052f660902755abab457cab1756817ded -F src/sqlite.h.in 51f69c62ba3e980aca1e39badcaf9ad13f008774fe1bb8e7f57e3e456c656670 +F src/shell.c.in 709c85e7f90ac62f8bc45ed11feabcfeb6e9559892c55fcb557a062b8c698d0e +F src/sqlite.h.in efaecabd038dc30282f243af087c4960e528d0df25a05f90f988435fec5ef779 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 72af51aa4e912e14cd495fb6e7fac65f0940db80ed950d90911aff292cc47ce2 -F src/sqliteInt.h e526421d44d88f17c397647371e460841c961b27ccf69301177b63d18ebbeead +F src/sqliteInt.h 3e4c8037071dbf74886c25f4ada1499bac7e90352a91ad072372282477dc7296 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1853,7 +1853,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f3171dc22e4d3a40ca17fe609391d92fc6a997b775bfefa5947aec69c889aa73 -R 25bc6cfca86f50c6bebf64970cf717c5 +P 3bd095a53119c368fe30e539983588b27957203344cf427405b9a64784b8eba7 +R 1519469fee4296191cf9c590f16cccb9 +T *branch * new-security-options +T *sym-new-security-options * +T -sym-trunk * U drh -Z 6a954000d634738bb471999423aebba1 +Z 66c42f7199d224391a430f509bbf28ff diff --git a/manifest.uuid b/manifest.uuid index 266e4c4a56..34ed42b1fb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3bd095a53119c368fe30e539983588b27957203344cf427405b9a64784b8eba7 \ No newline at end of file +96a2db2612f2e47bbec0e374a242820c88f03c42ccbf8467abccaef41469bae2 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 1afeee0bdb..70c5b89d0a 100644 --- a/src/main.c +++ b/src/main.c @@ -852,6 +852,8 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){ { SQLITE_DBCONFIG_DQS_DDL, SQLITE_DqsDDL }, { SQLITE_DBCONFIG_DQS_DML, SQLITE_DqsDML }, { SQLITE_DBCONFIG_LEGACY_FILE_FORMAT, SQLITE_LegacyFileFmt }, + { SQLITE_DBCONFIG_UNSAFE_FUNC_IN_VIEW, SQLITE_UnsafeInView }, + { SQLITE_DBCONFIG_VTAB_IN_VIEW, SQLITE_VtabInView }, }; unsigned int i; rc = SQLITE_ERROR; /* IMP: R-42790-23372 */ @@ -3082,6 +3084,8 @@ static int openDatabase( | SQLITE_EnableTrigger | SQLITE_EnableView | SQLITE_CacheSpill + | SQLITE_UnsafeInView + | SQLITE_VtabInView /* The SQLITE_DQS compile-time option determines the default settings ** for SQLITE_DBCONFIG_DQS_DDL and SQLITE_DBCONFIG_DQS_DML. diff --git a/src/resolve.c b/src/resolve.c index a0f9c0f22f..36eef4bb4e 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -861,6 +861,16 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ ** constant because they are constant for the duration of one query. ** This allows them to be factored out of inner loops. */ ExprSetProperty(pExpr,EP_ConstFunc); + }else{ + if( ExprHasProperty(pExpr, EP_Indirect) + && !IN_RENAME_OBJECT + && (pParse->db->flags & SQLITE_UnsafeInView)==0 + ){ + /* If SQLITE_DBCONFIG_UNSAFE_IN_VIEW is off, then functions with + ** side effects are not allowed inside triggers and views. */ + sqlite3ErrorMsg(pParse, "%s() prohibited in triggers and views", + pDef->zName); + } } if( (pDef->funcFlags & SQLITE_FUNC_CONSTANT)==0 ){ /* Date/time functions that use 'now', and other functions like diff --git a/src/shell.c.in b/src/shell.c.in index e6b6f1a1b3..1a06bf8477 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -7159,21 +7159,23 @@ static int do_meta_command(char *zLine, ShellState *p){ const char *zName; int op; } aDbConfig[] = { + { "defensive", SQLITE_DBCONFIG_DEFENSIVE }, + { "dqs_ddl", SQLITE_DBCONFIG_DQS_DDL }, + { "dqs_dml", SQLITE_DBCONFIG_DQS_DML }, { "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY }, + { "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG }, { "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER }, { "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW }, { "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER }, + { "legacy_alter_table", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE }, + { "legacy_file_format", SQLITE_DBCONFIG_LEGACY_FILE_FORMAT }, { "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION }, { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE }, - { "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG }, - { "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP }, { "reset_database", SQLITE_DBCONFIG_RESET_DATABASE }, - { "defensive", SQLITE_DBCONFIG_DEFENSIVE }, + { "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP }, + { "unsafe_func_in_view",SQLITE_DBCONFIG_UNSAFE_FUNC_IN_VIEW }, + { "vtab_in_view", SQLITE_DBCONFIG_VTAB_IN_VIEW }, { "writable_schema", SQLITE_DBCONFIG_WRITABLE_SCHEMA }, - { "legacy_alter_table", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE }, - { "dqs_dml", SQLITE_DBCONFIG_DQS_DML }, - { "dqs_ddl", SQLITE_DBCONFIG_DQS_DDL }, - { "legacy_file_format", SQLITE_DBCONFIG_LEGACY_FILE_FORMAT }, }; int ii, v; open_db(p, 0); @@ -7183,7 +7185,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_db_config(p->db, aDbConfig[ii].op, booleanValue(azArg[2]), 0); } sqlite3_db_config(p->db, aDbConfig[ii].op, -1, &v); - utf8_printf(p->out, "%18s %s\n", aDbConfig[ii].zName, v ? "on" : "off"); + utf8_printf(p->out, "%19s %s\n", aDbConfig[ii].zName, v ? "on" : "off"); if( nArg>1 ) break; } if( nArg>1 && ii==ArraySize(aDbConfig) ){ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 50976ee163..03e92a4c30 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2265,6 +2265,33 @@ struct sqlite3_mem_methods { ** compile-time option. ** ** +** [[SQLITE_DBCONFIG_UNSAFE_FUNC_IN_VIEW]] +**
SQLITE_DBCONFIG_UNSAFE_FUNC_IN_VIEW +**
The SQLITE_DBCONFIG_UNSAFE_FUNC_IN_VIEW option activates or deactivates +** the ability to use SQL functions that have side-effects inside of +** triggers and views. For legacy compatibility, this setting defaults +** to "on". Applications that are operating on untrusted database files +** are advised to change this setting to "off". When this setting is on, +** only functions that have no side effects are usable inside of views. +** This prevents an attacker from modifying the schema of a database so +** that views and/or triggers with undesirable side-effects are run when +** the application innocently tries to access what it thinks is an ordinary +** table. +**
+** +** [[SQLITE_DBCONFIG_VTAB_IN_VIEW]] +**
SQLITE_DBCONFIG_VTAB_IN_VIEW +**
The SQLITE_DBCONFIG_VTAB_IN_VIEW option activates or deactivates +** the ability to use [virtual tables] inside of triggers and views. +** For legacy compatibility, this setting defaults +** to "on". Applications that are operating on untrusted database files +** are advised to change this setting to "off". Turning this setting off +** prevents an attacker from modifying the schema of a database so +** that views and/or triggers with undesirable side-effects are run when +** the application innocently tries to access what it thinks is an ordinary +** table. +**
+** ** [[SQLITE_DBCONFIG_LEGACY_FILE_FORMAT]] **
SQLITE_DBCONFIG_LEGACY_FILE_FORMAT **
The SQLITE_DBCONFIG_LEGACY_FILE_FORMAT option activates or deactivates @@ -2305,7 +2332,9 @@ struct sqlite3_mem_methods { #define SQLITE_DBCONFIG_DQS_DDL 1014 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */ #define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 1016 /* int int* */ -#define SQLITE_DBCONFIG_MAX 1016 /* Largest DBCONFIG */ +#define SQLITE_DBCONFIG_UNSAFE_FUNC_IN_VIEW 1017 /* int int* */ +#define SQLITE_DBCONFIG_VTAB_IN_VIEW 1018 /* int int* */ +#define SQLITE_DBCONFIG_MAX 1018 /* Largest DBCONFIG */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 0dcb103532..d0452f548c 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1142,6 +1142,7 @@ typedef struct With With; ** A bit in a Bitmask */ #define MASKBIT(n) (((Bitmask)1)<<(n)) +#define MASKBIT64(n) (((u64)1)<<(n)) #define MASKBIT32(n) (((unsigned int)1)<<(n)) #define ALLBITS ((Bitmask)-1) @@ -1526,6 +1527,13 @@ struct sqlite3 { #define SCHEMA_ENC(db) ((db)->aDb[0].pSchema->enc) #define ENC(db) ((db)->enc) +/* +** A u64 constant where the lower 32 bits are all zeros. Only the +** upper 32 bits are included in the argument. Necessary because some +** C-compilers still do not accept LL integer literals. +*/ +#define HI(X) ((u64)(X)<<32) + /* ** Possible values for the sqlite3.flags. ** @@ -1541,11 +1549,10 @@ struct sqlite3 { #define SQLITE_CkptFullFSync 0x00000010 /* Use full fsync for checkpoint */ #define SQLITE_CacheSpill 0x00000020 /* OK to spill pager cache */ #define SQLITE_ShortColNames 0x00000040 /* Show short columns names */ -#define SQLITE_CountRows 0x00000080 /* Count rows changed by INSERT, */ - /* DELETE, or UPDATE and return */ - /* the count using a callback. */ -#define SQLITE_NullCallback 0x00000100 /* Invoke the callback once if the */ - /* result set is empty */ +#define SQLITE_UnsafeInView 0x00000080 /* Allow functions with side-effect + ** in triggers and views */ +#define SQLITE_VtabInView 0x00000100 /* Allow views and triggers to access + ** virtual tables */ #define SQLITE_IgnoreChecks 0x00000200 /* Do not enforce check constraints */ #define SQLITE_ReadUncommit 0x00000400 /* READ UNCOMMITTED in shared-cache */ #define SQLITE_NoCkptOnClose 0x00000800 /* No checkpoint on close()/DETACH */ @@ -1569,9 +1576,13 @@ struct sqlite3 { #define SQLITE_DqsDDL 0x20000000 /* dbl-quoted strings allowed in DDL*/ #define SQLITE_DqsDML 0x40000000 /* dbl-quoted strings allowed in DML*/ #define SQLITE_EnableView 0x80000000 /* Enable the use of views */ +#define SQLITE_CountRows HI(0x00001) /* Count rows changed by INSERT, */ + /* DELETE, or UPDATE and return */ + /* the count using a callback. */ +#define SQLITE_NullCallback HI(0000002) /* Invoke the callback once if the */ + /* result set is empty */ /* Flags used only if debugging */ -#define HI(X) ((u64)(X)<<32) #ifdef SQLITE_DEBUG #define SQLITE_SqlTrace HI(0x0100000) /* Debug print SQL as it executes */ #define SQLITE_VdbeListing HI(0x0200000) /* Debug listings of VDBE progs */ From c4ad849921ff0840deca5285d8934e898b1261cd Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 3 Jan 2020 20:57:38 +0000 Subject: [PATCH 02/22] When UNSAFE_IN_VIEW is disabled, only allow functions in views that are tagged with SQLITE_INNOCUOUS. FossilOrigin-Name: 9ee79b254e4c51a2a41f7ed49ad389d8d7105e649483adb79772052fa0ade3c0 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/main.c | 4 +++- src/resolve.c | 28 +++++++++++++--------------- src/sqlite.h.in | 19 +++++++++++++++++-- src/sqliteInt.h | 24 +++++++++++++++--------- 6 files changed, 58 insertions(+), 37 deletions(-) diff --git a/manifest b/manifest index 15f785bf63..a67c93395c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sfixes\sfrom\strunk. -D 2020-01-03T15:22:54.803 +C When\sUNSAFE_IN_VIEW\sis\sdisabled,\sonly\sallow\sfunctions\sin\sviews\sthat\sare\ntagged\swith\sSQLITE_INNOCUOUS. +D 2020-01-03T20:57:38.480 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -492,7 +492,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 5ba8fd376f539240939ae76b5bc9fa7ad9a0d86e9914ecd11eb7002204138c11 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c d74f5e7bd51f3c9d283442473eb65aef359664efd6513591c03f01881c4ae2da -F src/main.c 939e0ff163bd4c96362f7c81be98a8d7a043d1bf1eb250ea7119d39c27d6c5ac +F src/main.c 2dfc4695d00025100e9a2cf908afb2a3fce5ee067c52ddad1cf835d3a3d5aae1 F src/malloc.c eaa4dc9602ce28b077f7de2eb275db2be270c5cc56d7fec5466301bd9b80e2f5 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -526,14 +526,14 @@ F src/pragma.h ec3b31eac9b1df040f1cc8cb3d89bc06605c3b4cb3d76f833de8d6d6c3f77f04 F src/prepare.c 6049beb71385f017af6fc320d2c75a4e50b75e280c54232442b785fbb83df057 F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c 3868d75d4bbf8e7d3c78b9cd9c8ec5b483d004cf671a35ee2f18e5ed907d4bde +F src/resolve.c 70eda312d1044b4375ad78b8515ee2f638a8a61f5e71ec073ae99a73ba846bef F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 64bf450dc0f2b37be8d2be6ff7d25a70de37ef6fb64527c68f767fe9fe47bc55 F src/shell.c.in 69462c95793d69a16df93deabbd6d026f5f6ef6c87d9da54ed1477c03490d17b -F src/sqlite.h.in efaecabd038dc30282f243af087c4960e528d0df25a05f90f988435fec5ef779 +F src/sqlite.h.in 7f3178430f94f30a105bbaa6ed3ff44c9a16784d3d7783e306c0b9dd735ba599 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 72af51aa4e912e14cd495fb6e7fac65f0940db80ed950d90911aff292cc47ce2 -F src/sqliteInt.h a45a681d64b1f86e8baac511d81e7ac11825efb929081ae75601391a9e4e2e7d +F src/sqliteInt.h 0ba7721a5fb78f1700284a48583d62279f8d890bb63477e7f45fb7297726d087 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1853,7 +1853,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 091403a6705f5f1352c76eacbfdca75fe0bab12ab9b156842641de07c38d3f66 536e9a9d1bd514056ecbc8172ed58f2656a86f791a15e526ae2e5f2c93687b6a -R 9513c96f193ce58d39e33f5bdd19fac1 +P 002406df22995880d002be2e4cebb4d560283d4e0d7a4b5a34edcb110802b543 +R ffbc2f459e8917962197eed185bd6b4a U drh -Z 07648178e3cddd9499b97db1756ee9dd +Z d68f1f3db35645e195a57ca8b6527579 diff --git a/manifest.uuid b/manifest.uuid index a5bfac2f65..b875ae02c2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -002406df22995880d002be2e4cebb4d560283d4e0d7a4b5a34edcb110802b543 \ No newline at end of file +9ee79b254e4c51a2a41f7ed49ad389d8d7105e649483adb79772052fa0ade3c0 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 9838b34198..5e6ff16543 100644 --- a/src/main.c +++ b/src/main.c @@ -1760,7 +1760,9 @@ int sqlite3CreateFunc( assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY ); - extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY|SQLITE_SUBTYPE); + assert( SQLITE_FUNC_SAFE==SQLITE_INNOCUOUS ); + extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY| + SQLITE_SUBTYPE|SQLITE_INNOCUOUS); enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY); #ifndef SQLITE_OMIT_UTF16 diff --git a/src/resolve.c b/src/resolve.c index 4587540d33..f934cf6029 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -866,16 +866,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ ** constant because they are constant for the duration of one query. ** This allows them to be factored out of inner loops. */ ExprSetProperty(pExpr,EP_ConstFunc); - }else{ - if( ExprHasProperty(pExpr, EP_Indirect) - && !IN_RENAME_OBJECT - && (pParse->db->flags & SQLITE_UnsafeInView)==0 - ){ - /* If SQLITE_DBCONFIG_UNSAFE_IN_VIEW is off, then functions with - ** side effects are not allowed inside triggers and views. */ - sqlite3ErrorMsg(pParse, "%s() prohibited in triggers and views", - pDef->zName); - } } if( (pDef->funcFlags & SQLITE_FUNC_CONSTANT)==0 ){ /* Date/time functions that use 'now', and other functions like @@ -896,14 +886,22 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ no_such_func = 1; pDef = 0; }else - if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0 + if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_SAFE)) + != SQLITE_FUNC_SAFE && ExprHasProperty(pExpr, EP_Indirect) && !IN_RENAME_OBJECT ){ - /* Functions tagged with SQLITE_DIRECTONLY may not be used - ** inside of triggers and views */ - sqlite3ErrorMsg(pParse, "%s() prohibited in triggers and views", - pDef->zName); + if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0 + || (pParse->db->flags & SQLITE_UnsafeInView)==0 + ){ + /* Functions prohibited in triggers and views if: + ** (1) tagged with SQLITE_DIRECTONLY + ** (2) not tagged with SQLITE_INNOCUOUS and + ** SQLITE_DBCONFIG_UNSAFE_IN_VIEW is off + */ + sqlite3ErrorMsg(pParse, "%s() prohibited in triggers and views", + pDef->zName); + } } } diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 03e92a4c30..dc8bf4a384 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -5025,12 +5025,26 @@ int sqlite3_create_window_function( ** [sqlite3_create_function_v2()]. ** ** The SQLITE_DETERMINISTIC flag means that the new function always gives -** the same output when the input parameters are the same. The abs() function -** is deterministic, for example, but randomblob() is not. Functions must +** the same output when the input parameters are the same. +** The [abs|abs() function] is deterministic, for example, but +** [randomblob|randomblob()] is not. Functions must ** be deterministic in order to be used in certain contexts such as ** [CHECK constraints] or [generated columns]. SQLite might also optimize ** deterministic functions by factoring them out of inner loops. ** +** The SQLITE_INNOCUOUS flag means that the new function is unlikely +** to cause problems even if misused. An innocuous function should have +** no side effects and consume few resources. The [abs|abs() function] +** is an example of an innocuous function. +** The [load_extension() SQL function] is not innocuous because of its +** side effects. Some heightened security settings +** ([SQLITE_DBCONFIG_UNSAFE_FUNC_IN_VIEW]) +** disable the use of SQLlfunctions inside views and triggers unless +** the function is tagged with SQLITE_INNOCUOUS. Most built-in functions +** are innocuous. Developers are advised to avoid using the +** SQLITE_INNOCUOUS flag for application-defined functions unless the +** function is specifically intended for use inside of views and triggers. +** ** The SQLITE_DIRECTONLY flag means that the function may only be invoked ** from top-level SQL, and cannot be used in VIEWs or TRIGGERs. This is ** a security feature which is recommended for all @@ -5050,6 +5064,7 @@ int sqlite3_create_window_function( #define SQLITE_DETERMINISTIC 0x000000800 #define SQLITE_DIRECTONLY 0x000080000 #define SQLITE_SUBTYPE 0x000100000 +#define SQLITE_INNOCUOUS 0x000200000 /* ** CAPI3REF: Deprecated Functions diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 24b656d9ac..34dd74ac56 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1740,6 +1740,7 @@ struct FuncDestructor { ** SQLITE_FUNC_TYPEOF == OPFLAG_TYPEOFARG ** SQLITE_FUNC_CONSTANT == SQLITE_DETERMINISTIC from the API ** SQLITE_FUNC_DIRECT == SQLITE_DIRECTONLY from the API +** SQLITE_FUNC_SAFE == SQLITE_INNOCUOUS ** SQLITE_FUNC_ENCMASK depends on SQLITE_UTF* macros in the API */ #define SQLITE_FUNC_ENCMASK 0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */ @@ -1762,7 +1763,11 @@ struct FuncDestructor { #define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */ #define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */ #define SQLITE_FUNC_SUBTYPE 0x00100000 /* Result likely to have sub-type */ -#define SQLITE_FUNC_INLINE 0x00200000 /* Functions implemented in-line */ +#define SQLITE_FUNC_SAFE 0x00200000 /* Function has no side effects */ +#define SQLITE_FUNC_INLINE 0x00400000 /* Functions implemented in-line */ + +/* Combination flags */ +#define SQLITE_FUNC_PURE (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SAFE) /* Identifier numbers for each in-line function */ #define INLINEFUNC_coalesce 0 @@ -1836,7 +1841,7 @@ struct FuncDestructor { ** parameter. */ #define FUNCTION(zName, nArg, iArg, bNC, xFunc) \ - {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ + {nArg, SQLITE_FUNC_PURE|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } #define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ @@ -1845,26 +1850,27 @@ struct FuncDestructor { {nArg, SQLITE_UTF8|SQLITE_DIRECTONLY, \ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } #define INLINE_FUNC(zName, nArg, iArg, mFlags) \ - {nArg, SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \ + {nArg, SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_PURE|(mFlags), \ SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} } #define TEST_FUNC(zName, nArg, iArg, mFlags) \ {nArg, SQLITE_UTF8|SQLITE_FUNC_INTERNAL|SQLITE_FUNC_TEST| \ - SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \ + SQLITE_FUNC_INLINE|(mFlags), \ SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} } #define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \ - {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8, \ + {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_FUNC_SAFE|SQLITE_UTF8, \ 0, 0, xFunc, 0, 0, 0, #zName, {0} } #define PURE_DATE(zName, nArg, iArg, bNC, xFunc) \ - {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \ + {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|SQLITE_FUNC_PURE, \ (void*)&sqlite3Config, 0, xFunc, 0, 0, 0, #zName, {0} } #define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \ - {nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\ + {nArg,SQLITE_FUNC_PURE|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } #define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \ - {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ + {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_FUNC_SAFE| \ + SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ pArg, 0, xFunc, 0, 0, 0, #zName, } #define LIKEFUNC(zName, nArg, arg, flags) \ - {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \ + {nArg, SQLITE_FUNC_PURE|SQLITE_UTF8|flags, \ (void *)arg, 0, likeFunc, 0, 0, 0, #zName, {0} } #define WAGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue, xInverse, f) \ {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \ From 4be621e1ba6a5ef729cf4f90896b16421fc6a4e2 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 3 Jan 2020 21:57:53 +0000 Subject: [PATCH 03/22] Invert the SQLITE_FUNC_SAFE bit to be SQLITE_FUNC_UNSAFE. The external bit is still SQLITE_INNOCUOUS. It gets inverted as the appdef function is registered. FossilOrigin-Name: 1c266cb3be46d26e640752a99979acb1a1809361ba70ca3fca981c42383c360e --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/main.c | 7 ++++++- src/resolve.c | 6 +++--- src/sqliteInt.h | 24 ++++++++++-------------- 5 files changed, 28 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index a67c93395c..598ef1b796 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sUNSAFE_IN_VIEW\sis\sdisabled,\sonly\sallow\sfunctions\sin\sviews\sthat\sare\ntagged\swith\sSQLITE_INNOCUOUS. -D 2020-01-03T20:57:38.480 +C Invert\sthe\sSQLITE_FUNC_SAFE\sbit\sto\sbe\sSQLITE_FUNC_UNSAFE.\s\sThe\sexternal\nbit\sis\sstill\sSQLITE_INNOCUOUS.\s\sIt\sgets\sinverted\sas\sthe\sappdef\sfunction\nis\sregistered. +D 2020-01-03T21:57:53.010 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -492,7 +492,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 5ba8fd376f539240939ae76b5bc9fa7ad9a0d86e9914ecd11eb7002204138c11 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c d74f5e7bd51f3c9d283442473eb65aef359664efd6513591c03f01881c4ae2da -F src/main.c 2dfc4695d00025100e9a2cf908afb2a3fce5ee067c52ddad1cf835d3a3d5aae1 +F src/main.c bca003eae084faa6a93847fc103831d506789bad3121b2f7a8a14f92cee5884b F src/malloc.c eaa4dc9602ce28b077f7de2eb275db2be270c5cc56d7fec5466301bd9b80e2f5 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -526,14 +526,14 @@ F src/pragma.h ec3b31eac9b1df040f1cc8cb3d89bc06605c3b4cb3d76f833de8d6d6c3f77f04 F src/prepare.c 6049beb71385f017af6fc320d2c75a4e50b75e280c54232442b785fbb83df057 F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c 70eda312d1044b4375ad78b8515ee2f638a8a61f5e71ec073ae99a73ba846bef +F src/resolve.c c15dbf93b031e82fe19bfedacca72c520b616a0c02d6aac660073bf1ef5299ba F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 64bf450dc0f2b37be8d2be6ff7d25a70de37ef6fb64527c68f767fe9fe47bc55 F src/shell.c.in 69462c95793d69a16df93deabbd6d026f5f6ef6c87d9da54ed1477c03490d17b F src/sqlite.h.in 7f3178430f94f30a105bbaa6ed3ff44c9a16784d3d7783e306c0b9dd735ba599 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 72af51aa4e912e14cd495fb6e7fac65f0940db80ed950d90911aff292cc47ce2 -F src/sqliteInt.h 0ba7721a5fb78f1700284a48583d62279f8d890bb63477e7f45fb7297726d087 +F src/sqliteInt.h 16ece06f4b6538455a5a5960b47118c431edfa505258ef2c9fc03efebf65afea F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1853,7 +1853,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 002406df22995880d002be2e4cebb4d560283d4e0d7a4b5a34edcb110802b543 -R ffbc2f459e8917962197eed185bd6b4a +P 9ee79b254e4c51a2a41f7ed49ad389d8d7105e649483adb79772052fa0ade3c0 +R ddc48ddbd6fd5ffcaeac23e5df6802fd U drh -Z d68f1f3db35645e195a57ca8b6527579 +Z b1286d15b3f3c1b252630c4f9a042db9 diff --git a/manifest.uuid b/manifest.uuid index b875ae02c2..f29a681adb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9ee79b254e4c51a2a41f7ed49ad389d8d7105e649483adb79772052fa0ade3c0 \ No newline at end of file +1c266cb3be46d26e640752a99979acb1a1809361ba70ca3fca981c42383c360e \ No newline at end of file diff --git a/src/main.c b/src/main.c index 5e6ff16543..34485f0be9 100644 --- a/src/main.c +++ b/src/main.c @@ -1760,10 +1760,15 @@ int sqlite3CreateFunc( assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY ); - assert( SQLITE_FUNC_SAFE==SQLITE_INNOCUOUS ); extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY| SQLITE_SUBTYPE|SQLITE_INNOCUOUS); enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY); + + /* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But + ** the meaning is inverted. So flip the bit. */ + assert( SQLITE_FUNC_UNSAFE==SQLITE_INNOCUOUS ); + extraFlags ^= SQLITE_FUNC_UNSAFE; + #ifndef SQLITE_OMIT_UTF16 /* If SQLITE_UTF16 is specified as the encoding type, transform this diff --git a/src/resolve.c b/src/resolve.c index f934cf6029..ef77d8be5d 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -886,8 +886,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ no_such_func = 1; pDef = 0; }else - if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_SAFE)) - != SQLITE_FUNC_SAFE + if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0 && ExprHasProperty(pExpr, EP_Indirect) && !IN_RENAME_OBJECT ){ @@ -896,7 +895,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ ){ /* Functions prohibited in triggers and views if: ** (1) tagged with SQLITE_DIRECTONLY - ** (2) not tagged with SQLITE_INNOCUOUS and + ** (2) not tagged with SQLITE_INNOCUOUS (which means it + ** is tagged with SQLITE_FUNC_UNSAFE) and ** SQLITE_DBCONFIG_UNSAFE_IN_VIEW is off */ sqlite3ErrorMsg(pParse, "%s() prohibited in triggers and views", diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 34dd74ac56..37ef76eb51 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1740,7 +1740,7 @@ struct FuncDestructor { ** SQLITE_FUNC_TYPEOF == OPFLAG_TYPEOFARG ** SQLITE_FUNC_CONSTANT == SQLITE_DETERMINISTIC from the API ** SQLITE_FUNC_DIRECT == SQLITE_DIRECTONLY from the API -** SQLITE_FUNC_SAFE == SQLITE_INNOCUOUS +** SQLITE_FUNC_UNSAFE == SQLITE_INNOCUOUS ** SQLITE_FUNC_ENCMASK depends on SQLITE_UTF* macros in the API */ #define SQLITE_FUNC_ENCMASK 0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */ @@ -1763,12 +1763,9 @@ struct FuncDestructor { #define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */ #define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */ #define SQLITE_FUNC_SUBTYPE 0x00100000 /* Result likely to have sub-type */ -#define SQLITE_FUNC_SAFE 0x00200000 /* Function has no side effects */ +#define SQLITE_FUNC_UNSAFE 0x00200000 /* Function has side effects */ #define SQLITE_FUNC_INLINE 0x00400000 /* Functions implemented in-line */ -/* Combination flags */ -#define SQLITE_FUNC_PURE (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SAFE) - /* Identifier numbers for each in-line function */ #define INLINEFUNC_coalesce 0 #define INLINEFUNC_implies_nonnull_row 1 @@ -1841,7 +1838,7 @@ struct FuncDestructor { ** parameter. */ #define FUNCTION(zName, nArg, iArg, bNC, xFunc) \ - {nArg, SQLITE_FUNC_PURE|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ + {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } #define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ @@ -1850,27 +1847,26 @@ struct FuncDestructor { {nArg, SQLITE_UTF8|SQLITE_DIRECTONLY, \ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } #define INLINE_FUNC(zName, nArg, iArg, mFlags) \ - {nArg, SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_PURE|(mFlags), \ + {nArg, SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \ SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} } #define TEST_FUNC(zName, nArg, iArg, mFlags) \ {nArg, SQLITE_UTF8|SQLITE_FUNC_INTERNAL|SQLITE_FUNC_TEST| \ - SQLITE_FUNC_INLINE|(mFlags), \ + SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \ SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} } #define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \ - {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_FUNC_SAFE|SQLITE_UTF8, \ + {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8, \ 0, 0, xFunc, 0, 0, 0, #zName, {0} } #define PURE_DATE(zName, nArg, iArg, bNC, xFunc) \ - {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|SQLITE_FUNC_PURE, \ + {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \ (void*)&sqlite3Config, 0, xFunc, 0, 0, 0, #zName, {0} } #define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \ - {nArg,SQLITE_FUNC_PURE|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\ + {nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } #define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \ - {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_FUNC_SAFE| \ - SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ + {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ pArg, 0, xFunc, 0, 0, 0, #zName, } #define LIKEFUNC(zName, nArg, arg, flags) \ - {nArg, SQLITE_FUNC_PURE|SQLITE_UTF8|flags, \ + {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \ (void *)arg, 0, likeFunc, 0, 0, 0, #zName, {0} } #define WAGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue, xInverse, f) \ {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \ From 79d5bc80c7d448955e7c1ee191e8f3a4b5920368 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 4 Jan 2020 01:43:02 +0000 Subject: [PATCH 04/22] Enhance PRAGMA function_list so that it shows all instances of each FuncDef, the number of arguments, the encoding, the type, and the flags. Use this capability to locate and fix incorrect function flags in the standard build. FossilOrigin-Name: 9ca906d24a2e88eddb2fd067783512b66cfc49dce1596d816a1c38a09d128218 --- ext/icu/icu.c | 27 +++++++-------- ext/misc/json1.c | 9 +++-- ext/rtree/geopoly.c | 12 +++++-- manifest | 28 ++++++++-------- manifest.uuid | 2 +- src/main.c | 8 +++-- src/pragma.c | 46 ++++++++++++++++++++++++-- src/pragma.h | 78 +++++++++++++++++++++++--------------------- src/sqliteInt.h | 2 +- test/pragma5.test | 10 ++++-- tool/mkpragmatab.tcl | 2 +- 11 files changed, 143 insertions(+), 81 deletions(-) diff --git a/ext/icu/icu.c b/ext/icu/icu.c index 13524ebc2a..7fbe32a7eb 100644 --- a/ext/icu/icu.c +++ b/ext/icu/icu.c @@ -499,26 +499,27 @@ static void icuLoadCollation( ** Register the ICU extension functions with database db. */ int sqlite3IcuInit(sqlite3 *db){ +# define SQLITEICU_EXTRAFLAGS (SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS) static const struct IcuScalar { const char *zName; /* Function name */ unsigned char nArg; /* Number of arguments */ - unsigned short enc; /* Optimal text encoding */ + unsigned int enc; /* Optimal text encoding */ unsigned char iContext; /* sqlite3_user_data() context */ void (*xFunc)(sqlite3_context*,int,sqlite3_value**); } scalars[] = { - {"icu_load_collation", 2, SQLITE_UTF8, 1, icuLoadCollation}, + {"icu_load_collation",2,SQLITE_UTF8|SQLITE_DIRECTONLY,1, icuLoadCollation}, #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) - {"regexp", 2, SQLITE_ANY|SQLITE_DETERMINISTIC, 0, icuRegexpFunc}, - {"lower", 1, SQLITE_UTF16|SQLITE_DETERMINISTIC, 0, icuCaseFunc16}, - {"lower", 2, SQLITE_UTF16|SQLITE_DETERMINISTIC, 0, icuCaseFunc16}, - {"upper", 1, SQLITE_UTF16|SQLITE_DETERMINISTIC, 1, icuCaseFunc16}, - {"upper", 2, SQLITE_UTF16|SQLITE_DETERMINISTIC, 1, icuCaseFunc16}, - {"lower", 1, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuCaseFunc16}, - {"lower", 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuCaseFunc16}, - {"upper", 1, SQLITE_UTF8|SQLITE_DETERMINISTIC, 1, icuCaseFunc16}, - {"upper", 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, 1, icuCaseFunc16}, - {"like", 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuLikeFunc}, - {"like", 3, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuLikeFunc}, + {"regexp", 2, SQLITE_ANY|SQLITEICU_EXTRAFLAGS, 0, icuRegexpFunc}, + {"lower", 1, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 0, icuCaseFunc16}, + {"lower", 2, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 0, icuCaseFunc16}, + {"upper", 1, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 1, icuCaseFunc16}, + {"upper", 2, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 1, icuCaseFunc16}, + {"lower", 1, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS, 0, icuCaseFunc16}, + {"lower", 2, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS, 0, icuCaseFunc16}, + {"upper", 1, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS, 1, icuCaseFunc16}, + {"upper", 2, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS, 1, icuCaseFunc16}, + {"like", 2, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS, 0, icuLikeFunc}, + {"like", 3, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS, 0, icuLikeFunc}, #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) */ }; int rc = SQLITE_OK; diff --git a/ext/misc/json1.c b/ext/misc/json1.c index 012ac4a890..006186b679 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -2581,16 +2581,19 @@ int sqlite3Json1Init(sqlite3 *db){ { "json_tree", &jsonTreeModule }, }; #endif + static const int enc = + SQLITE_UTF8 | + SQLITE_DETERMINISTIC | + SQLITE_INNOCUOUS; for(i=0; iupr ? 0 : &aPragmaName[mid]; } +/* +** Create zero or more entries in the output for the SQL functions +** defined by FuncDef p. +*/ +static void pragmaFunclistLine(Vdbe *v, FuncDef *p, int isBuiltin){ + for(; p; p=p->pNext){ + const char *zType; + const char *zEnc; + static const u32 mask = + SQLITE_DETERMINISTIC | + SQLITE_DIRECTONLY | + SQLITE_SUBTYPE | + SQLITE_INNOCUOUS + ; + + if( p->xSFunc==0 ) continue; + if( p->xValue!=0 ){ + zType = "w"; + }else if( p->xFinalize!=0 ){ + zType = "a"; + }else{ + zType = "s"; + } + if( p->funcFlags & SQLITE_UTF8 ){ + zEnc = "utf8"; + }else if( p->funcFlags & SQLITE_UTF16BE ){ + zEnc = "utf16be"; + }else{ + zEnc = "utf16le"; + } + sqlite3VdbeMultiLoad(v, 1, "sissii", + p->zName, isBuiltin, + zType, zEnc, + p->nArg, + (p->funcFlags & mask) ^ SQLITE_INNOCUOUS + ); + } +} + + /* ** Helper subroutine for PRAGMA integrity_check: ** @@ -1259,16 +1299,16 @@ void sqlite3Pragma( int i; HashElem *j; FuncDef *p; - pParse->nMem = 2; + pParse->nMem = 6; for(i=0; iu.pHash ){ if( p->funcFlags & SQLITE_FUNC_INTERNAL ) continue; - sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 1); + pragmaFunclistLine(v, p, 1); } } for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){ p = (FuncDef*)sqliteHashData(j); - sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 0); + pragmaFunclistLine(v, p, 0); } } break; diff --git a/src/pragma.h b/src/pragma.h index eadbf93b41..449180ba13 100644 --- a/src/pragma.h +++ b/src/pragma.h @@ -88,35 +88,39 @@ static const char *const pragCName[] = { /* 18 */ "desc", /* 19 */ "coll", /* 20 */ "key", - /* 21 */ "tbl", /* Used by: stats */ - /* 22 */ "idx", - /* 23 */ "wdth", - /* 24 */ "hght", - /* 25 */ "flgs", - /* 26 */ "seq", /* Used by: index_list */ - /* 27 */ "name", - /* 28 */ "unique", - /* 29 */ "origin", - /* 30 */ "partial", - /* 31 */ "table", /* Used by: foreign_key_check */ - /* 32 */ "rowid", - /* 33 */ "parent", - /* 34 */ "fkid", + /* 21 */ "name", /* Used by: function_list */ + /* 22 */ "builtin", + /* 23 */ "type", + /* 24 */ "enc", + /* 25 */ "narg", + /* 26 */ "flags", + /* 27 */ "tbl", /* Used by: stats */ + /* 28 */ "idx", + /* 29 */ "wdth", + /* 30 */ "hght", + /* 31 */ "flgs", + /* 32 */ "seq", /* Used by: index_list */ + /* 33 */ "name", + /* 34 */ "unique", + /* 35 */ "origin", + /* 36 */ "partial", + /* 37 */ "table", /* Used by: foreign_key_check */ + /* 38 */ "rowid", + /* 39 */ "parent", + /* 40 */ "fkid", /* index_info reuses 15 */ - /* 35 */ "seq", /* Used by: database_list */ - /* 36 */ "name", - /* 37 */ "file", - /* 38 */ "busy", /* Used by: wal_checkpoint */ - /* 39 */ "log", - /* 40 */ "checkpointed", - /* 41 */ "name", /* Used by: function_list */ - /* 42 */ "builtin", - /* collation_list reuses 26 */ - /* 43 */ "database", /* Used by: lock_status */ - /* 44 */ "status", - /* 45 */ "cache_size", /* Used by: default_cache_size */ + /* 41 */ "seq", /* Used by: database_list */ + /* 42 */ "name", + /* 43 */ "file", + /* 44 */ "busy", /* Used by: wal_checkpoint */ + /* 45 */ "log", + /* 46 */ "checkpointed", + /* collation_list reuses 32 */ + /* 47 */ "database", /* Used by: lock_status */ + /* 48 */ "status", + /* 49 */ "cache_size", /* Used by: default_cache_size */ /* module_list pragma_list reuses 9 */ - /* 46 */ "timeout", /* Used by: busy_timeout */ + /* 50 */ "timeout", /* Used by: busy_timeout */ }; /* Definitions of all built-in pragmas */ @@ -162,7 +166,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "busy_timeout", /* ePragTyp: */ PragTyp_BUSY_TIMEOUT, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 46, 1, + /* ColNames: */ 50, 1, /* iArg: */ 0 }, #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) {/* zName: */ "cache_size", @@ -201,7 +205,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "collation_list", /* ePragTyp: */ PragTyp_COLLATION_LIST, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 26, 2, + /* ColNames: */ 32, 2, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) @@ -236,14 +240,14 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "database_list", /* ePragTyp: */ PragTyp_DATABASE_LIST, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0, - /* ColNames: */ 35, 3, + /* ColNames: */ 41, 3, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) {/* zName: */ "default_cache_size", /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, - /* ColNames: */ 45, 1, + /* ColNames: */ 49, 1, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) @@ -273,7 +277,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "foreign_key_check", /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0, - /* ColNames: */ 31, 4, + /* ColNames: */ 37, 4, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FOREIGN_KEY) @@ -316,7 +320,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "function_list", /* ePragTyp: */ PragTyp_FUNCTION_LIST, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 41, 2, + /* ColNames: */ 21, 6, /* iArg: */ 0 }, #endif #endif @@ -362,7 +366,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "index_list", /* ePragTyp: */ PragTyp_INDEX_LIST, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, - /* ColNames: */ 26, 5, + /* ColNames: */ 32, 5, /* iArg: */ 0 }, {/* zName: */ "index_xinfo", /* ePragTyp: */ PragTyp_INDEX_INFO, @@ -414,7 +418,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "lock_status", /* ePragTyp: */ PragTyp_LOCK_STATUS, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 43, 2, + /* ColNames: */ 47, 2, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) @@ -562,7 +566,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "stats", /* ePragTyp: */ PragTyp_STATS, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, - /* ColNames: */ 21, 5, + /* ColNames: */ 27, 5, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) @@ -658,7 +662,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "wal_checkpoint", /* ePragTyp: */ PragTyp_WAL_CHECKPOINT, /* ePragFlg: */ PragFlg_NeedSchema, - /* ColNames: */ 38, 3, + /* ColNames: */ 44, 3, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 37ef76eb51..e8eafe2b6b 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1844,7 +1844,7 @@ struct FuncDestructor { {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } #define SFUNCTION(zName, nArg, iArg, bNC, xFunc) \ - {nArg, SQLITE_UTF8|SQLITE_DIRECTONLY, \ + {nArg, SQLITE_UTF8|SQLITE_DIRECTONLY|SQLITE_FUNC_UNSAFE, \ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } #define INLINE_FUNC(zName, nArg, iArg, mFlags) \ {nArg, SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \ diff --git a/test/pragma5.test b/test/pragma5.test index f16e4627ba..6d9b5bbcdc 100644 --- a/test/pragma5.test +++ b/test/pragma5.test @@ -32,12 +32,18 @@ do_execsql_test 1.0 { } { 0 name {} 0 {} 0 1 builtin {} 0 {} 0 + 2 type {} 0 {} 0 + 3 enc {} 0 {} 0 + 4 narg {} 0 {} 0 + 5 flags {} 0 {} 0 } do_execsql_test 1.1 { - SELECT * FROM pragma_function_list WHERE name='upper' AND builtin + SELECT DISTINCT name, builtin + FROM pragma_function_list WHERE name='upper' AND builtin } {upper 1} do_execsql_test 1.2 { - SELECT * FROM pragma_function_list WHERE name LIKE 'exter%'; + SELECT DISTINCT name, builtin + FROM pragma_function_list WHERE name LIKE 'exter%'; } {external 0} ifcapable fts5 { diff --git a/tool/mkpragmatab.tcl b/tool/mkpragmatab.tcl index fa9edcdcc6..04c6416786 100644 --- a/tool/mkpragmatab.tcl +++ b/tool/mkpragmatab.tcl @@ -257,7 +257,7 @@ set pragma_def { NAME: function_list FLAG: Result0 - COLS: name builtin + COLS: name builtin type enc narg flags IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) IF: !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) From 337ca519e1c106bbcfa3b7b91c0fe68673e3cc42 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 4 Jan 2020 19:58:28 +0000 Subject: [PATCH 05/22] Enhance PRAGMA function_list to show internal functions if the direct use of internal functions is enabled via the SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test control. FossilOrigin-Name: 7a8d7ca726666f4384925f959df0d58f7622229e06f1b5e643a3caccd539bb6e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pragma.c | 23 +++++++++++++++++------ 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index b9177bbb7a..fc1ba87890 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sall\sfixes\sand\senhancements\sfrom\strunk. -D 2020-01-04T19:19:54.288 +C Enhance\sPRAGMA\sfunction_list\sto\sshow\sinternal\sfunctions\sif\sthe\sdirect\suse\nof\sinternal\sfunctions\sis\senabled\svia\sthe\sSQLITE_TESTCTRL_INTERNAL_FUNCTIONS\ntest\scontrol. +D 2020-01-04T19:58:28.209 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -521,7 +521,7 @@ F src/parse.y c8d2de64db469fd56e0fa24da46cd8ec8523eb98626567d2708df371b47fdc3f F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a -F src/pragma.c 4f5df0df55a3fd5adadc28744bee3de1d10a313b1ae0f8470ca4b2dc93cc5cbf +F src/pragma.c 6e13c9a885c0f2effaa6a1155b707d3d3e39bc572c3b003ce4caa9c2e9010ca3 F src/pragma.h 5bbfafd74cf085762b64e4e2b00242917951b30468e380bddd8be6c21789aec2 F src/prepare.c 6049beb71385f017af6fc320d2c75a4e50b75e280c54232442b785fbb83df057 F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 @@ -1853,7 +1853,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 26ef709a47294c512a70aecd37d29caecec2af261977d9fb2c4d78d09b12f77a 5b246b47aeadc25dbec0956e2d6edcd49fbe874a01734fdf15b770507648222d -R 23b6db5bd743b43a08b2a78aa5bfe764 +P b878c30f03e895bbc5c4c99c0f727d49093bb78bdc275593cf4852148579ae69 +R 2a316337c77b32f3140387723d41365c U drh -Z df93cd8dd048f13be0eda50d95f72385 +Z 5d85e17177ca37ac3e27744033bcda94 diff --git a/manifest.uuid b/manifest.uuid index 1ec699ac35..e5671db0ee 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b878c30f03e895bbc5c4c99c0f727d49093bb78bdc275593cf4852148579ae69 \ No newline at end of file +7a8d7ca726666f4384925f959df0d58f7622229e06f1b5e643a3caccd539bb6e \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 470cbdbdea..2c127ed5a7 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -299,7 +299,12 @@ static const PragmaName *pragmaLocate(const char *zName){ ** Create zero or more entries in the output for the SQL functions ** defined by FuncDef p. */ -static void pragmaFunclistLine(Vdbe *v, FuncDef *p, int isBuiltin){ +static void pragmaFunclistLine( + Vdbe *v, /* The prepared statement being created */ + FuncDef *p, /* A particular function definition */ + int isBuiltin, /* True if this is a built-in function */ + int showInternFuncs /* True if showing internal functions */ +){ for(; p; p=p->pNext){ const char *zType; const char *zEnc; @@ -307,10 +312,16 @@ static void pragmaFunclistLine(Vdbe *v, FuncDef *p, int isBuiltin){ SQLITE_DETERMINISTIC | SQLITE_DIRECTONLY | SQLITE_SUBTYPE | - SQLITE_INNOCUOUS + SQLITE_INNOCUOUS | + SQLITE_FUNC_INTERNAL ; - + if( p->xSFunc==0 ) continue; + if( (p->funcFlags & SQLITE_FUNC_INTERNAL)!=0 + && showInternFuncs==0 + ){ + continue; + } if( p->xValue!=0 ){ zType = "w"; }else if( p->xFinalize!=0 ){ @@ -1299,16 +1310,16 @@ void sqlite3Pragma( int i; HashElem *j; FuncDef *p; + int showInternFunc = (db->mDbFlags & DBFLAG_InternalFunc)!=0; pParse->nMem = 6; for(i=0; iu.pHash ){ - if( p->funcFlags & SQLITE_FUNC_INTERNAL ) continue; - pragmaFunclistLine(v, p, 1); + pragmaFunclistLine(v, p, 1, showInternFunc); } } for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){ p = (FuncDef*)sqliteHashData(j); - pragmaFunclistLine(v, p, 0); + pragmaFunclistLine(v, p, 0, showInternFunc); } } break; From 67c826536fba0cf3f430fc1abe42e0795de50de5 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 4 Jan 2020 20:58:41 +0000 Subject: [PATCH 06/22] Refactor the names of the new controls for restricting what actions the schema can take behind the application's back. FossilOrigin-Name: 65d7d39a858c51ffd781f5a6335e029895e597aeb1e1ccdadea8ce79c8ad412f --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/main.c | 6 ++---- src/resolve.c | 4 ++-- src/shell.c.in | 3 +-- src/sqlite.h.in | 43 +++++++++++++++---------------------------- src/sqliteInt.h | 10 ++++------ 7 files changed, 35 insertions(+), 53 deletions(-) diff --git a/manifest b/manifest index fc1ba87890..d3b967c6de 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sPRAGMA\sfunction_list\sto\sshow\sinternal\sfunctions\sif\sthe\sdirect\suse\nof\sinternal\sfunctions\sis\senabled\svia\sthe\sSQLITE_TESTCTRL_INTERNAL_FUNCTIONS\ntest\scontrol. -D 2020-01-04T19:58:28.209 +C Refactor\sthe\snames\sof\sthe\snew\scontrols\sfor\srestricting\swhat\sactions\sthe\sschema\ncan\stake\sbehind\sthe\sapplication's\sback. +D 2020-01-04T20:58:41.624 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -492,7 +492,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 5ba8fd376f539240939ae76b5bc9fa7ad9a0d86e9914ecd11eb7002204138c11 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c d74f5e7bd51f3c9d283442473eb65aef359664efd6513591c03f01881c4ae2da -F src/main.c 5e71133fdb94908d3575998fe13430a4875dd211e0cb48bc9e684f0a616d657e +F src/main.c 372f764daf1fd8f86ea87a2eb285faaed891300682e9fa5a2fd75c3a3e6c5af7 F src/malloc.c eaa4dc9602ce28b077f7de2eb275db2be270c5cc56d7fec5466301bd9b80e2f5 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -526,14 +526,14 @@ F src/pragma.h 5bbfafd74cf085762b64e4e2b00242917951b30468e380bddd8be6c21789aec2 F src/prepare.c 6049beb71385f017af6fc320d2c75a4e50b75e280c54232442b785fbb83df057 F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c c15dbf93b031e82fe19bfedacca72c520b616a0c02d6aac660073bf1ef5299ba +F src/resolve.c d368864894450413a78ab5381eea7f6deb2f1f7b10c7e6ca20cb345e5a7b9281 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 64bf450dc0f2b37be8d2be6ff7d25a70de37ef6fb64527c68f767fe9fe47bc55 -F src/shell.c.in 69462c95793d69a16df93deabbd6d026f5f6ef6c87d9da54ed1477c03490d17b -F src/sqlite.h.in 7f3178430f94f30a105bbaa6ed3ff44c9a16784d3d7783e306c0b9dd735ba599 +F src/shell.c.in 0fcf24b526e35eb2e02212e2504b695f79992ccc69b8be0f841276abea037008 +F src/sqlite.h.in 600fd6093a03112831e2658daac299d2a803ffcd3d7f4f6b091a447f79b4d6c2 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 72af51aa4e912e14cd495fb6e7fac65f0940db80ed950d90911aff292cc47ce2 -F src/sqliteInt.h 5a27f5858868acddf980dc879d02e6d1b1455853adc17ebab7376ab63fa0a505 +F src/sqliteInt.h 002066fa9a7ea1dacdca6f395968d4eed0fcf2978ac1f7528c61cb6e65f52e6e F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1853,7 +1853,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 b878c30f03e895bbc5c4c99c0f727d49093bb78bdc275593cf4852148579ae69 -R 2a316337c77b32f3140387723d41365c +P 7a8d7ca726666f4384925f959df0d58f7622229e06f1b5e643a3caccd539bb6e +R f9fb8a85043cff3871f686f554fff1c5 U drh -Z 5d85e17177ca37ac3e27744033bcda94 +Z 2b34921532ba1ddcc3f837ba912e08b2 diff --git a/manifest.uuid b/manifest.uuid index e5671db0ee..3d1543ad1f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7a8d7ca726666f4384925f959df0d58f7622229e06f1b5e643a3caccd539bb6e \ No newline at end of file +65d7d39a858c51ffd781f5a6335e029895e597aeb1e1ccdadea8ce79c8ad412f \ No newline at end of file diff --git a/src/main.c b/src/main.c index 6632e54a8a..b96d99038f 100644 --- a/src/main.c +++ b/src/main.c @@ -887,8 +887,7 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){ { SQLITE_DBCONFIG_DQS_DDL, SQLITE_DqsDDL }, { SQLITE_DBCONFIG_DQS_DML, SQLITE_DqsDML }, { SQLITE_DBCONFIG_LEGACY_FILE_FORMAT, SQLITE_LegacyFileFmt }, - { SQLITE_DBCONFIG_UNSAFE_FUNC_IN_VIEW, SQLITE_UnsafeInView }, - { SQLITE_DBCONFIG_VTAB_IN_VIEW, SQLITE_VtabInView }, + { SQLITE_DBCONFIG_ENABLE_UNSAFE_DDL, SQLITE_UnsafeDDL }, }; unsigned int i; rc = SQLITE_ERROR; /* IMP: R-42790-23372 */ @@ -3128,8 +3127,7 @@ static int openDatabase( | SQLITE_EnableTrigger | SQLITE_EnableView | SQLITE_CacheSpill - | SQLITE_UnsafeInView - | SQLITE_VtabInView + | SQLITE_UnsafeDDL /* The SQLITE_DQS compile-time option determines the default settings ** for SQLITE_DBCONFIG_DQS_DDL and SQLITE_DBCONFIG_DQS_DML. diff --git a/src/resolve.c b/src/resolve.c index ef77d8be5d..c4321e3930 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -891,13 +891,13 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ && !IN_RENAME_OBJECT ){ if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0 - || (pParse->db->flags & SQLITE_UnsafeInView)==0 + || (pParse->db->flags & SQLITE_UnsafeDDL)==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_UNSAFE_IN_VIEW is off + ** SQLITE_DBCONFIG_ENABLE_UNSAFE_DDL is off */ sqlite3ErrorMsg(pParse, "%s() prohibited in triggers and views", pDef->zName); diff --git a/src/shell.c.in b/src/shell.c.in index 25ab36e495..cd478d8d4d 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -7165,6 +7165,7 @@ static int do_meta_command(char *zLine, ShellState *p){ { "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY }, { "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG }, { "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER }, + { "enable_unsafe_ddl", SQLITE_DBCONFIG_ENABLE_UNSAFE_DDL }, { "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW }, { "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER }, { "legacy_alter_table", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE }, @@ -7173,8 +7174,6 @@ static int do_meta_command(char *zLine, ShellState *p){ { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE }, { "reset_database", SQLITE_DBCONFIG_RESET_DATABASE }, { "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP }, - { "unsafe_func_in_view",SQLITE_DBCONFIG_UNSAFE_FUNC_IN_VIEW }, - { "vtab_in_view", SQLITE_DBCONFIG_VTAB_IN_VIEW }, { "writable_schema", SQLITE_DBCONFIG_WRITABLE_SCHEMA }, }; int ii, v; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index dc8bf4a384..a49684ed0d 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2265,31 +2265,19 @@ struct sqlite3_mem_methods { ** compile-time option. **
** -** [[SQLITE_DBCONFIG_UNSAFE_FUNC_IN_VIEW]] -**
SQLITE_DBCONFIG_UNSAFE_FUNC_IN_VIEW -**
The SQLITE_DBCONFIG_UNSAFE_FUNC_IN_VIEW option activates or deactivates -** the ability to use SQL functions that have side-effects inside of -** triggers and views. For legacy compatibility, this setting defaults -** to "on". Applications that are operating on untrusted database files -** are advised to change this setting to "off". When this setting is on, -** only functions that have no side effects are usable inside of views. -** This prevents an attacker from modifying the schema of a database so -** that views and/or triggers with undesirable side-effects are run when -** the application innocently tries to access what it thinks is an ordinary -** table. -**
-** -** [[SQLITE_DBCONFIG_VTAB_IN_VIEW]] -**
SQLITE_DBCONFIG_VTAB_IN_VIEW -**
The SQLITE_DBCONFIG_VTAB_IN_VIEW option activates or deactivates -** the ability to use [virtual tables] inside of triggers and views. -** For legacy compatibility, this setting defaults -** to "on". Applications that are operating on untrusted database files -** are advised to change this setting to "off". Turning this setting off -** prevents an attacker from modifying the schema of a database so -** that views and/or triggers with undesirable side-effects are run when -** the application innocently tries to access what it thinks is an ordinary -** table. +** [[SQLITE_DBCONFIG_INDIRECT_UNSAFE]] +**
SQLITE_DBCONFIG_INDIRECT_UNSAFE +**
The SQLITE_DBCONFIG_INDIRECT_UNSAFE option activates or deactivates +** the ability to use "unsafe" SQL functions and virtual tables in the +** schema of the database. Using an SQL function or virtual table "in the +** schema" means using the rsource in a +** trigger, view, CHECK constraint, INDEX definition, generated column, +** default value, or in any other context that is part of the DDL for the +** database file. "Unsafe" SQL functions are SQL functions that are not +** tagged with [SQLITE_INNOCUOUS]. +**

For legacy compatibility, the SQLITE_DBCONFIG_INDIRECT_UNSAFE setting +** defaults to "on". Applications that are operating on untrusted database +** files are advised to change this setting to "off". **

** ** [[SQLITE_DBCONFIG_LEGACY_FILE_FORMAT]] @@ -2332,9 +2320,8 @@ struct sqlite3_mem_methods { #define SQLITE_DBCONFIG_DQS_DDL 1014 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */ #define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 1016 /* int int* */ -#define SQLITE_DBCONFIG_UNSAFE_FUNC_IN_VIEW 1017 /* int int* */ -#define SQLITE_DBCONFIG_VTAB_IN_VIEW 1018 /* int int* */ -#define SQLITE_DBCONFIG_MAX 1018 /* Largest DBCONFIG */ +#define SQLITE_DBCONFIG_ENABLE_UNSAFE_DDL 1017 /* int int* */ +#define SQLITE_DBCONFIG_MAX 1017 /* Largest DBCONFIG */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes diff --git a/src/sqliteInt.h b/src/sqliteInt.h index e8eafe2b6b..3b807532fd 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1581,10 +1581,10 @@ struct sqlite3 { #define SQLITE_CkptFullFSync 0x00000010 /* Use full fsync for checkpoint */ #define SQLITE_CacheSpill 0x00000020 /* OK to spill pager cache */ #define SQLITE_ShortColNames 0x00000040 /* Show short columns names */ -#define SQLITE_UnsafeInView 0x00000080 /* Allow functions with side-effect - ** in triggers and views */ -#define SQLITE_VtabInView 0x00000100 /* Allow views and triggers to access - ** virtual tables */ +#define SQLITE_UnsafeDDL 0x00000080 /* Allow unsafe functions and vtabs + ** in the schema definition */ +#define SQLITE_NullCallback 0x00000100 /* Invoke the callback once if the */ + /* result set is empty */ #define SQLITE_IgnoreChecks 0x00000200 /* Do not enforce check constraints */ #define SQLITE_ReadUncommit 0x00000400 /* READ UNCOMMITTED in shared-cache */ #define SQLITE_NoCkptOnClose 0x00000800 /* No checkpoint on close()/DETACH */ @@ -1611,8 +1611,6 @@ struct sqlite3 { #define SQLITE_CountRows HI(0x00001) /* Count rows changed by INSERT, */ /* DELETE, or UPDATE and return */ /* the count using a callback. */ -#define SQLITE_NullCallback HI(0000002) /* Invoke the callback once if the */ - /* result set is empty */ /* Flags used only if debugging */ #ifdef SQLITE_DEBUG From 2928a15b3c4c16bb3894bcd809c0626c469bf7ba Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 6 Jan 2020 15:25:41 +0000 Subject: [PATCH 07/22] Refactor names of flags for improved legibility. FossilOrigin-Name: 411e8ec2219bb4181aaf2209fb1e7baf5e8df8b8c8adb82a69b48cf7e8e7e7d4 --- manifest | 24 ++++++++++----------- manifest.uuid | 2 +- src/attach.c | 7 +++--- src/main.c | 3 +-- src/resolve.c | 7 +++--- src/shell.c.in | 2 +- src/sqlite.h.in | 57 ++++++++++++++++++++++++++++++++++++------------- src/sqliteInt.h | 16 ++++++++++---- src/vtab.c | 37 +++++++++++++++++++++----------- 9 files changed, 101 insertions(+), 54 deletions(-) diff --git a/manifest b/manifest index d3b967c6de..30dbc3466c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refactor\sthe\snames\sof\sthe\snew\scontrols\sfor\srestricting\swhat\sactions\sthe\sschema\ncan\stake\sbehind\sthe\sapplication's\sback. -D 2020-01-04T20:58:41.624 +C Refactor\snames\sof\sflags\sfor\simproved\slegibility. +D 2020-01-06T15:25:41.454 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -464,7 +464,7 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c f48a4423c8f198d7f1ae4940f74b606707d05384ac79fb219be8e3323af2a2de F src/analyze.c b3ceec3fc052df8a96ca8a8c858d455dc5029ba681b4be98bb5c5a9162cfa58c -F src/attach.c b30c44333d55a68c0a12920b5b9d40b254cbd3d4509bda77417209eeed8b3d80 +F src/attach.c df0ead9091042c68964856ecc08dba55d5403ad5f3ca865d9d396d71528c511a F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c f70077d40c08b7787bfe934e4d1da8030cb0cc57d46b345fba2294b7d1be23ab F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 @@ -492,7 +492,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 5ba8fd376f539240939ae76b5bc9fa7ad9a0d86e9914ecd11eb7002204138c11 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c d74f5e7bd51f3c9d283442473eb65aef359664efd6513591c03f01881c4ae2da -F src/main.c 372f764daf1fd8f86ea87a2eb285faaed891300682e9fa5a2fd75c3a3e6c5af7 +F src/main.c 1505cc36860dcbfbe62579de97637b0d757282b810ead96095b8ca6be2e13c4b F src/malloc.c eaa4dc9602ce28b077f7de2eb275db2be270c5cc56d7fec5466301bd9b80e2f5 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -526,14 +526,14 @@ F src/pragma.h 5bbfafd74cf085762b64e4e2b00242917951b30468e380bddd8be6c21789aec2 F src/prepare.c 6049beb71385f017af6fc320d2c75a4e50b75e280c54232442b785fbb83df057 F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c d368864894450413a78ab5381eea7f6deb2f1f7b10c7e6ca20cb345e5a7b9281 +F src/resolve.c f35aa580fd29a9213f43bc267f486bb26430352bf78d1ceef4a4c9735b4c9d24 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 64bf450dc0f2b37be8d2be6ff7d25a70de37ef6fb64527c68f767fe9fe47bc55 -F src/shell.c.in 0fcf24b526e35eb2e02212e2504b695f79992ccc69b8be0f841276abea037008 -F src/sqlite.h.in 600fd6093a03112831e2658daac299d2a803ffcd3d7f4f6b091a447f79b4d6c2 +F src/shell.c.in 6893d5b8d598aa59457c1490b8c9970c9b8d19d5f37951b3f831a0cd5f45a57c +F src/sqlite.h.in b2dc8fc4db9496b3b9c06d68026d83976e9b76afc8b53d16aadb68f3e5cc3ca0 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 72af51aa4e912e14cd495fb6e7fac65f0940db80ed950d90911aff292cc47ce2 -F src/sqliteInt.h 002066fa9a7ea1dacdca6f395968d4eed0fcf2978ac1f7528c61cb6e65f52e6e +F src/sqliteInt.h badbde0a53c2fb8311d7cd7f177a7bef70002658daa61d3effcaef365adb5f4b F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -609,7 +609,7 @@ F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b F src/vdbemem.c 05668cc1b44845736784f1ce9da46403dbf202c7c6d1a02205285cfc30e78f0d F src/vdbesort.c a3be032cc3fee0e3af31773af4a7a6f931b7230a34f53282ccf1d9a2a72343be F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0 -F src/vtab.c a2fead3e97fca54fcf3f3db784e17c9ee2d39a0c5ad323e9d514855106300a86 +F src/vtab.c 7b704a90515a239c6cdba6a66b1bb3a385e62326cceb5ecb05ec7a091d6b8515 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 15a2845769f51ba132f9cf0b2c7a6887a91fc8437892dbcce9fcdc68b66d60a1 F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a @@ -1853,7 +1853,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 7a8d7ca726666f4384925f959df0d58f7622229e06f1b5e643a3caccd539bb6e -R f9fb8a85043cff3871f686f554fff1c5 +P 65d7d39a858c51ffd781f5a6335e029895e597aeb1e1ccdadea8ce79c8ad412f +R fb33b89473d770b763bebc42b1cd394c U drh -Z 2b34921532ba1ddcc3f837ba912e08b2 +Z 6124e43a4879e0631853de887c7788db diff --git a/manifest.uuid b/manifest.uuid index 3d1543ad1f..46808f3518 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -65d7d39a858c51ffd781f5a6335e029895e597aeb1e1ccdadea8ce79c8ad412f \ No newline at end of file +411e8ec2219bb4181aaf2209fb1e7baf5e8df8b8c8adb82a69b48cf7e8e7e7d4 \ No newline at end of file diff --git a/src/attach.c b/src/attach.c index ca9af483c2..fdd71854ed 100644 --- a/src/attach.c +++ b/src/attach.c @@ -477,7 +477,7 @@ void sqlite3FixInit( pFix->pSchema = db->aDb[iDb].pSchema; pFix->zType = zType; pFix->pName = pName; - pFix->bVarOnly = (iDb==1); + pFix->bTemp = (iDb==1); } /* @@ -505,7 +505,7 @@ int sqlite3FixSrcList( if( NEVER(pList==0) ) return 0; zDb = pFix->zDb; for(i=0, pItem=pList->a; inSrc; i++, pItem++){ - if( pFix->bVarOnly==0 ){ + if( pFix->bTemp==0 ){ if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){ sqlite3ErrorMsg(pFix->pParse, "%s %T cannot reference objects in database %s", @@ -515,6 +515,7 @@ int sqlite3FixSrcList( sqlite3DbFree(pFix->pParse->db, pItem->zDatabase); pItem->zDatabase = 0; pItem->pSchema = pFix->pSchema; + pItem->fg.fromDDL = 1; } #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1; @@ -570,7 +571,7 @@ int sqlite3FixExpr( Expr *pExpr /* The expression to be fixed to one database */ ){ while( pExpr ){ - ExprSetProperty(pExpr, EP_Indirect); + if( !pFix->bTemp ) ExprSetProperty(pExpr, EP_FromDDL); if( pExpr->op==TK_VARIABLE ){ if( pFix->pParse->db->init.busy ){ pExpr->op = TK_NULL; diff --git a/src/main.c b/src/main.c index b96d99038f..9349daca26 100644 --- a/src/main.c +++ b/src/main.c @@ -887,7 +887,7 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){ { SQLITE_DBCONFIG_DQS_DDL, SQLITE_DqsDDL }, { SQLITE_DBCONFIG_DQS_DML, SQLITE_DqsDML }, { SQLITE_DBCONFIG_LEGACY_FILE_FORMAT, SQLITE_LegacyFileFmt }, - { SQLITE_DBCONFIG_ENABLE_UNSAFE_DDL, SQLITE_UnsafeDDL }, + { SQLITE_DBCONFIG_UNTRUSTED_SCHEMA, SQLITE_UnsafeSchema }, }; unsigned int i; rc = SQLITE_ERROR; /* IMP: R-42790-23372 */ @@ -3127,7 +3127,6 @@ static int openDatabase( | SQLITE_EnableTrigger | SQLITE_EnableView | SQLITE_CacheSpill - | SQLITE_UnsafeDDL /* The SQLITE_DQS compile-time option determines the default settings ** for SQLITE_DBCONFIG_DQS_DDL and SQLITE_DBCONFIG_DQS_DML. diff --git a/src/resolve.c b/src/resolve.c index c4321e3930..8ccd0ab7d0 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -887,17 +887,18 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ pDef = 0; }else if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0 - && ExprHasProperty(pExpr, EP_Indirect) + && ExprHasProperty(pExpr, EP_FromDDL) && !IN_RENAME_OBJECT ){ if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0 - || (pParse->db->flags & SQLITE_UnsafeDDL)==0 + || (pParse->db->flags & SQLITE_UnsafeSchema)!=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_ENABLE_UNSAFE_DDL is off + ** SQLITE_DBCONFIG_UNTRUSTED_SCHEMA is off (meaning + ** that the schema is fully trustworthy). */ sqlite3ErrorMsg(pParse, "%s() prohibited in triggers and views", pDef->zName); diff --git a/src/shell.c.in b/src/shell.c.in index cd478d8d4d..5cc4c3b10b 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -7165,7 +7165,6 @@ static int do_meta_command(char *zLine, ShellState *p){ { "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY }, { "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG }, { "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER }, - { "enable_unsafe_ddl", SQLITE_DBCONFIG_ENABLE_UNSAFE_DDL }, { "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW }, { "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER }, { "legacy_alter_table", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE }, @@ -7174,6 +7173,7 @@ static int do_meta_command(char *zLine, ShellState *p){ { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE }, { "reset_database", SQLITE_DBCONFIG_RESET_DATABASE }, { "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP }, + { "untrusted_schema", SQLITE_DBCONFIG_UNTRUSTED_SCHEMA }, { "writable_schema", SQLITE_DBCONFIG_WRITABLE_SCHEMA }, }; int ii, v; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index a49684ed0d..5ee3b5dcf0 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2265,19 +2265,24 @@ struct sqlite3_mem_methods { ** compile-time option. ** ** -** [[SQLITE_DBCONFIG_INDIRECT_UNSAFE]] -**
SQLITE_DBCONFIG_INDIRECT_UNSAFE -**
The SQLITE_DBCONFIG_INDIRECT_UNSAFE option activates or deactivates -** the ability to use "unsafe" SQL functions and virtual tables in the -** schema of the database. Using an SQL function or virtual table "in the -** schema" means using the rsource in a -** trigger, view, CHECK constraint, INDEX definition, generated column, -** default value, or in any other context that is part of the DDL for the -** database file. "Unsafe" SQL functions are SQL functions that are not -** tagged with [SQLITE_INNOCUOUS]. -**

For legacy compatibility, the SQLITE_DBCONFIG_INDIRECT_UNSAFE setting -** defaults to "on". Applications that are operating on untrusted database -** files are advised to change this setting to "off". +** [[SQLITE_DBCONFIG_UNTRUSTED_SCHEMA]] +**

SQLITE_DBCONFIG_UNTRUSTED_SCHEMA +**
The SQLITE_DBCONFIG_UNTRUSTED_SCHEMA option tells the SQLite +** database connection that the schemas of the database files it reads +** might contain malicious corruption intended to harm the application. +** When the SQLITE_DBCONFIG_UNTRUSTED_SCHEMA option is enabled, SQLite +** takes additional defensive steps including, but not limited to, the +** following: +**
    +**
  • Prohibit the use of SQL functions inside triggers, views, +** CHECK constraints, DEFAULT VALUEs, index definitions, and/or +** generated columns unless those functions are tagged +** with [SQLITE_INNOCUOUS]. +**
  • Pohibit the use of virtual tables inside of triggers and/or views +** unless those virtual tables are tagged with [SQLITE_VTAB_INNOCUOUS]. +**
+** This setting defaults to "off" for legacy compatibility, however +** all applications are advised to turn it on if possible. **
** ** [[SQLITE_DBCONFIG_LEGACY_FILE_FORMAT]] @@ -2320,7 +2325,7 @@ struct sqlite3_mem_methods { #define SQLITE_DBCONFIG_DQS_DDL 1014 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */ #define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 1016 /* int int* */ -#define SQLITE_DBCONFIG_ENABLE_UNSAFE_DDL 1017 /* int int* */ +#define SQLITE_DBCONFIG_UNTRUSTED_SCHEMA 1017 /* int int* */ #define SQLITE_DBCONFIG_MAX 1017 /* Largest DBCONFIG */ /* @@ -8899,7 +8904,7 @@ int sqlite3_vtab_config(sqlite3*, int op, ...); ** **
** [[SQLITE_VTAB_CONSTRAINT_SUPPORT]] -**
SQLITE_VTAB_CONSTRAINT_SUPPORT +**
SQLITE_VTAB_CONSTRAINT_SUPPORT
**
Calls of the form ** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported, ** where X is an integer. If X is zero, then the [virtual table] whose @@ -8928,9 +8933,31 @@ int sqlite3_vtab_config(sqlite3*, int op, ...); ** return SQLITE_OK. Or, if this is not possible, it may return ** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT ** constraint handling. +**
+** +** [[SQLITE_VTAB_INNOCUOUS]]
SQLITE_VTAB_INNOCUOUS
+**
Calls of the form +** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the +** the [xConnect] or [xCreate] methods of a [virtual table] implmentation +** identify that virtual table as being safe to use from within triggers +** and views. Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the +** virtual table can do no serious harm even if it is controlled by a +** malicious hacker. Developers should avoid setting the SQLITE_VTAB_INNOCUOUS +** flag unless absolutely necessary. +**
+** +** [[SQLITE_VTAB_DIRECTONLY]]
SQLITE_VTAB_DIRECTONLY
+**
Calls of the form +** [sqlite3_vtab_config](db,SQLITE_VTAB_DIRECTONLY) from within the +** the [xConnect] or [xCreate] methods of a [virtual table] implmentation +** prohibits that virtual table from being used from within triggers and +** views. +**
**
*/ #define SQLITE_VTAB_CONSTRAINT_SUPPORT 1 +#define SQLITE_VTAB_INNOCUOUS 2 +#define SQLITE_VTAB_DIRECTONLY 3 /* ** CAPI3REF: Determine The Virtual Table Conflict Policy diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 3b807532fd..1a8527fc29 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1581,8 +1581,8 @@ struct sqlite3 { #define SQLITE_CkptFullFSync 0x00000010 /* Use full fsync for checkpoint */ #define SQLITE_CacheSpill 0x00000020 /* OK to spill pager cache */ #define SQLITE_ShortColNames 0x00000040 /* Show short columns names */ -#define SQLITE_UnsafeDDL 0x00000080 /* Allow unsafe functions and vtabs - ** in the schema definition */ +#define SQLITE_UnsafeSchema 0x00000080 /* Disallow unsafe functions and + ** vtabs in the schema definition */ #define SQLITE_NullCallback 0x00000100 /* Invoke the callback once if the */ /* result set is empty */ #define SQLITE_IgnoreChecks 0x00000200 /* Do not enforce check constraints */ @@ -2067,10 +2067,17 @@ struct VTable { sqlite3_vtab *pVtab; /* Pointer to vtab instance */ int nRef; /* Number of pointers to this structure */ u8 bConstraint; /* True if constraints are supported */ + u8 eVtabRisk; /* Riskiness of allowing hacker access */ int iSavepoint; /* Depth of the SAVEPOINT stack */ VTable *pNext; /* Next in linked list (see above) */ }; +/* Allowed values for VTable.eVtabRisk +*/ +#define SQLITE_VTABRISK_Low 0 +#define SQLITE_VTABRISK_Normal 1 +#define SQLITE_VTABRISK_High 2 + /* ** The schema for each SQL table and view is represented in memory ** by an instance of the following structure. @@ -2671,7 +2678,7 @@ struct Expr { #define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */ #define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */ #define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */ -#define EP_Indirect 0x40000000 /* Contained within a TRIGGER or a VIEW */ +#define EP_FromDDL 0x40000000 /* Originates from sqlite_master */ /* ** The EP_Propagate mask is a set of properties that automatically propagate @@ -2840,6 +2847,7 @@ struct SrcList { unsigned isCorrelated :1; /* True if sub-query is correlated */ unsigned viaCoroutine :1; /* Implemented as a co-routine */ unsigned isRecursive :1; /* True for recursive reference in WITH */ + unsigned fromDDL :1; /* Comes from sqlite_master */ } fg; int iCursor; /* The VDBE cursor number used to access this table */ Expr *pOn; /* The ON clause of a join */ @@ -3515,7 +3523,7 @@ typedef struct DbFixer DbFixer; struct DbFixer { Parse *pParse; /* The parsing context. Error messages written here */ Schema *pSchema; /* Fix items to this schema */ - int bVarOnly; /* Check for variable references only */ + u8 bTemp; /* True for TEMP schema entries */ const char *zDb; /* Make sure all objects are contained in this database */ const char *zType; /* Type of the container - used for error messages */ const Token *pName; /* Name of the container - used for error messages */ diff --git a/src/vtab.c b/src/vtab.c index 082b56edb0..013511cfb4 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -587,6 +587,7 @@ static int vtabCallConstructor( } pVTable->db = db; pVTable->pMod = pMod; + pVTable->eVtabRisk = SQLITE_VTABRISK_Normal; iDb = sqlite3SchemaToIndex(db, pTab->pSchema); pTab->azModuleArg[1] = db->aDb[iDb].zDbSName; @@ -1276,28 +1277,38 @@ int sqlite3_vtab_on_conflict(sqlite3 *db){ int sqlite3_vtab_config(sqlite3 *db, int op, ...){ va_list ap; int rc = SQLITE_OK; + VtabCtx *p; #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif sqlite3_mutex_enter(db->mutex); - va_start(ap, op); - switch( op ){ - case SQLITE_VTAB_CONSTRAINT_SUPPORT: { - VtabCtx *p = db->pVtabCtx; - if( !p ){ - rc = SQLITE_MISUSE_BKPT; - }else{ - assert( p->pTab==0 || IsVirtual(p->pTab) ); + p = db->pVtabCtx; + if( !p ){ + rc = SQLITE_MISUSE_BKPT; + }else{ + assert( p->pTab==0 || IsVirtual(p->pTab) ); + va_start(ap, op); + switch( op ){ + case SQLITE_VTAB_CONSTRAINT_SUPPORT: { p->pVTable->bConstraint = (u8)va_arg(ap, int); + break; + } + case SQLITE_VTAB_INNOCUOUS: { + p->pVTable->eVtabRisk = SQLITE_VTABRISK_Low; + break; + } + case SQLITE_VTAB_DIRECTONLY: { + p->pVTable->eVtabRisk = SQLITE_VTABRISK_High; + break; + } + default: { + rc = SQLITE_MISUSE_BKPT; + break; } - break; } - default: - rc = SQLITE_MISUSE_BKPT; - break; + va_end(ap); } - va_end(ap); if( rc!=SQLITE_OK ) sqlite3Error(db, rc); sqlite3_mutex_leave(db->mutex); From b77da374ab6dfeaac5def640da91f219da7fa5c0 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 7 Jan 2020 16:09:11 +0000 Subject: [PATCH 08/22] Invert the UNTRUSTED_SCHEMA setting to be TRUSTED_SCHEMA. FossilOrigin-Name: f5fcf1fbc6473f8e91315b14d67745f2748010641b7463d1f4ca51e6fdf97462 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/main.c | 6 ++++-- src/resolve.c | 2 +- src/shell.c.in | 2 +- src/sqlite.h.in | 21 ++++++++++----------- src/sqliteInt.h | 2 +- 7 files changed, 28 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index 44bc3b7078..30adf0d294 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\srecent\sfixes\sfrom\strunk. -D 2020-01-07T15:44:22.828 +C Invert\sthe\sUNTRUSTED_SCHEMA\ssetting\sto\sbe\sTRUSTED_SCHEMA. +D 2020-01-07T16:09:11.843 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -492,7 +492,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 5ba8fd376f539240939ae76b5bc9fa7ad9a0d86e9914ecd11eb7002204138c11 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c d74f5e7bd51f3c9d283442473eb65aef359664efd6513591c03f01881c4ae2da -F src/main.c 1505cc36860dcbfbe62579de97637b0d757282b810ead96095b8ca6be2e13c4b +F src/main.c 6ba00f15f0e7d36a12136ac390a403de4c4b47b76733d1cad60c2b23b4a2cf1d F src/malloc.c eaa4dc9602ce28b077f7de2eb275db2be270c5cc56d7fec5466301bd9b80e2f5 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -526,14 +526,14 @@ F src/pragma.h 5bbfafd74cf085762b64e4e2b00242917951b30468e380bddd8be6c21789aec2 F src/prepare.c 6049beb71385f017af6fc320d2c75a4e50b75e280c54232442b785fbb83df057 F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c f35aa580fd29a9213f43bc267f486bb26430352bf78d1ceef4a4c9735b4c9d24 +F src/resolve.c 894397f372b5c23fb68e0c534d3682f45285f228bb335d713344a7ed37f0ba45 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 80d1aac7017824b803c8e6bdb75f699e11aef22e02d29d206a523d8a3dcf2a13 -F src/shell.c.in 6893d5b8d598aa59457c1490b8c9970c9b8d19d5f37951b3f831a0cd5f45a57c -F src/sqlite.h.in b2dc8fc4db9496b3b9c06d68026d83976e9b76afc8b53d16aadb68f3e5cc3ca0 +F src/shell.c.in 43d3cfbee97d78ca5782dc53e4c1e22d3cc15c91beff20889dc60551f47eab9f +F src/sqlite.h.in 972e3473e096cd322abe136caa5cc443c94a93a984030aa07824f0410667d04b F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 72af51aa4e912e14cd495fb6e7fac65f0940db80ed950d90911aff292cc47ce2 -F src/sqliteInt.h badbde0a53c2fb8311d7cd7f177a7bef70002658daa61d3effcaef365adb5f4b +F src/sqliteInt.h 8c1fcdad7418c87cd482d2868610ed299e0201091e247598495e92e9c5d8e884 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1853,7 +1853,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 9c50f6c28a4cadb2c33954c066a8e94f8aaf4c31b6c0309db35efc472cb0bcaa 03c1d75ddc063469fc856114595bd12d21759fe0979ce1ba1cf52e48e6b0d4a1 -R 3f9c42e2a1153621e11e54b50f905166 +P 5dfa33a09e608d26549e46c58a5563754688af68fa99415f9a548e91f81aca7c +R a21ed46e9ca0e50811978a859d8bcb1e U drh -Z ce4d5892a82ed81a290c1004012f18cc +Z 4afc7b0d302d12e9a276c855c439b690 diff --git a/manifest.uuid b/manifest.uuid index ebc1418a71..d1429eed65 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5dfa33a09e608d26549e46c58a5563754688af68fa99415f9a548e91f81aca7c \ No newline at end of file +f5fcf1fbc6473f8e91315b14d67745f2748010641b7463d1f4ca51e6fdf97462 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 9349daca26..c0f53916a6 100644 --- a/src/main.c +++ b/src/main.c @@ -887,7 +887,7 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){ { SQLITE_DBCONFIG_DQS_DDL, SQLITE_DqsDDL }, { SQLITE_DBCONFIG_DQS_DML, SQLITE_DqsDML }, { SQLITE_DBCONFIG_LEGACY_FILE_FORMAT, SQLITE_LegacyFileFmt }, - { SQLITE_DBCONFIG_UNTRUSTED_SCHEMA, SQLITE_UnsafeSchema }, + { SQLITE_DBCONFIG_TRUSTED_SCHEMA, SQLITE_TrustedSchema }, }; unsigned int i; rc = SQLITE_ERROR; /* IMP: R-42790-23372 */ @@ -3127,7 +3127,9 @@ static int openDatabase( | SQLITE_EnableTrigger | SQLITE_EnableView | SQLITE_CacheSpill - +#if !defined(SQLITE_TRUSTED_SCHEMA) || SQLITE_TRUSTED_SCHEMA+0!=0 + | SQLITE_TrustedSchema +#endif /* The SQLITE_DQS compile-time option determines the default settings ** for SQLITE_DBCONFIG_DQS_DDL and SQLITE_DBCONFIG_DQS_DML. ** diff --git a/src/resolve.c b/src/resolve.c index 8ccd0ab7d0..929c8743f5 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -891,7 +891,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ && !IN_RENAME_OBJECT ){ if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0 - || (pParse->db->flags & SQLITE_UnsafeSchema)!=0 + || (pParse->db->flags & SQLITE_TrustedSchema)==0 ){ /* Functions prohibited in triggers and views if: ** (1) tagged with SQLITE_DIRECTONLY diff --git a/src/shell.c.in b/src/shell.c.in index 5cc4c3b10b..118205532c 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -7173,7 +7173,7 @@ static int do_meta_command(char *zLine, ShellState *p){ { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE }, { "reset_database", SQLITE_DBCONFIG_RESET_DATABASE }, { "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP }, - { "untrusted_schema", SQLITE_DBCONFIG_UNTRUSTED_SCHEMA }, + { "trusted_schema", SQLITE_DBCONFIG_TRUSTED_SCHEMA }, { "writable_schema", SQLITE_DBCONFIG_WRITABLE_SCHEMA }, }; int ii, v; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 5ee3b5dcf0..cb572a3294 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2265,14 +2265,13 @@ struct sqlite3_mem_methods { ** compile-time option. ** ** -** [[SQLITE_DBCONFIG_UNTRUSTED_SCHEMA]] -**
SQLITE_DBCONFIG_UNTRUSTED_SCHEMA -**
The SQLITE_DBCONFIG_UNTRUSTED_SCHEMA option tells the SQLite -** database connection that the schemas of the database files it reads -** might contain malicious corruption intended to harm the application. -** When the SQLITE_DBCONFIG_UNTRUSTED_SCHEMA option is enabled, SQLite -** takes additional defensive steps including, but not limited to, the -** following: +** [[SQLITE_DBCONFIG_TRUSTED_SCHEMA]] +**
SQLITE_DBCONFIG_TRUSTED_SCHEMA +**
The SQLITE_DBCONFIG_TRUSTED_SCHEMA option tells the SQLite to +** assume that database schemas are untainted by malicious content. +** When the SQLITE_DBCONFIG_TRUSTED_SCHEMA option is disabled, SQLite +** takes additional defensive steps to protect the application from harm +** including, but not limited to, the following: **
    **
  • Prohibit the use of SQL functions inside triggers, views, ** CHECK constraints, DEFAULT VALUEs, index definitions, and/or @@ -2281,8 +2280,8 @@ struct sqlite3_mem_methods { **
  • Pohibit the use of virtual tables inside of triggers and/or views ** unless those virtual tables are tagged with [SQLITE_VTAB_INNOCUOUS]. **
-** This setting defaults to "off" for legacy compatibility, however -** all applications are advised to turn it on if possible. +** This setting defaults to "on" for legacy compatibility, however +** all applications are advised to turn it off if possible. **
** ** [[SQLITE_DBCONFIG_LEGACY_FILE_FORMAT]] @@ -2325,7 +2324,7 @@ struct sqlite3_mem_methods { #define SQLITE_DBCONFIG_DQS_DDL 1014 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */ #define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 1016 /* int int* */ -#define SQLITE_DBCONFIG_UNTRUSTED_SCHEMA 1017 /* int int* */ +#define SQLITE_DBCONFIG_TRUSTED_SCHEMA 1017 /* int int* */ #define SQLITE_DBCONFIG_MAX 1017 /* Largest DBCONFIG */ /* diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 1a8527fc29..455403637a 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1581,7 +1581,7 @@ struct sqlite3 { #define SQLITE_CkptFullFSync 0x00000010 /* Use full fsync for checkpoint */ #define SQLITE_CacheSpill 0x00000020 /* OK to spill pager cache */ #define SQLITE_ShortColNames 0x00000040 /* Show short columns names */ -#define SQLITE_UnsafeSchema 0x00000080 /* Disallow unsafe functions and +#define SQLITE_TrustedSchema 0x00000080 /* Allow unsafe functions and ** vtabs in the schema definition */ #define SQLITE_NullCallback 0x00000100 /* Invoke the callback once if the */ /* result set is empty */ From 3f68142b820d10f3b0b4b9df65e789f4058eb67d Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 7 Jan 2020 18:10:56 +0000 Subject: [PATCH 09/22] Enforce SQLITE_VTABRISK restrictions. FossilOrigin-Name: 3d87ff312e617a26846d482b423163cad9c222513f33e128f0fe348dda27c7c9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 10 +++++++++- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 30adf0d294..168249e8ee 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Invert\sthe\sUNTRUSTED_SCHEMA\ssetting\sto\sbe\sTRUSTED_SCHEMA. -D 2020-01-07T16:09:11.843 +C Enforce\sSQLITE_VTABRISK\srestrictions. +D 2020-01-07T18:10:56.084 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -528,7 +528,7 @@ F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 894397f372b5c23fb68e0c534d3682f45285f228bb335d713344a7ed37f0ba45 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 -F src/select.c 80d1aac7017824b803c8e6bdb75f699e11aef22e02d29d206a523d8a3dcf2a13 +F src/select.c a2be95ccf2f9f98ce3a0b5a0f15200908de4e156802098fedff4f780f04c8b6d F src/shell.c.in 43d3cfbee97d78ca5782dc53e4c1e22d3cc15c91beff20889dc60551f47eab9f F src/sqlite.h.in 972e3473e096cd322abe136caa5cc443c94a93a984030aa07824f0410667d04b F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1853,7 +1853,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 5dfa33a09e608d26549e46c58a5563754688af68fa99415f9a548e91f81aca7c -R a21ed46e9ca0e50811978a859d8bcb1e +P f5fcf1fbc6473f8e91315b14d67745f2748010641b7463d1f4ca51e6fdf97462 +R 46209d5a1d64e52999e7462bf5830187 U drh -Z 4afc7b0d302d12e9a276c855c439b690 +Z 6fc5982c5d29c856ec36714597408f55 diff --git a/manifest.uuid b/manifest.uuid index d1429eed65..1471672163 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f5fcf1fbc6473f8e91315b14d67745f2748010641b7463d1f4ca51e6fdf97462 \ No newline at end of file +3d87ff312e617a26846d482b423163cad9c222513f33e128f0fe348dda27c7c9 \ No newline at end of file diff --git a/src/select.c b/src/select.c index d45735b0ed..d6cd7c25ec 100644 --- a/src/select.c +++ b/src/select.c @@ -4964,7 +4964,15 @@ static int selectExpander(Walker *pWalker, Select *p){ assert( pFrom->pSelect==0 ); if( pTab->pSelect && (db->flags & SQLITE_EnableView)==0 ){ sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited", - pTab->zName); + pTab->zName); + } + if( IsVirtual(pTab) + && pFrom->fg.fromDDL + && ALWAYS(pTab->pVTable!=0) + && pTab->pVTable->eVtabRisk > ((db->flags & SQLITE_TrustedSchema)!=0) + ){ + sqlite3ErrorMsg(pParse, "cannot access \"%s\" from within a trigger" + " or view", pTab->zName); } pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0); nCol = pTab->nCol; From 2b1c2aad9f45a21e04d3420152779386b6cf7d33 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 7 Jan 2020 19:45:40 +0000 Subject: [PATCH 10/22] Create the "trusted_schema" pragma. Add sqlite3_vtab_config() calls to set the risk rank for many virtual tables. FossilOrigin-Name: 4c21373c21c9b17b222ae65297a039a035e6ec6b505c00c33704e3c03f94f834 --- ext/misc/amatch.c | 1 + ext/misc/completion.c | 1 + ext/misc/compress.c | 10 ++++--- ext/misc/csv.c | 9 ++++++ ext/misc/eval.c | 6 ++-- ext/misc/fileio.c | 7 +++-- ext/misc/fossildelta.c | 8 +++-- ext/misc/fuzzer.c | 2 ++ ext/misc/ieee754.c | 6 ++-- ext/misc/json1.c | 1 + ext/misc/nextchar.c | 9 ++++-- ext/misc/percentile.c | 3 +- ext/misc/prefixes.c | 1 + ext/misc/regexp.c | 4 +-- ext/misc/rot13.c | 2 +- ext/misc/series.c | 1 + ext/misc/sha1.c | 5 ++-- ext/misc/shathree.c | 20 ++++++++----- ext/misc/spellfix.c | 1 + ext/misc/sqlar.c | 6 ++-- ext/misc/totype.c | 4 +-- ext/misc/uuid.c | 12 ++++---- ext/misc/wholenumber.c | 1 + ext/misc/zipfile.c | 1 + manifest | 68 +++++++++++++++++++++--------------------- manifest.uuid | 2 +- src/dbpage.c | 1 + src/dbstat.c | 1 + src/pragma.c | 2 +- src/pragma.h | 9 +++++- tool/mkpragmatab.tcl | 5 ++++ 31 files changed, 133 insertions(+), 76 deletions(-) diff --git a/ext/misc/amatch.c b/ext/misc/amatch.c index cbc068bafb..bafa43283a 100644 --- a/ext/misc/amatch.c +++ b/ext/misc/amatch.c @@ -900,6 +900,7 @@ static int amatchConnect( rc = amatchLoadRules(db, pNew, pzErr); } if( rc==SQLITE_OK ){ + sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); rc = sqlite3_declare_vtab(db, "CREATE TABLE x(word,distance,language," "command HIDDEN,nword HIDDEN)" diff --git a/ext/misc/completion.c b/ext/misc/completion.c index 72ad23df93..b624b6d476 100644 --- a/ext/misc/completion.c +++ b/ext/misc/completion.c @@ -118,6 +118,7 @@ static int completionConnect( #define COMPLETION_COLUMN_WHOLELINE 2 /* Entire line seen so far */ #define COMPLETION_COLUMN_PHASE 3 /* ePhase - used for debugging only */ + sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); rc = sqlite3_declare_vtab(db, "CREATE TABLE x(" " candidate TEXT," diff --git a/ext/misc/compress.c b/ext/misc/compress.c index 6e7d8b6148..ab9f5de69c 100644 --- a/ext/misc/compress.c +++ b/ext/misc/compress.c @@ -119,11 +119,13 @@ int sqlite3_compress_init( int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Unused parameter */ - rc = sqlite3_create_function(db, "compress", 1, SQLITE_UTF8, 0, - compressFunc, 0, 0); + rc = sqlite3_create_function(db, "compress", 1, + SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, + 0, compressFunc, 0, 0); if( rc==SQLITE_OK ){ - rc = sqlite3_create_function(db, "uncompress", 1, SQLITE_UTF8, 0, - uncompressFunc, 0, 0); + rc = sqlite3_create_function(db, "uncompress", 1, + SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, + 0, uncompressFunc, 0, 0); } return rc; } diff --git a/ext/misc/csv.c b/ext/misc/csv.c index 09e970ee79..71e3828c77 100644 --- a/ext/misc/csv.c +++ b/ext/misc/csv.c @@ -632,6 +632,15 @@ static int csvtabConnect( for(i=0; izTableName==0 ){ rc = SQLITE_NOMEM; }else{ + sqlite3_vtab_config(db, SQLITE_INNOCUOUS); rc = sqlite3_declare_vtab(db, "CREATE TABLE x(word,rank,distance,langid, " "score, matchlen, phonehash HIDDEN, " diff --git a/ext/misc/sqlar.c b/ext/misc/sqlar.c index e812d70c99..8b90f9d1d8 100644 --- a/ext/misc/sqlar.c +++ b/ext/misc/sqlar.c @@ -111,10 +111,12 @@ int sqlite3_sqlar_init( int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Unused parameter */ - rc = sqlite3_create_function(db, "sqlar_compress", 1, SQLITE_UTF8, 0, + rc = sqlite3_create_function(db, "sqlar_compress", 1, + SQLITE_UTF8|SQLITE_INNOCUOUS, 0, sqlarCompressFunc, 0, 0); if( rc==SQLITE_OK ){ - rc = sqlite3_create_function(db, "sqlar_uncompress", 2, SQLITE_UTF8, 0, + rc = sqlite3_create_function(db, "sqlar_uncompress", 2, + SQLITE_UTF8|SQLITE_INNOCUOUS, 0, sqlarUncompressFunc, 0, 0); } return rc; diff --git a/ext/misc/totype.c b/ext/misc/totype.c index c9655c3dbf..50d7f05d90 100644 --- a/ext/misc/totype.c +++ b/ext/misc/totype.c @@ -503,11 +503,11 @@ int sqlite3_totype_init( SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Unused parameter */ rc = sqlite3_create_function(db, "tointeger", 1, - SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0, + SQLITE_UTF8 | SQLITE_DETERMINISTIC | SQLITE_INNOCUOUS, 0, tointegerFunc, 0, 0); if( rc==SQLITE_OK ){ rc = sqlite3_create_function(db, "toreal", 1, - SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0, + SQLITE_UTF8 | SQLITE_DETERMINISTIC | SQLITE_INNOCUOUS, 0, torealFunc, 0, 0); } return rc; diff --git a/ext/misc/uuid.c b/ext/misc/uuid.c index cb2878b203..5b5b8085ad 100644 --- a/ext/misc/uuid.c +++ b/ext/misc/uuid.c @@ -217,15 +217,17 @@ int sqlite3_uuid_init( int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Unused parameter */ - rc = sqlite3_create_function(db, "uuid", 0, SQLITE_UTF8, 0, + rc = sqlite3_create_function(db, "uuid", 0, SQLITE_UTF8|SQLITE_INNOCUOUS, 0, sqlite3UuidFunc, 0, 0); if( rc==SQLITE_OK ){ - rc = sqlite3_create_function(db, "uuid_str", 1, SQLITE_UTF8, 0, - sqlite3UuidStrFunc, 0, 0); + rc = sqlite3_create_function(db, "uuid_str", 1, + SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, + 0, sqlite3UuidStrFunc, 0, 0); } if( rc==SQLITE_OK ){ - rc = sqlite3_create_function(db, "uuid_blob", 1, SQLITE_UTF8, 0, - sqlite3UuidBlobFunc, 0, 0); + rc = sqlite3_create_function(db, "uuid_blob", 1, + SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, + 0, sqlite3UuidBlobFunc, 0, 0); } return rc; } diff --git a/ext/misc/wholenumber.c b/ext/misc/wholenumber.c index 63369c6ac4..5643f9cf7e 100644 --- a/ext/misc/wholenumber.c +++ b/ext/misc/wholenumber.c @@ -50,6 +50,7 @@ static int wholenumberConnect( pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); if( pNew==0 ) return SQLITE_NOMEM; sqlite3_declare_vtab(db, "CREATE TABLE x(value)"); + sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); memset(pNew, 0, sizeof(*pNew)); return SQLITE_OK; } diff --git a/ext/misc/zipfile.c b/ext/misc/zipfile.c index ac56ac2e55..82e9ce06e9 100644 --- a/ext/misc/zipfile.c +++ b/ext/misc/zipfile.c @@ -369,6 +369,7 @@ static int zipfileConnect( zipfileDequote(pNew->zFile); } } + sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY); *ppVtab = (sqlite3_vtab*)pNew; return rc; } diff --git a/manifest b/manifest index 168249e8ee..651f48782c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enforce\sSQLITE_VTABRISK\srestrictions. -D 2020-01-07T18:10:56.084 +C Create\sthe\s"trusted_schema"\spragma.\s\sAdd\ssqlite3_vtab_config()\scalls\sto\sset\nthe\srisk\srank\sfor\smany\svirtual\stables. +D 2020-01-07T19:45:40.750 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -278,54 +278,54 @@ F ext/lsm1/test/lsm1_common.tcl 5ed4bab07c93be2e4f300ebe46007ecf4b3e20bc5fbe1ded F ext/lsm1/test/lsm1_simple.test a04d08e8661ae6fc53786c67f0bd102c6692f003e859dde03ed9ac3f12e066e5 F ext/lsm1/tool/mklsm1c.tcl f31561bbee5349f0a554d1ad7236ac1991fc09176626f529f6078e07335398b0 F ext/misc/README.md d6dd0fe1d8af77040216798a6a2b0c46c73054d2f0ea544fbbcdccf6f238c240 -F ext/misc/amatch.c 50a9ef2d38dabfa371f8c1904097d493271e63d58ccb0e9b79a4fa4a94e66660 +F ext/misc/amatch.c e3ad5532799cee9a97647f483f67f43b38796b84b5a8c60594fe782a4338f358 F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb F ext/misc/appendvfs.c 3777f22ec1057dc4e5fd89f2fbddcc7a29fbeef1ad038c736c54411bb1967af7 F ext/misc/blobio.c a867c4c4617f6ec223a307ebfe0eabb45e0992f74dd47722b96f3e631c0edb2a F ext/misc/btreeinfo.c 4f0ebf278f46e68e6306c667917766cebc5550fd35d5de17847988e22892d4d2 F ext/misc/carray.c 91e9a7f512fda934894bed30464552fffa7d3073b5be04189ae0bd0c59f26bfd F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c85c243 -F ext/misc/completion.c cec672d40604075bb341a7f11ac48393efdcd90a979269b8fe7977ea62d0547f -F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189 -F ext/misc/csv.c 7f047aeb68f5802e7ce6639292095d622a488bb43526ed04810e0649faa71ceb +F ext/misc/completion.c a0efe03edfdc4f717c61e6c9b0bfe2708ff7878010dae3174980a68fdf76aabc +F ext/misc/compress.c 3ed77691a3ce9e50921ae2b133dc176bb4d5587fdb57bde5872c4e5c348ce0bc +F ext/misc/csv.c 3ed979c1eb35e35a98b30ef545a2facf62994594217681d9138b4b75faf6b0d7 F ext/misc/dbdata.c e316fba936571584e55abd5b974a32a191727a6b746053a0c9d439bd2cf93940 F ext/misc/dbdump.c baf6e37447c9d6968417b1cd34cbedb0b0ab3f91b5329501d8a8d5be3287c336 -F ext/misc/eval.c 4b4757592d00fd32e44c7a067e6a0e4839c81a4d57abc4131ee7806d1be3104e +F ext/misc/eval.c 04bc9aada78c888394204b4ed996ab834b99726fb59603b0ee3ed6e049755dc1 F ext/misc/explain.c d5c12962d79913ef774b297006872af1fccda388f61a11d37758f9179a09551f -F ext/misc/fileio.c 288e7230e0fe464d71b0694e2d8bdd3a353118ac2e31da3964b95f460f09915f -F ext/misc/fossildelta.c 7708651072eb5620ab21bbfb518d184f27b2c29c0131b09b9a2d8852a8016430 -F ext/misc/fuzzer.c c4e27daf41433a64cad5265cd27dbcb891147e9994d0422200ce81ce9a54b625 -F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c -F ext/misc/json1.c 3005cd7c2508fc39e54959aab97120c332f1aa78888d3d64107f3a62469aa70a +F ext/misc/fileio.c bfa11a207da4eed8e5f84a1e3954608492f25f8850f9f00d0d2076f4648d7608 +F ext/misc/fossildelta.c 3761bc206e1d52b6c43fd86efbf94d9f800d32c8323cf2b5d51104262bdd4dc0 +F ext/misc/fuzzer.c eae560134f66333e9e1ca4c8ffea75df42056e2ce8456734565dbe1c2a92bf3d +F ext/misc/ieee754.c eaffd9b364d7c8371727e9c43fc8bec38cdacc4d11fc26beffaa3ca05a0ea9d6 +F ext/misc/json1.c 2d44e3fa37f958b42cbcd41651f9f0a0eaaf3bac3f1f4b8eb456431623cb3bd8 F ext/misc/memstat.c 3017a0832c645c0f8c773435620d663855f04690172316bd127270d1a7523d4d F ext/misc/memtrace.c 7c0d115d2ef716ad0ba632c91e05bd119cb16c1aedf3bec9f06196ead2d5537b F ext/misc/memvfs.c ab36f49e02ebcdf85a1e08dc4d8599ea8f343e073ac9e0bca18a98b7e1ec9567 F ext/misc/mmapwarm.c 8c5fe90d807a23e44a8b93e96e8b812b19b300d5fd8c1d40a4fd1d8224e33f46 -F ext/misc/nextchar.c 279f80fe8ef5ba413242e2704e246503ac601f005eefb180d19e6c920338a0ba +F ext/misc/nextchar.c 7877914c2a80c2f181dd04c3dbef550dfb54c93495dc03da2403b5dd58f34edd F ext/misc/normalize.c b4290464f542bae7a97b43f15bd197949b833ffd668b7c313631bd5d4610212c -F ext/misc/percentile.c 148dd07286b16e50f232bb638a47850085ad37d51f270429905bd865e595d1ca -F ext/misc/prefixes.c 7be86d17525cfae6ed462fc3c519efc44488ac329890f77491c8f82871f57e17 -F ext/misc/regexp.c be064ad9478361e40c7b8ca460f78b3d3c9b96080d5f391126c95e14bd362fae +F ext/misc/percentile.c b9086e223d583bdaf8cb73c98a6539d501a2fc4282654adbfea576453d82e691 +F ext/misc/prefixes.c 0f4f8cff5aebc00a7e3ac4021fd59cfe1a8e17c800ceaf592859ecb9cbc38196 +F ext/misc/regexp.c 246244c714267f303df76acf73dcf110cf2eaf076896aaaba8db6d6d21a129db F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c -F ext/misc/rot13.c 540a169cb0d74f15522a8930b0cccdcb37a4fd071d219a5a083a319fc6e8db77 +F ext/misc/rot13.c 4a57b830f8cf23b96156e1e3cbd1115186243feae25010bf9b02af88a343ae1f F ext/misc/scrub.c db9fff56fed322ca587d73727c6021b11ae79ce3f31b389e1d82891d144f22ad -F ext/misc/series.c 0c97f63378fddc9f425e82ba139b9aaf902211f24ced115c2b6ae12b425f7334 -F ext/misc/sha1.c d8125a88ee9023bc17d6f87ea8850db33f906d5701b30d4fd9bddb57f231e60a -F ext/misc/shathree.c 22ba7ca84a433d6466a7d05dcc876910b435a715da8cc462517db9351412b8c8 +F ext/misc/series.c a733a77d152983cc5d337c9df7b358ad17cfb44965476843cd03e2f571054914 +F ext/misc/sha1.c 1190aec0d9d886d9f5ffdf891142a626812327d11472c0cade3489db3b7b140a +F ext/misc/shathree.c 135b7c145db4a09b1650c3e7aff9cb538763a9a361e834c015dd1aaf8d5c9a00 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 -F ext/misc/spellfix.c f88ecb2c0294453ce8b7704b211f5350c41b085b38c8e056852e3a08b0f5e484 -F ext/misc/sqlar.c 57d5bc45cd5492208e451f697404be88f8612527d64c9d42f96b325b64983d74 +F ext/misc/spellfix.c 5cb7e1876925508aeef0e5ecd5ec8dab6089e09fa44cbf4322d5cb7a821a53f9 +F ext/misc/sqlar.c c9e5d58544e1506135806a1e0f525f92d4bb6bb125348dce469d778fb334fbce F ext/misc/stmt.c 8a8dc4675042e4551e4afe99b8d0cc7a4a2fc1a8dacc0a9ce1b1bbff145da93d F ext/misc/templatevtab.c 8a16a91a5ceaccfcbd6aaaa56d46828806e460dd194965b3f77bf38f14b942c4 -F ext/misc/totype.c 5b6b1eafaa993e29f8df843319b3292b029f1b5cbbbf11c8a88e05d3f714159f +F ext/misc/totype.c fa4aedeb07f66169005dffa8de3b0a2b621779fd44f85c103228a42afa71853b F ext/misc/unionvtab.c 36237f0607ca954ac13a4a0e2d2ac40c33bc6e032a5f55f431713061ef1625f9 -F ext/misc/uuid.c db4db81e8c6a92ad6176ebd9f81dcb6870e331e1a286d0452f4319e3ba3df812 +F ext/misc/uuid.c 5bb2264c1b64d163efa46509544fd7500cb8769cb7c16dd52052da8d961505cf F ext/misc/vfslog.c 3b25c2f56ba60788db247287be6ab024b53c4afffd412b4876db563389be0d35 F ext/misc/vfsstat.c 77b5b4235c9f7f11eddf82487c0a422944ac2f132dafd5af3be7a68a057b1cdb F ext/misc/vtablog.c 5538acd0c8ddaae372331bee11608d76973436b77d6a91e8635cfc9432fba5ae F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd -F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 -F ext/misc/zipfile.c 529c6e962e7dd39aa6f6aa6859f8c86af8af36833de270f27fa60135bb16c5d9 +F ext/misc/wholenumber.c 520f34c3099e5b7d546f13708607dc2fa173c46b68952eecf0d19cd675fec85e +F ext/misc/zipfile.c b09f38ccd4b9666b8e152f71c33ee381c8c2d6939203ac896c174e4c6fc6bc4a F ext/misc/zorder.c b0ff58fa643afa1d846786d51ea8d5c4b6b35aa0254ab5a82617db92f3adda64 F ext/rbu/rbu.c 8681f6157db6adc82c34af24b14ea8a3be0146ad2a3b6c1d5da6cb8a5796c8ce F ext/rbu/rbu1.test 221d9c18a5e600ac9ac6b1810d99d9f99163a7909ba61597876ab6e4d4beb3d6 @@ -477,8 +477,8 @@ F src/callback.c 88615dfc0a82167b65b452b4b305dbf86be77200b3343c6ffc6d03e92a01d18 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 1b0724e66f95f33b160b1af85caaf9cceb325d22abf39bd24df4f54a73982251 F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 -F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 -F src/dbstat.c 5125f559b33787a29f7ded750f2a69080f50a85bced98fe8ad02a99e543c4b44 +F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a +F src/dbstat.c 0f55297469d4244ab7df395849e1af98eb5e95816af7c661e7d2d8402dea23da F src/delete.c a5c59b9c0251cf7682bc52af0d64f09b1aefc6781a63592c8f1136f7b73c66e4 F src/expr.c 631b1f24d07114066c756984b8bc7be64529afb2ea3a5da4e3e262792f320dfa F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 @@ -521,8 +521,8 @@ F src/parse.y c8d2de64db469fd56e0fa24da46cd8ec8523eb98626567d2708df371b47fdc3f F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a -F src/pragma.c 6e13c9a885c0f2effaa6a1155b707d3d3e39bc572c3b003ce4caa9c2e9010ca3 -F src/pragma.h 5bbfafd74cf085762b64e4e2b00242917951b30468e380bddd8be6c21789aec2 +F src/pragma.c f648521a5b25c5ac17ddebab920ee0e5890a9af3492f747fd2e89bbce4d7e1d9 +F src/pragma.h 9f86a3a3a0099e651189521c8ad03768df598974e7bbdc21c7f9bb6125592fbd F src/prepare.c 6049beb71385f017af6fc320d2c75a4e50b75e280c54232442b785fbb83df057 F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 @@ -1786,7 +1786,7 @@ F tool/mkmsvcmin.tcl 6ecab9fe22c2c8de4d82d4c46797bda3d2deac8e763885f5a38d0c44a89 F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl 352a4319c0ad869eb26442bf7c3b015aa15594c21f1cce5a6420dbe999367c21 F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa -F tool/mkpragmatab.tcl ebff6eecf6bb0adf58093ee3174b76a87e7dd46eec1b4ca2798e4eac6bffdb8a +F tool/mkpragmatab.tcl ca12b1c718ececdab2d3aacb437bc3c81ebf68467f19d7974e17f18844a3a48f F tool/mkshellc.tcl 70a9978e363b0f3280ca9ce1c46d72563ff479c1930a12a7375e3881b7325712 F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 @@ -1853,7 +1853,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 f5fcf1fbc6473f8e91315b14d67745f2748010641b7463d1f4ca51e6fdf97462 -R 46209d5a1d64e52999e7462bf5830187 +P 3d87ff312e617a26846d482b423163cad9c222513f33e128f0fe348dda27c7c9 +R 29e3b810eabfd7c3a1417261cbdb8d29 U drh -Z 6fc5982c5d29c856ec36714597408f55 +Z c61c0860fa3c230e549e94e37c114435 diff --git a/manifest.uuid b/manifest.uuid index 1471672163..a5eb0373c6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3d87ff312e617a26846d482b423163cad9c222513f33e128f0fe348dda27c7c9 \ No newline at end of file +4c21373c21c9b17b222ae65297a039a035e6ec6b505c00c33704e3c03f94f834 \ No newline at end of file diff --git a/src/dbpage.c b/src/dbpage.c index 27c962d144..c4f0b539ef 100644 --- a/src/dbpage.c +++ b/src/dbpage.c @@ -73,6 +73,7 @@ static int dbpageConnect( DbpageTable *pTab = 0; int rc = SQLITE_OK; + sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY); rc = sqlite3_declare_vtab(db, "CREATE TABLE x(pgno INTEGER PRIMARY KEY, data BLOB, schema HIDDEN)"); if( rc==SQLITE_OK ){ diff --git a/src/dbstat.c b/src/dbstat.c index d0ce82e8c6..2fea48ce8c 100644 --- a/src/dbstat.c +++ b/src/dbstat.c @@ -167,6 +167,7 @@ static int statConnect( }else{ iDb = 0; } + sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY); rc = sqlite3_declare_vtab(db, zDbstatSchema); if( rc==SQLITE_OK ){ pTab = (StatTable *)sqlite3_malloc64(sizeof(StatTable)); diff --git a/src/pragma.c b/src/pragma.c index 2c127ed5a7..f577fd2b58 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1107,7 +1107,7 @@ void sqlite3Pragma( #endif if( sqlite3GetBoolean(zRight, 0) ){ - db->flags |= mask; + db->flags |= (mask & ~(SQLITE_TrustedSchema)); }else{ db->flags &= ~mask; if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 0; diff --git a/src/pragma.h b/src/pragma.h index 449180ba13..3edf5c1c30 100644 --- a/src/pragma.h +++ b/src/pragma.h @@ -617,6 +617,13 @@ static const PragmaName aPragmaName[] = { /* ePragFlg: */ PragFlg_Result0, /* ColNames: */ 0, 0, /* iArg: */ 0 }, +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + {/* zName: */ "trusted_schema", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_TrustedSchema }, +#endif #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) {/* zName: */ "user_version", /* ePragTyp: */ PragTyp_HEADER_VALUE, @@ -673,4 +680,4 @@ static const PragmaName aPragmaName[] = { /* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError }, #endif }; -/* Number of pragmas: 65 on by default, 81 total. */ +/* Number of pragmas: 66 on by default, 82 total. */ diff --git a/tool/mkpragmatab.tcl b/tool/mkpragmatab.tcl index 04c6416786..9ce5bd40fe 100644 --- a/tool/mkpragmatab.tcl +++ b/tool/mkpragmatab.tcl @@ -128,6 +128,11 @@ set pragma_def { ARG: SQLITE_RecTriggers IF: !defined(SQLITE_OMIT_FLAG_PRAGMAS) + NAME: trusted_schema + TYPE: FLAG + ARG: SQLITE_TrustedSchema + IF: !defined(SQLITE_OMIT_FLAG_PRAGMAS) + NAME: foreign_keys TYPE: FLAG ARG: SQLITE_ForeignKeys From b7e519956a3a38f4a5b0c1c52a654d47b199f070 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 8 Jan 2020 14:39:57 +0000 Subject: [PATCH 11/22] In the TreeView debugging output, show a "DDL" mark on SrcList and Expr nodes that derive from a non-TEMP schema. FossilOrigin-Name: fe7472fd2a70b4df6cb62041b72ed1638ba27ed1e6ceb8aaf56d1c8a82d91889 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/treeview.c | 18 ++++++++++++------ 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 1fe31e4a6c..c3f7bec0f7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\srecent\schanges\sfrom\strunk. -D 2020-01-08T13:08:52.289 +C In\sthe\sTreeView\sdebugging\soutput,\sshow\sa\s"DDL"\smark\son\sSrcList\sand\sExpr\snodes\nthat\sderive\sfrom\sa\snon-TEMP\sschema. +D 2020-01-08T14:39:57.767 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -593,7 +593,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 7b17f6e2f20f6cbcb0b215025a86b7457c38451fc7622f705e553d7a488c572d -F src/treeview.c 2f712c821748dccced8977c33de83146e75a193afd17da3da8ad64e0225fee20 +F src/treeview.c f51bdcac260ed3eafd8880e857c56e086e28340a1d7b49b487893610d71a2325 F src/trigger.c a40d50e88bd3355f1d2a73f0a3b2d6b42eae26ca4219001b82ef0d064439badc F src/update.c 9ad19af96aff95dc02a923a99f97c1bc0b909009a29a2914b796f786b9ac0c60 F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78 @@ -1853,7 +1853,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 4c21373c21c9b17b222ae65297a039a035e6ec6b505c00c33704e3c03f94f834 1c76f1d8ec0937a2d2e4ce75f98494c953e9621db31945d7e44f45d90d1c3892 -R 11f59f8982210d84b12dbd1c2e27ec48 +P 5962921fceaf2ec645379a5f1d18e2c2c13abbf92cf64606caee69f45a21c500 +R 93a7c1674ece8353922d12da4e1fe3fc U drh -Z ba42883755b74cbe63cf9689f020b123 +Z 848f5182d2c3a0564e6132972f60b9ae diff --git a/manifest.uuid b/manifest.uuid index cbec142043..545d38920a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5962921fceaf2ec645379a5f1d18e2c2c13abbf92cf64606caee69f45a21c500 \ No newline at end of file +fe7472fd2a70b4df6cb62041b72ed1638ba27ed1e6ceb8aaf56d1c8a82d91889 \ No newline at end of file diff --git a/src/treeview.c b/src/treeview.c index 938c1f1a1f..1ea2f24f2f 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -147,6 +147,9 @@ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ if( pItem->fg.jointype & JT_LEFT ){ sqlite3_str_appendf(&x, " LEFT-JOIN"); } + if( pItem->fg.fromDDL ){ + sqlite3_str_appendf(&x, " DDL"); + } sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, inSrc-1); if( pItem->pSelect ){ @@ -403,14 +406,17 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ return; } if( pExpr->flags || pExpr->affExpr ){ + StrAccum x; + sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0); + sqlite3_str_appendf(&x, " fg.af=%x.%c", + pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n'); if( ExprHasProperty(pExpr, EP_FromJoin) ){ - sqlite3_snprintf(sizeof(zFlgs),zFlgs," fg.af=%x.%c iRJT=%d", - pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n', - pExpr->iRightJoinTable); - }else{ - sqlite3_snprintf(sizeof(zFlgs),zFlgs," fg.af=%x.%c", - pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n'); + sqlite3_str_appendf(&x, " iRJT=%d", pExpr->iRightJoinTable); } + if( ExprHasProperty(pExpr, EP_FromDDL) ){ + sqlite3_str_appendf(&x, " DDL"); + } + sqlite3StrAccumFinish(&x); }else{ zFlgs[0] = 0; } From 6d35956c86834f53da7743b922e4a688643a3467 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 8 Jan 2020 15:43:29 +0000 Subject: [PATCH 12/22] Fix the rot13.c extension to be deterministic. Add the noop.c extension. FossilOrigin-Name: a679122ca8ec95d5c8afba3a1a50170db9dd519a3810e56877b8f56e858d0175 --- ext/misc/noop.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ ext/misc/rot13.c | 5 +++-- manifest | 13 ++++++----- manifest.uuid | 2 +- 4 files changed, 68 insertions(+), 9 deletions(-) create mode 100644 ext/misc/noop.c diff --git a/ext/misc/noop.c b/ext/misc/noop.c new file mode 100644 index 0000000000..99091fbb8e --- /dev/null +++ b/ext/misc/noop.c @@ -0,0 +1,57 @@ +/* +** 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. +** +****************************************************************************** +** +** This SQLite extension implements a noop() function used for testing. +*/ +#include "sqlite3ext.h" +SQLITE_EXTENSION_INIT1 +#include +#include + +/* +** Implementation of the noop() function. +** +** The function returns its argument, unchanged. +*/ +static void noopfunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + assert( argc==1 ); + sqlite3_result_value(context, argv[0]); +} + +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_noop_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + SQLITE_EXTENSION_INIT2(pApi); + (void)pzErrMsg; /* Unused parameter */ + rc = sqlite3_create_function(db, "noop", 1, + SQLITE_UTF8 | SQLITE_DETERMINISTIC, + 0, noopfunc, 0, 0); + if( rc ) return rc; + rc = sqlite3_create_function(db, "noop_i", 1, + SQLITE_UTF8 | SQLITE_DETERMINISTIC | SQLITE_INNOCUOUS, + 0, noopfunc, 0, 0); + if( rc ) return rc; + rc = sqlite3_create_function(db, "noop_do", 1, + SQLITE_UTF8 | SQLITE_DETERMINISTIC | SQLITE_DIRECTONLY, + 0, noopfunc, 0, 0); + return rc; +} diff --git a/ext/misc/rot13.c b/ext/misc/rot13.c index 8bde54700e..05b4a18801 100644 --- a/ext/misc/rot13.c +++ b/ext/misc/rot13.c @@ -105,8 +105,9 @@ int sqlite3_rot_init( int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Unused parameter */ - rc = sqlite3_create_function(db, "rot13", 1, SQLITE_UTF8|SQLITE_INNOCUOUS, 0, - rot13func, 0, 0); + rc = sqlite3_create_function(db, "rot13", 1, + SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, + 0, rot13func, 0, 0); if( rc==SQLITE_OK ){ rc = sqlite3_create_collation(db, "rot13", SQLITE_UTF8, 0, rot13CollFunc); } diff --git a/manifest b/manifest index c3f7bec0f7..d090866118 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sTreeView\sdebugging\soutput,\sshow\sa\s"DDL"\smark\son\sSrcList\sand\sExpr\snodes\nthat\sderive\sfrom\sa\snon-TEMP\sschema. -D 2020-01-08T14:39:57.767 +C Fix\sthe\srot13.c\sextension\sto\sbe\sdeterministic.\s\sAdd\sthe\snoop.c\sextension. +D 2020-01-08T15:43:29.452 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -302,12 +302,13 @@ F ext/misc/memtrace.c 7c0d115d2ef716ad0ba632c91e05bd119cb16c1aedf3bec9f06196ead2 F ext/misc/memvfs.c ab36f49e02ebcdf85a1e08dc4d8599ea8f343e073ac9e0bca18a98b7e1ec9567 F ext/misc/mmapwarm.c 8c5fe90d807a23e44a8b93e96e8b812b19b300d5fd8c1d40a4fd1d8224e33f46 F ext/misc/nextchar.c 7877914c2a80c2f181dd04c3dbef550dfb54c93495dc03da2403b5dd58f34edd +F ext/misc/noop.c 05e8263fb9998d675b5714a3d280b284b19ffe65256d6856fec807948485f6f0 F ext/misc/normalize.c b4290464f542bae7a97b43f15bd197949b833ffd668b7c313631bd5d4610212c F ext/misc/percentile.c b9086e223d583bdaf8cb73c98a6539d501a2fc4282654adbfea576453d82e691 F ext/misc/prefixes.c 0f4f8cff5aebc00a7e3ac4021fd59cfe1a8e17c800ceaf592859ecb9cbc38196 F ext/misc/regexp.c 246244c714267f303df76acf73dcf110cf2eaf076896aaaba8db6d6d21a129db F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c -F ext/misc/rot13.c 4a57b830f8cf23b96156e1e3cbd1115186243feae25010bf9b02af88a343ae1f +F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c F ext/misc/scrub.c db9fff56fed322ca587d73727c6021b11ae79ce3f31b389e1d82891d144f22ad F ext/misc/series.c a733a77d152983cc5d337c9df7b358ad17cfb44965476843cd03e2f571054914 F ext/misc/sha1.c 1190aec0d9d886d9f5ffdf891142a626812327d11472c0cade3489db3b7b140a @@ -1853,7 +1854,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 5962921fceaf2ec645379a5f1d18e2c2c13abbf92cf64606caee69f45a21c500 -R 93a7c1674ece8353922d12da4e1fe3fc +P fe7472fd2a70b4df6cb62041b72ed1638ba27ed1e6ceb8aaf56d1c8a82d91889 +R ac5937459d1f32e763d72ee868f7675e U drh -Z 848f5182d2c3a0564e6132972f60b9ae +Z 35839f6156af9b997f99a45283c98dee diff --git a/manifest.uuid b/manifest.uuid index 545d38920a..bbd4914395 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fe7472fd2a70b4df6cb62041b72ed1638ba27ed1e6ceb8aaf56d1c8a82d91889 \ No newline at end of file +a679122ca8ec95d5c8afba3a1a50170db9dd519a3810e56877b8f56e858d0175 \ No newline at end of file From 15f3eacfc0e9cfe6ebd4e71a342fab18c6d5eee0 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 8 Jan 2020 15:44:10 +0000 Subject: [PATCH 13/22] Provide the -innocuous option to the "db func" method in the TCL interface. FossilOrigin-Name: 0138652b6c2f21fd67e59a23a396a5b9d6a16ee9b44701cddfc49b23fddfce5b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/tclsqlite.c | 6 +++++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index d090866118..1a81415783 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\srot13.c\sextension\sto\sbe\sdeterministic.\s\sAdd\sthe\snoop.c\sextension. -D 2020-01-08T15:43:29.452 +C Provide\sthe\s-innocuous\soption\sto\sthe\s"db\sfunc"\smethod\sin\sthe\sTCL\sinterface. +D 2020-01-08T15:44:10.295 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -538,7 +538,7 @@ F src/sqliteInt.h 8c1fcdad7418c87cd482d2868610ed299e0201091e247598495e92e9c5d8e8 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 -F src/tclsqlite.c 8cd2600e8de23dff6cdf84d39f46ca57139b061b28f6f80b166bace17d52ab1c +F src/tclsqlite.c f2dae14bfe7a35c94b6d515df88071014678ec39dafebdcf8e6bde91d62516c1 F src/test1.c 4d0ab2f67053a4fff87d1d3586ecc0e5322a1fc45dd4119ab11dc96de44f17a1 F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644 @@ -1854,7 +1854,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 fe7472fd2a70b4df6cb62041b72ed1638ba27ed1e6ceb8aaf56d1c8a82d91889 -R ac5937459d1f32e763d72ee868f7675e +P a679122ca8ec95d5c8afba3a1a50170db9dd519a3810e56877b8f56e858d0175 +R 9fbba3111d220dbea3ef9c5770ac6cef U drh -Z 35839f6156af9b997f99a45283c98dee +Z fc531ff60387ab6488432d4541dd29bf diff --git a/manifest.uuid b/manifest.uuid index bbd4914395..0381fd8065 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a679122ca8ec95d5c8afba3a1a50170db9dd519a3810e56877b8f56e858d0175 \ No newline at end of file +0138652b6c2f21fd67e59a23a396a5b9d6a16ee9b44701cddfc49b23fddfce5b \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index a691898dc3..6a8b52b6bc 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -2818,6 +2818,7 @@ deserialize_error: ** --argcount N Function has exactly N arguments ** --deterministic The function is pure ** --directonly Prohibit use inside triggers and views + ** --innocuous Has no side effects or information leaks ** --returntype TYPE Specify the return type of the function */ case DB_FUNCTION: { @@ -2854,6 +2855,9 @@ deserialize_error: if( n>1 && strncmp(z, "-directonly",n)==0 ){ flags |= SQLITE_DIRECTONLY; }else + if( n>1 && strncmp(z, "-innocuous",n)==0 ){ + flags |= SQLITE_INNOCUOUS; + }else if( n>1 && strncmp(z, "-returntype", n)==0 ){ const char *azType[] = {"integer", "real", "text", "blob", "any", 0}; assert( SQLITE_INTEGER==1 && SQLITE_FLOAT==2 && SQLITE_TEXT==3 ); @@ -2870,7 +2874,7 @@ deserialize_error: }else{ Tcl_AppendResult(interp, "bad option \"", z, "\": must be -argcount, -deterministic, -directonly," - " or -returntype", (char*)0 + " -innocuous, or -returntype", (char*)0 ); return TCL_ERROR; } From 0dfa5255bc012a1991809e23ad2ac1a4089e1261 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 8 Jan 2020 17:28:19 +0000 Subject: [PATCH 14/22] 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 --- manifest | 21 ++++++++++---------- manifest.uuid | 2 +- src/expr.c | 39 +++++++++++++++++++++++++++++++++++++ src/resolve.c | 23 ++++------------------ src/sqliteInt.h | 1 + test/fts3atoken.test | 4 ++-- test/func.test | 6 +++--- test/trustschema1.test | 44 ++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 105 insertions(+), 35 deletions(-) create mode 100644 test/trustschema1.test diff --git a/manifest b/manifest index 1a81415783..dd4d4bcc90 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index 0381fd8065..3ce3dd07e0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0138652b6c2f21fd67e59a23a396a5b9d6a16ee9b44701cddfc49b23fddfce5b \ No newline at end of file +1da802d54b689a462e1fe899c6ffa08ef14d34f36728b14b055b5a76b1edc274 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 4e8703e552..7d712ad674 100644 --- a/src/expr.c +++ b/src/expr.c @@ -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; ia[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 diff --git a/src/resolve.c b/src/resolve.c index 929c8743f5..16546ada4b 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -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); - } } } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 455403637a..e56a4b3d54 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -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*); diff --git a/test/fts3atoken.test b/test/fts3atoken.test index 5694dfb9f0..4981480b5e 100644 --- a/test/fts3atoken.test +++ b/test/fts3atoken.test @@ -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 {}} diff --git a/test/func.test b/test/func.test index 3bfb1fe8ac..585ae1a14f 100644 --- a/test/func.test +++ b/test/func.test @@ -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 index 0000000000..d536645397 --- /dev/null +++ b/test/trustschema1.test @@ -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 From 2eeca2046eae31d913e7bae79893e343c17bd624 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 8 Jan 2020 20:37:45 +0000 Subject: [PATCH 15/22] Performance improvements and test cases added. Allow "PRAGMA trusted_schema=ON" FossilOrigin-Name: 30882ca80f6c51f6bb7b2692c1ac3f19a7c61a23aa8730be79aec0ae3ef08d54 --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/callback.c | 9 +++++---- src/expr.c | 9 ++++----- src/pragma.c | 2 +- src/resolve.c | 5 +++++ test/tclsqlite.test | 2 +- test/trustschema1.test | 34 ++++++++++++++++++++++++++++++++++ 8 files changed, 62 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index dd4d4bcc90..72132f8790 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -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 +C Performance\simprovements\sand\stest\scases\sadded.\sAllow\s"PRAGMA\strusted_schema=ON" +D 2020-01-08T20:37:45.893 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -474,14 +474,14 @@ F src/btree.c d70000b51523138582663b578b7f8a13e5d03c73c7c7ef18fdeafe1c234bbc3c F src/btree.h 6111552f19ed7a40f029cf4b33badc6fef9880314fffd80a945f0b7f43ab7471 F src/btreeInt.h 6794084fad08c9750b45145743c0e3e5c27c94dee89f26dd8df7073314934fd2 F src/build.c 67b1a8d3ac700747687dbdc49ded847a3c17fef450a8c919ac0399b44cbd4215 -F src/callback.c 88615dfc0a82167b65b452b4b305dbf86be77200b3343c6ffc6d03e92a01d181 +F src/callback.c c547d00963ae28100117b4fb1f0f32242109b5804374ee3bfe01138a54da7f76 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 1b0724e66f95f33b160b1af85caaf9cceb325d22abf39bd24df4f54a73982251 F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 0f55297469d4244ab7df395849e1af98eb5e95816af7c661e7d2d8402dea23da F src/delete.c a5c59b9c0251cf7682bc52af0d64f09b1aefc6781a63592c8f1136f7b73c66e4 -F src/expr.c bea12b33808867bb8f336d4bd70ebedfef72bb96bd453adcb068e578417b5e46 +F src/expr.c b1cb02a4b4fd1d2723f3de13d212fb5649923783835e37ee94d2792cad983035 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 92a248ec0fa4ed8ab60c98d9b188ce173aaf218f32e7737ba77deb2a684f9847 F src/func.c 259496e4856bd0a3215d16804992f3339f3e8db29f129a5a7285c341488bbe9c @@ -522,12 +522,12 @@ F src/parse.y c8d2de64db469fd56e0fa24da46cd8ec8523eb98626567d2708df371b47fdc3f F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a -F src/pragma.c f648521a5b25c5ac17ddebab920ee0e5890a9af3492f747fd2e89bbce4d7e1d9 +F src/pragma.c 6e13c9a885c0f2effaa6a1155b707d3d3e39bc572c3b003ce4caa9c2e9010ca3 F src/pragma.h 9f86a3a3a0099e651189521c8ad03768df598974e7bbdc21c7f9bb6125592fbd F src/prepare.c 6049beb71385f017af6fc320d2c75a4e50b75e280c54232442b785fbb83df057 F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c 5200d014fa78412f6189777cde3ac71b2dde55260c620be095610afe03fe9354 +F src/resolve.c 06abaef6272a4f0da048a1728b039a4f0beb318bda4bdc0efca89cb6af3b4f88 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c fbae5d6db63959aa1ecb34efe93caf5399444ca3c78d6f1ef4620b0ee5c37707 F src/shell.c.in 43d3cfbee97d78ca5782dc53e4c1e22d3cc15c91beff20889dc60551f47eab9f @@ -1402,7 +1402,7 @@ F test/tabfunc01.test 5ca6d004157a3e886a55a9387b960cc0db41acd88753eb597ff409ec6c F test/table.test eb3463b7add9f16a5bb836badf118cf391b809d09fdccd1f79684600d07ec132 F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 -F test/tclsqlite.test c4a5f5af3672fbe28a0aa322b88d9d1ce2225b6b1284ea11ede2e6d38e7c812c +F test/tclsqlite.test 6f8705d09377e2f2ff482ab181a1388773953a280623fff2ccab0e87d2bc10a2 F test/tempdb.test 4cdaa23ddd8acb4d79cbb1b68ccdfd09b0537aaba909ca69a876157c2a2cbd08 F test/tempdb2.test 353864e96fd3ae2f70773d0ffbf8b1fe48589b02c2ec05013b540879410c3440 F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900 @@ -1592,7 +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/trustschema1.test aec32a37ef8468aa6f8e5645cdd22c6ff70e0cddfff39d70de5683c67a2c0091 F test/tt3_checkpoint.c 9e75cf7c1c364f52e1c47fd0f14c4340a9db0fe1 F test/tt3_index.c 39eec10a35f57672225be4d182862152896dee4a F test/tt3_lookaside1.c 0377e202c3c2a50d688cb65ba203afeda6fafeb9 @@ -1855,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 0138652b6c2f21fd67e59a23a396a5b9d6a16ee9b44701cddfc49b23fddfce5b -R ce4061dc1b633cb47a4ee9d471ef9c80 +P 1da802d54b689a462e1fe899c6ffa08ef14d34f36728b14b055b5a76b1edc274 +R 78a6c1828843e575068f968acb0f372e U drh -Z 1c75c43008bf3984bb39f61126a3891e +Z ca06f3bd43b14133e2371bf0709d0315 diff --git a/manifest.uuid b/manifest.uuid index 3ce3dd07e0..e118370206 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1da802d54b689a462e1fe899c6ffa08ef14d34f36728b14b055b5a76b1edc274 \ No newline at end of file +30882ca80f6c51f6bb7b2692c1ac3f19a7c61a23aa8730be79aec0ae3ef08d54 \ No newline at end of file diff --git a/src/callback.c b/src/callback.c index a360e46ee4..3d991901d1 100644 --- a/src/callback.c +++ b/src/callback.c @@ -288,12 +288,13 @@ static int matchQuality( u8 enc /* Desired text encoding */ ){ int match; - - /* nArg of -2 is a special case */ - if( nArg==(-2) ) return (p->xSFunc==0) ? 0 : FUNC_PERFECT_MATCH; + assert( p->nArg>=-1 ); /* Wrong number of arguments means "no match" */ - if( p->nArg!=nArg && p->nArg>=0 ) return 0; + if( p->nArg!=nArg ){ + if( nArg==(-2) ) return (p->xSFunc==0) ? 0 : FUNC_PERFECT_MATCH; + if( p->nArg>=0 ) return 0; + } /* Give a better score to a function with a specific number of arguments ** than to function that accepts any number of arguments. */ diff --git a/src/expr.c b/src/expr.c index 7d712ad674..a9d59cfa60 100644 --- a/src/expr.c +++ b/src/expr.c @@ -990,9 +990,8 @@ void sqlite3ExprFunctionUsable( FuncDef *pDef /* The function being invoked */ ){ assert( !IN_RENAME_OBJECT ); - if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0 - && ExprHasProperty(pExpr, EP_FromDDL) - ){ + assert( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0 ); + if( ExprHasProperty(pExpr, EP_FromDDL) ){ if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0 || (pParse->db->flags & SQLITE_TrustedSchema)==0 ){ @@ -4112,8 +4111,9 @@ expr_code_doover: assert( (pDef->funcFlags & SQLITE_FUNC_DIRECT)==0 ); return exprCodeInlineFunction(pParse, pFarg, SQLITE_PTR_TO_INT(pDef->pUserData), target); + }else if( pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE) ){ + sqlite3ExprFunctionUsable(pParse, pExpr, pDef); } - sqlite3ExprFunctionUsable(pParse, pExpr, pDef); for(i=0; ia[i].pExpr) ){ @@ -5778,7 +5778,6 @@ 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 diff --git a/src/pragma.c b/src/pragma.c index f577fd2b58..2c127ed5a7 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1107,7 +1107,7 @@ void sqlite3Pragma( #endif if( sqlite3GetBoolean(zRight, 0) ){ - db->flags |= (mask & ~(SQLITE_TrustedSchema)); + db->flags |= mask; }else{ db->flags &= ~mask; if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 0; diff --git a/src/resolve.c b/src/resolve.c index 16546ada4b..cfdbc569fd 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -888,6 +888,11 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ ** 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 + && !IN_RENAME_OBJECT + ){ + sqlite3ExprFunctionUsable(pParse, pExpr, pDef); } } diff --git a/test/tclsqlite.test b/test/tclsqlite.test index d72f858666..b01da0ec23 100644 --- a/test/tclsqlite.test +++ b/test/tclsqlite.test @@ -789,7 +789,7 @@ do_test 17.6.2 { do_test 17.6.3 { list [catch { db function xyz -n object ret } msg] $msg -} {1 {bad option "-n": must be -argcount, -deterministic, -directonly, or -returntype}} +} {1 {bad option "-n": must be -argcount, -deterministic, -directonly, -innocuous, or -returntype}} # 2019-02-28: The "bind_fallback" command. # diff --git a/test/trustschema1.test b/test/trustschema1.test index d536645397..1d8b5f924e 100644 --- a/test/trustschema1.test +++ b/test/trustschema1.test @@ -41,4 +41,38 @@ do_catchsql_test 1.140 { SELECT a, b, c FROM t1; } {1 {unsafe use of f2()}} +do_catchsql_test 1.200 { + CREATE TABLE t2(a,b,c,CHECK(f3(c)==c)); +} {1 {unsafe use of f3()}} +do_catchsql_test 1.210 { + PRAGMA trusted_schema=Off; + CREATE TABLE t2(a,b,c,CHECK(f2(c)==c)); +} {1 {unsafe use of f2()}} +do_catchsql_test 1.211 { + PRAGMA trusted_schema=On; + CREATE TABLE t2(a,b,c,CHECK(f2(c)==c)); +} {0 {}} +do_catchsql_test 1.220 { + INSERT INTO t2 VALUES(1,2,3); + SELECT * FROM t2; +} {0 {1 2 3}} +do_catchsql_test 1.230 { + PRAGMA trusted_schema=off; + INSERT INTO t2 VALUES(4,5,6); +} {1 {unsafe use of f2()}} +do_execsql_test 1.231 { + SELECT * FROM t2; +} {1 2 3} + +do_catchsql_test 1.300 { + CREATE TABLE t3(a,b DEFAULT(f2(25))); +} {0 {}} +do_catchsql_test 1.310 { + PRAGMA trusted_schema=Off; + INSERT INTO t3(a) VALUES(1); +} {1 {unsafe use of f2()}} +do_catchsql_test 1.311 { + INSERT INTO t3(a,b) VALUES(1,2); +} {0 {}} + finish_test From 014fff20adb15674b91be74895fc8e3164a92434 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 8 Jan 2020 22:22:36 +0000 Subject: [PATCH 16/22] Block edgy functions used in DEFAULT constraints. FossilOrigin-Name: da434dc149786e4b1cd80b3b2b25f8b614d0dec62d5439f839a66b536999e398 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/build.c | 3 ++- src/expr.c | 28 +++++++++++++++++++++------- src/treeview.c | 2 +- 5 files changed, 33 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 72132f8790..c99f7e7da3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\simprovements\sand\stest\scases\sadded.\sAllow\s"PRAGMA\strusted_schema=ON" -D 2020-01-08T20:37:45.893 +C Block\sedgy\sfunctions\sused\sin\sDEFAULT\sconstraints. +D 2020-01-08T22:22:36.071 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -473,7 +473,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c d70000b51523138582663b578b7f8a13e5d03c73c7c7ef18fdeafe1c234bbc3c F src/btree.h 6111552f19ed7a40f029cf4b33badc6fef9880314fffd80a945f0b7f43ab7471 F src/btreeInt.h 6794084fad08c9750b45145743c0e3e5c27c94dee89f26dd8df7073314934fd2 -F src/build.c 67b1a8d3ac700747687dbdc49ded847a3c17fef450a8c919ac0399b44cbd4215 +F src/build.c bd2f382562b08f14748d54402220be1082c2f8ff8973fad47e45a381c438f9bf F src/callback.c c547d00963ae28100117b4fb1f0f32242109b5804374ee3bfe01138a54da7f76 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 1b0724e66f95f33b160b1af85caaf9cceb325d22abf39bd24df4f54a73982251 @@ -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 b1cb02a4b4fd1d2723f3de13d212fb5649923783835e37ee94d2792cad983035 +F src/expr.c c5ff3bb83e5b512f6251a37e7ac9f5b1686e6a135e22d40c013d7d267a532af5 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 92a248ec0fa4ed8ab60c98d9b188ce173aaf218f32e7737ba77deb2a684f9847 F src/func.c 259496e4856bd0a3215d16804992f3339f3e8db29f129a5a7285c341488bbe9c @@ -594,7 +594,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 7b17f6e2f20f6cbcb0b215025a86b7457c38451fc7622f705e553d7a488c572d -F src/treeview.c f51bdcac260ed3eafd8880e857c56e086e28340a1d7b49b487893610d71a2325 +F src/treeview.c 438c1000587b33faba35e87596bebcf7f40638d98f33781cdd9e04711b18b09c F src/trigger.c a40d50e88bd3355f1d2a73f0a3b2d6b42eae26ca4219001b82ef0d064439badc F src/update.c 9ad19af96aff95dc02a923a99f97c1bc0b909009a29a2914b796f786b9ac0c60 F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78 @@ -1855,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 1da802d54b689a462e1fe899c6ffa08ef14d34f36728b14b055b5a76b1edc274 -R 78a6c1828843e575068f968acb0f372e +P 30882ca80f6c51f6bb7b2692c1ac3f19a7c61a23aa8730be79aec0ae3ef08d54 +R 2d6bd4faf1a02c29990cd0df461c78ad U drh -Z ca06f3bd43b14133e2371bf0709d0315 +Z 9253d4aa29f3b6b8cb96462d5b434aa9 diff --git a/manifest.uuid b/manifest.uuid index e118370206..640d9dc50c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -30882ca80f6c51f6bb7b2692c1ac3f19a7c61a23aa8730be79aec0ae3ef08d54 \ No newline at end of file +da434dc149786e4b1cd80b3b2b25f8b614d0dec62d5439f839a66b536999e398 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 81332356ec..f0435aacec 100644 --- a/src/build.c +++ b/src/build.c @@ -1404,8 +1404,9 @@ void sqlite3AddDefaultValue( sqlite3 *db = pParse->db; p = pParse->pNewTable; if( p!=0 ){ + int isInit = db->init.busy && db->init.iDb!=1; pCol = &(p->aCol[p->nCol-1]); - if( !sqlite3ExprIsConstantOrFunction(pExpr, db->init.busy) ){ + if( !sqlite3ExprIsConstantOrFunction(pExpr, isInit) ){ sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant", pCol->zName); #ifndef SQLITE_OMIT_GENERATED_COLUMNS diff --git a/src/expr.c b/src/expr.c index a9d59cfa60..994e3fe07f 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1971,10 +1971,11 @@ Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){ ** In all cases, the callbacks set Walker.eCode=0 and abort if the expression ** is found to not be a constant. ** -** The sqlite3ExprIsConstantOrFunction() is used for evaluating expressions -** in a CREATE TABLE statement. The Walker.eCode value is 5 when parsing -** an existing schema and 4 when processing a new statement. A bound -** parameter raises an error for new statements, but is silently converted +** The sqlite3ExprIsConstantOrFunction() is used for evaluating DEFAULT +** expressions in a CREATE TABLE statement. The Walker.eCode value is 5 +** when parsing an existing schema out of the sqlite_master table and 4 +** when processing a new CREATE TABLE statement. A bound parameter raises +** an error for new statements, but is silently converted ** to NULL for existing schemas. This allows sqlite_master tables that ** contain a bound parameter because they were generated by older versions ** of SQLite to be parsed by newer versions of SQLite without raising a @@ -1998,6 +1999,7 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ if( (pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc)) && !ExprHasProperty(pExpr, EP_WinFunc) ){ + if( pWalker->eCode==5 ) ExprSetProperty(pExpr, EP_FromDDL); return WRC_Continue; }else{ pWalker->eCode = 0; @@ -2161,9 +2163,21 @@ int sqlite3ExprIsConstantOrGroupBy(Parse *pParse, Expr *p, ExprList *pGroupBy){ } /* -** Walk an expression tree. Return non-zero if the expression is constant -** or a function call with constant arguments. Return and 0 if there -** are any variables. +** Walk an expression tree for the DEFAULT field of a column definition +** in a CREATE TABLE statement. Return non-zero if the expression is +** acceptable for use as a DEFAULT. That is to say, return non-zero if +** the expression is constant or a function call with constant arguments. +** Return and 0 if there are any variables. +** +** isInit is true when parsing from sqlite_master. isInit is false when +** processing a new CREATE TABLE statement. When isInit is true, parameters +** (such as ? or $abc) in the expression are converted into NULL. When +** isInit is false, parameters raise an error. Parameters should not be +** allowed in a CREATE TABLE statement, but some legacy versions of SQLite +** allowed it, so we need to support it when reading sqlite_master for +** backwards compatibility. +** +** If isInit is true, set EP_FromDDL on every TK_FUNCTION node. ** ** For the purposes of this function, a double-quoted string (ex: "abc") ** is considered a variable but a single-quoted string (ex: 'abc') is diff --git a/src/treeview.c b/src/treeview.c index 1ea2f24f2f..90a1d2dcc9 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -572,7 +572,7 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ }else{ pFarg = pExpr->x.pList; #ifndef SQLITE_OMIT_WINDOWFUNC - pWin = pExpr->y.pWin; + pWin = ExprHasProperty(pExpr, EP_WinFunc) ? pExpr->y.pWin : 0; #else pWin = 0; #endif From 05b32ee3c0788fbe3d210ade38e186c903678556 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 9 Jan 2020 01:20:03 +0000 Subject: [PATCH 17/22] Fix a problem that restricted edgy functions in TEMP tables. New test cases added. FossilOrigin-Name: 8878c40753566a8c4ccd1d413019cabde7569b947f730527d13bfc3db384e97d --- manifest | 16 ++-- manifest.uuid | 2 +- src/resolve.c | 7 +- src/sqliteInt.h | 1 + test/trustschema1.test | 175 ++++++++++++++++++++++++++++++++++++++++- 5 files changed, 190 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index c99f7e7da3..2544b8cd3d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Block\sedgy\sfunctions\sused\sin\sDEFAULT\sconstraints. -D 2020-01-08T22:22:36.071 +C Fix\sa\sproblem\sthat\srestricted\sedgy\sfunctions\sin\sTEMP\stables.\nNew\stest\scases\sadded. +D 2020-01-09T01:20:03.116 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -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 06abaef6272a4f0da048a1728b039a4f0beb318bda4bdc0efca89cb6af3b4f88 +F src/resolve.c 1139e3157c710c6e6f04fe726f4e0d8bdb1ae89a276d3b0ca4975af163141c9c 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 0ca99e207087851fd27c6e1314fc52d273caa424ff2bafa3f1daf6d5eb63b35a +F src/sqliteInt.h ee242902766f9a96aeaca4315dbe1e204bbb2954cd455ffa085bba84fa47956b F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1592,7 +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 aec32a37ef8468aa6f8e5645cdd22c6ff70e0cddfff39d70de5683c67a2c0091 +F test/trustschema1.test 4e970aef0bfe0cee139703cc7209d0e0f07725d999b180ba50770f49edef1494 F test/tt3_checkpoint.c 9e75cf7c1c364f52e1c47fd0f14c4340a9db0fe1 F test/tt3_index.c 39eec10a35f57672225be4d182862152896dee4a F test/tt3_lookaside1.c 0377e202c3c2a50d688cb65ba203afeda6fafeb9 @@ -1855,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 30882ca80f6c51f6bb7b2692c1ac3f19a7c61a23aa8730be79aec0ae3ef08d54 -R 2d6bd4faf1a02c29990cd0df461c78ad +P da434dc149786e4b1cd80b3b2b25f8b614d0dec62d5439f839a66b536999e398 +R 5d23da58c4e26d6a3869b8997dbb1f9d U drh -Z 9253d4aa29f3b6b8cb96462d5b434aa9 +Z 2a63c0c342c8804a0df9ef8a4a5f7519 diff --git a/manifest.uuid b/manifest.uuid index 640d9dc50c..e7e1532d0f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -da434dc149786e4b1cd80b3b2b25f8b614d0dec62d5439f839a66b536999e398 \ No newline at end of file +8878c40753566a8c4ccd1d413019cabde7569b947f730527d13bfc3db384e97d \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index cfdbc569fd..3e5ac16e2e 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -876,7 +876,7 @@ 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( pNC->ncFlags & NC_FromDDL ) ExprSetProperty(pExpr, EP_FromDDL); } if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0 && pParse->nested==0 @@ -1884,6 +1884,11 @@ int sqlite3ResolveSelfReference( sSrc.a[0].zName = pTab->zName; sSrc.a[0].pTab = pTab; sSrc.a[0].iCursor = -1; + if( pTab->pSchema!=pParse->db->aDb[1].pSchema ){ + /* Cause EP_FromDDL to be set on TK_FUNCTION nodes of non-TEMP + ** schema elements */ + type |= NC_FromDDL; + } } sNC.pParse = pParse; sNC.pSrcList = &sSrc; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index e56a4b3d54..14c17a42e6 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2968,6 +2968,7 @@ struct NameContext { #define NC_HasWin 0x08000 /* One or more window functions seen */ #define NC_IsDDL 0x10000 /* Resolving names in a CREATE statement */ #define NC_InAggFunc 0x20000 /* True if analyzing arguments to an agg func */ +#define NC_FromDDL 0x40000 /* SQL text comes from sqlite_master */ /* ** An instance of the following object describes a single ON CONFLICT diff --git a/test/trustschema1.test b/test/trustschema1.test index 1d8b5f924e..dba954f146 100644 --- a/test/trustschema1.test +++ b/test/trustschema1.test @@ -17,7 +17,8 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix trustschema1 - +# edgy functions used in generated columns +# proc f1 {x} {return $x} do_test 1.100 { db function f1 -innocuous -deterministic f1 @@ -40,8 +41,22 @@ do_catchsql_test 1.130 { do_catchsql_test 1.140 { SELECT a, b, c FROM t1; } {1 {unsafe use of f2()}} +do_catchsql_test 1.150 { + PRAGMA trusted_schema=ON; + DROP TABLE t1; + CREATE TABLE t1(a, b AS (f3(a+1))); +} {1 {unsafe use of f3()}} +do_execsql_test 1.160 { + PRAGMA trusted_schema=OFF; + CREATE TEMP TABLE temp1(a,b AS (f3(a+1))); + INSERT INTO temp1(a) VALUES(100),(900); + SELECT * FROM temp1; +} {100 101 900 901} +# edgy functions used in CHECK constraints +# do_catchsql_test 1.200 { + PRAGMA trusted_schema=ON; CREATE TABLE t2(a,b,c,CHECK(f3(c)==c)); } {1 {unsafe use of f3()}} do_catchsql_test 1.210 { @@ -63,7 +78,17 @@ do_catchsql_test 1.230 { do_execsql_test 1.231 { SELECT * FROM t2; } {1 2 3} +# Ok to put as many edgy functions as you want in a +# TEMP table. +do_execsql_test 1.240 { + PRAGMA trusted_schema=OFF; + CREATE TEMP TABLE temp2(a, b, CHECK(f3(b)==b)); + INSERT INTO temp2(a,b) VALUES(1,2),('x','y'); + SELECT * FROM temp2; +} {1 2 x y} +# edgy functions used in DEFAULT constraints +# do_catchsql_test 1.300 { CREATE TABLE t3(a,b DEFAULT(f2(25))); } {0 {}} @@ -74,5 +99,153 @@ do_catchsql_test 1.310 { do_catchsql_test 1.311 { INSERT INTO t3(a,b) VALUES(1,2); } {0 {}} +do_execsql_test 1.320 { + CREATE TEMP TABLE temp3(a, b DEFAULT(f3(31))); + INSERT INTO temp3(a) VALUES(22); + SELECT * FROM temp3; +} {22 31} + +# edgy functions used in partial indexes. +# +do_execsql_test 1.400 { + CREATE TABLE t4(a,b,c); + INSERT INTO t4 VALUES(1,2,3),('a','b','c'),(4,'d',0); + SELECT * FROM t4; + CREATE TEMP TABLE temp4(a,b,c); + INSERT INTO temp4 SELECT * FROM t4; +} {1 2 3 a b c 4 d 0} +do_catchsql_test 1.410 { + CREATE INDEX t4a ON t4(a) WHERE f3(c); +} {1 {unsafe use of f3()}} +do_catchsql_test 1.420 { + PRAGMA trusted_schema=OFF; + CREATE INDEX t4a ON t4(a) WHERE f2(c); +} {1 {unsafe use of f2()}} +do_execsql_test 1.421 { + CREATE INDEX t4a ON t4(a) WHERE f1(c); + SELECT a FROM t4 WHERE f1(c) ORDER BY a; +} {1} +do_execsql_test 1.430 { + PRAGMA trusted_schema=ON; + CREATE INDEX t4b ON t4(b) WHERE f2(c); + SELECT b FROM t4 WHERE f2(c) ORDER BY b; +} {2} +do_execsql_test 1.440 { + PRAGMA trusted_schema=OFF; + CREATE INDEX temp4a ON temp4(a) WHERE f3(c); + SELECT a FROM temp4 WHERE f2(c) ORDER BY a; +} {1} + +# edgy functions used in index expressions +# +do_execsql_test 1.500 { + CREATE TABLE t5(a,b,c); + INSERT INTO t5 VALUES(1,2,3),(4,5,6),(7,0,-3); + SELECT * FROM t5; + CREATE TEMP TABLE temp5(a,b,c); + INSERT INTO temp5 SELECT * FROM t5; +} {1 2 3 4 5 6 7 0 -3} +do_catchsql_test 1.510 { + CREATE INDEX t5x1 ON t5(a+f3(b)); +} {1 {unsafe use of f3()}} +do_catchsql_test 1.520 { + PRAGMA trusted_schema=OFF; + CREATE INDEX t5x1 ON t5(a+f2(b)); +} {1 {unsafe use of f2()}} +do_execsql_test 1.521 { + CREATE INDEX t5x1 ON t5(a+f1(b)); + SELECT * FROM t5 INDEXED BY t5x1 WHERE a+f1(b)=3; +} {1 2 3} +do_execsql_test 1.530 { + PRAGMA trusted_schema=ON; + CREATE INDEX t5x2 ON t5(b+f2(c)); + SELECT * FROM t5 INDEXED BY t5x2 WHERE b+f2(c)=11; +} {4 5 6} +do_execsql_test 1.540 { + PRAGMA trusted_schema=OFF; + CREATE INDEX temp5x1 ON temp5(a+f3(b)); + SELECT * FROM temp5 INDEXED BY temp5x1 WHERE a+f3(b)=7; +} {7 0 -3} + +# edgy functions in VIEWs +# +reset_db +db function f1 -innocuous -deterministic f1 +db function f2 -deterministic f1 +db function f3 -directonly -deterministic f1 +do_execsql_test 2.100 { + CREATE TABLE t1(a,b,c); + INSERT INTO t1 VALUES(1,2,3),(100,50,75),(-11,22,-33); + CREATE VIEW v1a AS SELECT f3(a+b) FROM t1; + SELECT f3(a+b) FROM t1; +} {3 150 11} +do_catchsql_test 2.110 { + PRAGMA trusted_schema=ON; + SELECT * FROM v1a; +} {1 {unsafe use of f3()}} +do_catchsql_test 2.111 { + PRAGMA trusted_schema=OFF; + SELECT * FROM v1a; +} {1 {unsafe use of f3()}} +do_execsql_test 2.120 { + DROP VIEW v1a; + CREATE TEMP VIEW v1a AS SELECT f3(a+b) FROM t1; + SELECT * FROM v1a; +} {3 150 11} +do_execsql_test 2.130 { + CREATE VIEW v1b AS SELECT f2(b+c) FROM t1; + SELECT f2(b+c) FROM t1; +} {5 125 -11} +do_catchsql_test 2.140 { + PRAGMA trusted_schema=ON; + SELECT * FROM v1b; +} {0 {5 125 -11}} +do_catchsql_test 2.141 { + PRAGMA trusted_schema=OFF; + SELECT * FROM v1b; +} {1 {unsafe use of f2()}} +do_execsql_test 2.150 { + DROP VIEW v1b; + CREATE TEMP VIEW v1b AS SELECT f2(b+c) FROM t1; + SELECT * FROM v1b; +} {5 125 -11} + +# edgy functions inside of triggers +# +do_execsql_test 3.100 { + DELETE FROM t1; + CREATE TABLE t2(x); + CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN + INSERT INTO t2(x) SELECT f3(new.a); + END; +} {} +do_catchsql_test 3.110 { + INSERT INTO t1 VALUES(7,6,5); +} {1 {unsafe use of f3()}} +do_execsql_test 3.111 { + SELECT * FROM t1; + SELECT * FROM t2; +} {} + +do_execsql_test 3.120 { + DROP TRIGGER r1; + CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN + INSERT INTO t2(x) SELECT f2(new.a)+100; + END; + PRAGMA trusted_schema=ON; + INSERT INTO t1 VALUES(7,6,5); + SELECT * FROM t1, t2; +} {7 6 5 107} +do_catchsql_test 3.130 { + DELETE FROM t1; + DELETE FROM t2; + PRAGMA trusted_schema=OFF; + INSERT INTO t1 VALUES(7,6,5); +} {1 {unsafe use of f2()}} +do_execsql_test 3.131 { + SELECT * FROM t1; + SELECT * FROM t2; +} {} + finish_test From 32266a1072dae25c0bb52dc3aa6853e861f5d779 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 9 Jan 2020 13:08:28 +0000 Subject: [PATCH 18/22] Simplified error message for the unsafe use of a virtual table. FossilOrigin-Name: d662129a601e05e8fca5717a890b5bc920b80a750d061f3c2494788d32b917a5 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 2544b8cd3d..a4a0bd8da2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sthat\srestricted\sedgy\sfunctions\sin\sTEMP\stables.\nNew\stest\scases\sadded. -D 2020-01-09T01:20:03.116 +C Simplified\serror\smessage\sfor\sthe\sunsafe\suse\sof\sa\svirtual\stable. +D 2020-01-09T13:08:28.875 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -529,7 +529,7 @@ F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 1139e3157c710c6e6f04fe726f4e0d8bdb1ae89a276d3b0ca4975af163141c9c F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 -F src/select.c fbae5d6db63959aa1ecb34efe93caf5399444ca3c78d6f1ef4620b0ee5c37707 +F src/select.c 0ae5299e59845657ccbe1e05817b9926807523d3ca584e80040f57eab892b98a F src/shell.c.in 43d3cfbee97d78ca5782dc53e4c1e22d3cc15c91beff20889dc60551f47eab9f F src/sqlite.h.in 06452043348e35cf6108345a35574a2faa4d1c2829beefb1e73c73d6bfb2fa80 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1855,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 da434dc149786e4b1cd80b3b2b25f8b614d0dec62d5439f839a66b536999e398 -R 5d23da58c4e26d6a3869b8997dbb1f9d +P 8878c40753566a8c4ccd1d413019cabde7569b947f730527d13bfc3db384e97d +R 0dd0572d840f5da124648f9c608f9c87 U drh -Z 2a63c0c342c8804a0df9ef8a4a5f7519 +Z 4a660a42e378fba2b6c64d3dce74af2a diff --git a/manifest.uuid b/manifest.uuid index e7e1532d0f..47e32ca86f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8878c40753566a8c4ccd1d413019cabde7569b947f730527d13bfc3db384e97d \ No newline at end of file +d662129a601e05e8fca5717a890b5bc920b80a750d061f3c2494788d32b917a5 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 34c476ff73..e7fd1b8c9f 100644 --- a/src/select.c +++ b/src/select.c @@ -4977,8 +4977,8 @@ static int selectExpander(Walker *pWalker, Select *p){ && ALWAYS(pTab->pVTable!=0) && pTab->pVTable->eVtabRisk > ((db->flags & SQLITE_TrustedSchema)!=0) ){ - sqlite3ErrorMsg(pParse, "cannot access \"%s\" from within a trigger" - " or view", pTab->zName); + sqlite3ErrorMsg(pParse, "unsafe use of virtual table \"%s\"", + pTab->zName); } pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0); nCol = pTab->nCol; From b0c4ef711f625e1cdcc1340803e87e681e21e5f3 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 9 Jan 2020 14:51:47 +0000 Subject: [PATCH 19/22] Design notes for the new-security-options branch. FossilOrigin-Name: af7c1ed4f8a7293d0ecacca3cfbe9414e0de5ec40b418ce7831b8dc724feb747 --- doc/trusted-schema.md | 142 ++++++++++++++++++++++++++++++++++++++++++ manifest | 11 ++-- manifest.uuid | 2 +- 3 files changed, 149 insertions(+), 6 deletions(-) create mode 100644 doc/trusted-schema.md diff --git a/doc/trusted-schema.md b/doc/trusted-schema.md new file mode 100644 index 0000000000..32abf9d4d0 --- /dev/null +++ b/doc/trusted-schema.md @@ -0,0 +1,142 @@ +# The new-security-options branch + +## The problem that the [new-security-options](/timeline?r=new-security-options) branch tries to solve + +An attacker might modify the schema of an SQLite database by adding +structures that cause code to run when some other application opens and +reads the database. For example, the attacker might replace a table +definition with a view. Or the attacker might add triggers to tables +or views, or add new CHECK constraints or generated columns or indexes +with expressions in the index list or in the WHERE clause. If the +added features invoke SQL functions or virtual tables with side effects, +that might cause harm to the system if run by a high-privilege victim. +Or, the added features might exfiltrate information if the database is +read by a high-privilege victim. + +The changes in this branch strive to make it easier for high-privilege +applications to safely read SQLite database files that might have been +maliciously corrupted by an attacker. + +## Overview of changes in [new-security-options](/timeline?r=new-security-options) + +The basic idea is to tag every SQL function and virtual table with one +of three risk levels: + + 1. Innocuous + 2. Normal + 3. Direct-Only + +Innocuous functions/vtabs are safe and can be used at any time. +Direct-only elements, in contrast, might have cause side-effects and +should only be used from top-level SQL, not from within triggers or views nor +in elements of the schema such as CHECK constraint, DEFAULT values, +generated columns, index expressions, or in the WHERE clause of a +partial index that are potentially under the control of an attacker. +Normal elements be have like Innocuous if TRUSTED\_SCHEMA=on +and behave like direct-only if TRUSTED\_SCHEMA=off. + +Application-defined functions and virtual tables go in as Normal unless +the application takes deliberate stesp to change the risk level. + +For backwards compatibility, the default is TRUSTED\_SCHEMA=on. Documentation +will be updated to recommend applications turn TRUSTED\_SCHEMA to off. + +An innocuous function or virtual table is one that can only read content +from the database file in which it resides, and can only alter the database +in which it resides. Most SQL functions are innocuous. For example, there +is no harm in an attacker running the abs() function. + +Direct-only elements that have side-effects that go outside the database file +in which it lives, or return information from outside of the database file. +Examples of direct-only elements include: + + 1. The fts3_tokenizer() function + 2. The writefile() function + 3. The readfile() function + 4. The zipvfs virtual table + 5. The csv virtual table + +We do not want an attacker to be able to add these kinds of things to +the database schema and possibly trick a high-privilege application +from performing any of these actions. Therefore, functions and vtabs +with side-effects are marked as Direct-Only. + +Legacy applications might add other risky functions or vtabs. Those will +go in as "Normal" by default. For optimal security, we want those risky +app-defined functions and vtabs to be direct-only, but making that the +default might break some legacy applications. Hence, all app-defined +functions and vtabs go in as Normal, but the application can switch them +over to "Direct-Only" behavior using a single pragma. + +The restrictions on the use of functions and virtual tables do not apply +to TEMP. A TEMP VIEW or a TEMP TRIGGER can use any valid SQL function +or virtual table. The idea is that TEMP views and triggers must be +directly created by the application and are thus under the control of the +application. TEMP views and triggers cannot be created by an attacker who +corrupts the schema of a persistent database file. Hence TEMP views and +triggers are safe. + +## Specific changes + + 1. New sqlite3\_db\_config() option SQLITE\_DBCONFIG\_TRUSTED\_SCHEMA for + turning TRUSTED\_SCHEMA on and off. It defaults to ON. + + 2. Compile-time option -DSQLITE\_TRUSTED\_SCHEMA=0 causes the default + TRUSTED\_SCHEMA setting to be off. + + 3. New pragma "PRAGMA trusted\_schema=(ON\|OFF);". This provides access + to the TRUSTED_SCHEMA setting for application coded using scripting + languages or other secondary languages where they are unable to make + calls to sqlite3\_db\_config(). + + 4. New options for the "enc" parameter to sqlite3\_create\_function() and + its kin: +
    +
  1. _SQLITE\_INNOCUOUS_ → tags the new functions as Innocuous +
  2. _SQLITE\_DIRECTONLY_ → tags the new functions as Direct-Only +
+ + 5. New options to sqlite3\_vtab\_config(): +
    +
  1. _SQLITE\_VTAB\_INNOCUOUS_ → tags the vtab as Innocuous +
  2. _SQLITE\_VTAB\_DIRECTONLY_ → tags the vtab as Direct-Only +
+ + 6. Change many of the functions and virtual tables in the SQLite source + tree to use one of the tags above. + + 7. Enhanced PRAGMA function\_list and virtual-table "pragma\_function\_list" + with additional columns. The columns now are: +
    +
  • _name_ → Name of the function +
  • _builtin_ → 1 for built-in functions. 0 otherwise. +
  • _type_ → 's'=Scalar, 'a'=Aggregate, 'w'=Window +
  • _enc_ → 'utf8', 'utf16le', or 'utf16be' +
  • _narg_ → number of argument +
  • _flags_ → Bitmask of SQLITE\_INNOCUOUS, SQLITE\_DIRECTONLY, + SQLITE\_DETERMINISTIC, SQLITE\_SUBTYPE, and + SQLITE\_FUNC\_INTERNAL flags. +
+

The last four columns are new. + + 8. The function\_list PRAGMA now also shows all entries for each function. + So, for example, if a function can take either 2 or 3 arguments, + there are separate rows for the 2-argument and 3-argument versions of + the function. + +## Additional Notes + +The function_list enhancements allow the application to query the set +of SQL functions that meet various criteria. For example, to see all +SQL functions that are never allowed to be used in the schema or in +trigger or views: + +~~~ + SELECT DISTINCT name FROM pragma_function_list + WHERE (flags & 0x80000)!=0 + ORDER BY name; +~~~ + +Doing the same is not possible for virtual tables, as a virtual table +might be Innocuous, Normal, or Direct-Only depending on the arguments +passed into the xConnect method. diff --git a/manifest b/manifest index a4a0bd8da2..fbcbb2b31d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplified\serror\smessage\sfor\sthe\sunsafe\suse\sof\sa\svirtual\stable. -D 2020-01-09T13:08:28.875 +C Design\snotes\sfor\sthe\snew-security-options\sbranch. +D 2020-01-09T14:51:47.198 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -40,6 +40,7 @@ F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd F doc/lemon.html 24956ab2995e55fe171e55bdd04f22b553957dc8bb43501dbb9311e30187e0d3 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 +F doc/trusted-schema.md f6f680325d98cd3d2e60fc1b189c89bd91e7cf243a7538ddaaa77a9a85ecfc27 F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a F ext/README.md fd5f78013b0a2bc6f0067afb19e6ad040e89a10179b4f6f03eee58fac5f169bd F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91 @@ -1855,7 +1856,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 8878c40753566a8c4ccd1d413019cabde7569b947f730527d13bfc3db384e97d -R 0dd0572d840f5da124648f9c608f9c87 +P d662129a601e05e8fca5717a890b5bc920b80a750d061f3c2494788d32b917a5 +R e15da1979fa75b113b42a835dcf65862 U drh -Z 4a660a42e378fba2b6c64d3dce74af2a +Z 56f64c5778330d36d74ed745f5b7a873 diff --git a/manifest.uuid b/manifest.uuid index 47e32ca86f..40f122c7f0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d662129a601e05e8fca5717a890b5bc920b80a750d061f3c2494788d32b917a5 \ No newline at end of file +af7c1ed4f8a7293d0ecacca3cfbe9414e0de5ec40b418ce7831b8dc724feb747 \ No newline at end of file From 3858be3e599d174a8a9b3e68810578be551946ff Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 9 Jan 2020 15:18:08 +0000 Subject: [PATCH 20/22] Minor formatting changes in the trusted-schema.md document. FossilOrigin-Name: 55553b5e5ece8282f6a56a6f5c71024eaaef3c86ec42203af3da708b0de3643b --- doc/trusted-schema.md | 16 ++++++++-------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/doc/trusted-schema.md b/doc/trusted-schema.md index 32abf9d4d0..c552825eb2 100644 --- a/doc/trusted-schema.md +++ b/doc/trusted-schema.md @@ -22,9 +22,9 @@ maliciously corrupted by an attacker. The basic idea is to tag every SQL function and virtual table with one of three risk levels: - 1. Innocuous - 2. Normal - 3. Direct-Only + 1. Innocuous + 2. Normal + 3. Direct-Only Innocuous functions/vtabs are safe and can be used at any time. Direct-only elements, in contrast, might have cause side-effects and @@ -50,11 +50,11 @@ Direct-only elements that have side-effects that go outside the database file in which it lives, or return information from outside of the database file. Examples of direct-only elements include: - 1. The fts3_tokenizer() function - 2. The writefile() function - 3. The readfile() function - 4. The zipvfs virtual table - 5. The csv virtual table + 1. The fts3\_tokenizer() function + 2. The writefile() function + 3. The readfile() function + 4. The zipvfs virtual table + 5. The csv virtual table We do not want an attacker to be able to add these kinds of things to the database schema and possibly trick a high-privilege application diff --git a/manifest b/manifest index fbcbb2b31d..0261867caf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Design\snotes\sfor\sthe\snew-security-options\sbranch. -D 2020-01-09T14:51:47.198 +C Minor\sformatting\schanges\sin\sthe\strusted-schema.md\sdocument. +D 2020-01-09T15:18:08.637 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -40,7 +40,7 @@ F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd F doc/lemon.html 24956ab2995e55fe171e55bdd04f22b553957dc8bb43501dbb9311e30187e0d3 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 -F doc/trusted-schema.md f6f680325d98cd3d2e60fc1b189c89bd91e7cf243a7538ddaaa77a9a85ecfc27 +F doc/trusted-schema.md 85ce619aa1c7234931b7a9ee681ae1ebc781ade512a61ca03f0248f473c8dbaa F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a F ext/README.md fd5f78013b0a2bc6f0067afb19e6ad040e89a10179b4f6f03eee58fac5f169bd F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91 @@ -1856,7 +1856,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 d662129a601e05e8fca5717a890b5bc920b80a750d061f3c2494788d32b917a5 -R e15da1979fa75b113b42a835dcf65862 +P af7c1ed4f8a7293d0ecacca3cfbe9414e0de5ec40b418ce7831b8dc724feb747 +R b5a1b0709d80497117a6d5aa63bfc530 U drh -Z 56f64c5778330d36d74ed745f5b7a873 +Z 1bcdfac76412383a4c9029e5fef7a395 diff --git a/manifest.uuid b/manifest.uuid index 40f122c7f0..e4192f2c3c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -af7c1ed4f8a7293d0ecacca3cfbe9414e0de5ec40b418ce7831b8dc724feb747 \ No newline at end of file +55553b5e5ece8282f6a56a6f5c71024eaaef3c86ec42203af3da708b0de3643b \ No newline at end of file From 51ebd5fa14916c791f2bde20810d9eed107e0db5 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 9 Jan 2020 16:00:08 +0000 Subject: [PATCH 21/22] Fix minor typos in the trusted-schema.md document. FossilOrigin-Name: 87aea3ab1cdda4533e6fed605d1295e83bae0bbb9e1b238d239ce158a0d42954 --- doc/trusted-schema.md | 4 ++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/trusted-schema.md b/doc/trusted-schema.md index c552825eb2..d431fd49a3 100644 --- a/doc/trusted-schema.md +++ b/doc/trusted-schema.md @@ -32,11 +32,11 @@ should only be used from top-level SQL, not from within triggers or views nor in elements of the schema such as CHECK constraint, DEFAULT values, generated columns, index expressions, or in the WHERE clause of a partial index that are potentially under the control of an attacker. -Normal elements be have like Innocuous if TRUSTED\_SCHEMA=on +Normal elements behave like Innocuous if TRUSTED\_SCHEMA=on and behave like direct-only if TRUSTED\_SCHEMA=off. Application-defined functions and virtual tables go in as Normal unless -the application takes deliberate stesp to change the risk level. +the application takes deliberate steps to change the risk level. For backwards compatibility, the default is TRUSTED\_SCHEMA=on. Documentation will be updated to recommend applications turn TRUSTED\_SCHEMA to off. diff --git a/manifest b/manifest index 0261867caf..adf0883fee 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sformatting\schanges\sin\sthe\strusted-schema.md\sdocument. -D 2020-01-09T15:18:08.637 +C Fix\sminor\stypos\sin\sthe\strusted-schema.md\sdocument. +D 2020-01-09T16:00:08.934 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -40,7 +40,7 @@ F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd F doc/lemon.html 24956ab2995e55fe171e55bdd04f22b553957dc8bb43501dbb9311e30187e0d3 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 -F doc/trusted-schema.md 85ce619aa1c7234931b7a9ee681ae1ebc781ade512a61ca03f0248f473c8dbaa +F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a F ext/README.md fd5f78013b0a2bc6f0067afb19e6ad040e89a10179b4f6f03eee58fac5f169bd F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91 @@ -1856,7 +1856,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 af7c1ed4f8a7293d0ecacca3cfbe9414e0de5ec40b418ce7831b8dc724feb747 -R b5a1b0709d80497117a6d5aa63bfc530 +P 55553b5e5ece8282f6a56a6f5c71024eaaef3c86ec42203af3da708b0de3643b +R 36e30271b935c30d68186edc80f5a0f4 U drh -Z 1bcdfac76412383a4c9029e5fef7a395 +Z e885b154077129671d15d2a44722704d diff --git a/manifest.uuid b/manifest.uuid index e4192f2c3c..0ea17ec104 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -55553b5e5ece8282f6a56a6f5c71024eaaef3c86ec42203af3da708b0de3643b \ No newline at end of file +87aea3ab1cdda4533e6fed605d1295e83bae0bbb9e1b238d239ce158a0d42954 \ No newline at end of file From b84fda37efdd612288c1bc4933fa3ae6bcc2ffbc Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 9 Jan 2020 16:28:50 +0000 Subject: [PATCH 22/22] Fix a problem in the encoding display in the updated PRAGMA function_list. FossilOrigin-Name: 318ff7720bc60c30c0826becce424226e9cec25c1d59cb2cdb75793739322760 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pragma.c | 16 +++++++--------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index adf0883fee..82c579652b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sminor\stypos\sin\sthe\strusted-schema.md\sdocument. -D 2020-01-09T16:00:08.934 +C Fix\sa\sproblem\sin\sthe\sencoding\sdisplay\sin\sthe\supdated\sPRAGMA\sfunction_list. +D 2020-01-09T16:28:50.025 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -523,7 +523,7 @@ F src/parse.y c8d2de64db469fd56e0fa24da46cd8ec8523eb98626567d2708df371b47fdc3f F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a -F src/pragma.c 6e13c9a885c0f2effaa6a1155b707d3d3e39bc572c3b003ce4caa9c2e9010ca3 +F src/pragma.c 9145cc0d7309b49d383fe15deca9ab592830b8b532e7fb25e9e36b6f470cbf66 F src/pragma.h 9f86a3a3a0099e651189521c8ad03768df598974e7bbdc21c7f9bb6125592fbd F src/prepare.c 6049beb71385f017af6fc320d2c75a4e50b75e280c54232442b785fbb83df057 F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 @@ -1856,7 +1856,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 55553b5e5ece8282f6a56a6f5c71024eaaef3c86ec42203af3da708b0de3643b -R 36e30271b935c30d68186edc80f5a0f4 +P 87aea3ab1cdda4533e6fed605d1295e83bae0bbb9e1b238d239ce158a0d42954 +R a31dc2f4e3da7f138cd2121d67c1c563 U drh -Z e885b154077129671d15d2a44722704d +Z c76fa612566520f9cb4a404bd0c06588 diff --git a/manifest.uuid b/manifest.uuid index 0ea17ec104..d9bcdc87ad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -87aea3ab1cdda4533e6fed605d1295e83bae0bbb9e1b238d239ce158a0d42954 \ No newline at end of file +318ff7720bc60c30c0826becce424226e9cec25c1d59cb2cdb75793739322760 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 2c127ed5a7..9c292e1631 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -307,7 +307,6 @@ static void pragmaFunclistLine( ){ for(; p; p=p->pNext){ const char *zType; - const char *zEnc; static const u32 mask = SQLITE_DETERMINISTIC | SQLITE_DIRECTONLY | @@ -315,6 +314,12 @@ static void pragmaFunclistLine( SQLITE_INNOCUOUS | SQLITE_FUNC_INTERNAL ; + static const char *azEnc[] = { 0, "utf8", "utf16le", "utf16be" }; + + assert( SQLITE_FUNC_ENCMASK==0x3 ); + assert( strcmp(azEnc[SQLITE_UTF8],"utf8")==0 ); + assert( strcmp(azEnc[SQLITE_UTF16LE],"utf16le")==0 ); + assert( strcmp(azEnc[SQLITE_UTF16BE],"utf16be")==0 ); if( p->xSFunc==0 ) continue; if( (p->funcFlags & SQLITE_FUNC_INTERNAL)!=0 @@ -329,16 +334,9 @@ static void pragmaFunclistLine( }else{ zType = "s"; } - if( p->funcFlags & SQLITE_UTF8 ){ - zEnc = "utf8"; - }else if( p->funcFlags & SQLITE_UTF16BE ){ - zEnc = "utf16be"; - }else{ - zEnc = "utf16le"; - } sqlite3VdbeMultiLoad(v, 1, "sissii", p->zName, isBuiltin, - zType, zEnc, + zType, azEnc[p->funcFlags&SQLITE_FUNC_ENCMASK], p->nArg, (p->funcFlags & mask) ^ SQLITE_INNOCUOUS );