diff --git a/manifest b/manifest
index 154ad7c55d..a06de3ef6e 100644
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C API\sChange:\sModify\ssqlite3_enable_load_extension()\sso\sthat\sit\sonly\nenables/disables\sthe\sload_extension()\sSQL\sfunction,\sand\sleaves\sthe\sC-APIs\nenabled\sat\sall\stimes.\s\sIn\sthis\sway,\sapplications\scan\senable\sextension\sloading\nfor\sthe\sC\sinterface\swithout\shaving\sto\sexpose\sthat\scapability\sto\sthe\sSQL.
-D 2016-04-20T00:30:05.107
+C Revert\ssqlite3_enable_load_extension()\sto\sits\soriginal\slong-standing\sbehavior.\nAdd\sSQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION\swhich\swill\senable\sonly\sthe\sC-API\sand\nleave\sthe\sSQL\sfunction\sdisabled.
+D 2016-04-21T01:30:09.828
F Makefile.in eba680121821b8a60940a81454316f47a341487a
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836
@@ -332,15 +332,15 @@ F src/delete.c 78eb999114ec04fcf1b7d123ccedb4b5b734930e
F src/expr.c 17d4e745ef6a3fd2e4ef863f5f9a4912f1ba1198
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb
-F src/func.c 2105701329de3fc2bf47c4153181d412f9f1531c
+F src/func.c b61726e7a1b8f41464d8391d0f2d8a6be1a45281
F src/global.c c45ea22aff29334f6a9ec549235ac3357c970015
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b
F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e
-F src/loadext.c 3f74ec102096acc2e33379c8379fced14b66858a
-F src/main.c 5ac9dccc03faadd6f867f67b9018ff41eeeadb46
+F src/loadext.c 8b3a73f0624c5f7cadbd5cb89940783bee1d39a6
+F src/main.c 405d13e3a4f7c5add9fb27702ae70ed0a6e32cca
F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
@@ -377,15 +377,15 @@ F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20
F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e
F src/select.c 30217121bdf6b587462150b8ee9e1467f7a6036b
F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6
-F src/sqlite.h.in 64eb70a3b309751bebf73a5552a51244f68f0ea5
+F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2
-F src/sqliteInt.h 49cd2b5cd07cca7c462608540cb6dfa8ab03ba89
+F src/sqliteInt.h ec538389481a3d093f07fb344c5a9dc988042304
F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9
F src/tclsqlite.c 9c4c4589d078de37813ded708d8838b338ffb060
-F src/test1.c 457c601302b8a0f5960dffd17b6a2877603841dd
+F src/test1.c abc10e3e81258835aeb59616685d7369ba99ad1e
F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b
F src/test3.c a8887dabbbee3059af338f20d290084a63ed1b0f
F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e
@@ -1482,10 +1482,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 eba27d4d17a76884292667d570d542e580ee3e77
-R 9873f5bcb700ee71f0df5e53b0b9f6e3
-T *branch * load-ext-security
-T *sym-load-ext-security *
-T -sym-trunk *
+P edb454e45ae008e051e2f48d704a855b0c3e4be9
+R 1ffd5268513054a5c042ef7eabb85336
U drh
-Z 9467a7a3e92ef67650d6a6e01e05bbf1
+Z 6cdb5487d5064dce1cac61ac30e9bbbf
diff --git a/manifest.uuid b/manifest.uuid
index 6aaf8e7765..5c2ea41ae7 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-edb454e45ae008e051e2f48d704a855b0c3e4be9
\ No newline at end of file
+b2ae5bfa32e608625bd177907596df3dbc2212e1
\ No newline at end of file
diff --git a/src/func.c b/src/func.c
index 17ca7ab9a8..651591d8c8 100644
--- a/src/func.c
+++ b/src/func.c
@@ -1386,13 +1386,10 @@ static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){
sqlite3 *db = sqlite3_context_db_handle(context);
char *zErrMsg = 0;
- /* Disallow the load_extension function unless the SQLITE_LoadExtension
+ /* Disallow the load_extension() SQL function unless the SQLITE_LoadExtFunc
** flag is set. See the sqlite3_enable_load_extension() API.
*/
- if( (db->flags & SQLITE_LoadExtension)==0 ){
- sqlite3_result_error(context, "not authorized", -1);
- return;
- }
+ if( (db->flags & SQLITE_LoadExtFunc)==0 ) return;
if( argc==2 ){
zProc = (const char *)sqlite3_value_text(argv[1]);
diff --git a/src/loadext.c b/src/loadext.c
index 7be43cb86d..f881d99710 100644
--- a/src/loadext.c
+++ b/src/loadext.c
@@ -460,7 +460,23 @@ static int sqlite3LoadExtension(
if( pzErrMsg ) *pzErrMsg = 0;
+
+ /* Ticket #1863. To avoid a creating security problems for older
+ ** applications that relink against newer versions of SQLite, the
+ ** ability to run load_extension is turned off by default. One
+ ** must call either sqlite3_enable_load_extension(db) or
+ ** sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, 0)
+ ** to turn on extension loading.
+ */
+ if( (db->flags & SQLITE_LoadExtension)==0 ){
+ if( pzErrMsg ){
+ *pzErrMsg = sqlite3_mprintf("not authorized");
+ }
+ return SQLITE_ERROR;
+ }
+
zEntry = zProc ? zProc : "sqlite3_extension_init";
+
handle = sqlite3OsDlOpen(pVfs, zFile);
#if SQLITE_OS_UNIX || SQLITE_OS_WIN
for(ii=0; iimutex);
if( onoff ){
- db->flags |= SQLITE_LoadExtension;
+ db->flags |= SQLITE_LoadExtension|SQLITE_LoadExtFunc;
}else{
- db->flags &= ~SQLITE_LoadExtension;
+ db->flags &= ~(SQLITE_LoadExtension|SQLITE_LoadExtFunc);
}
sqlite3_mutex_leave(db->mutex);
return SQLITE_OK;
diff --git a/src/main.c b/src/main.c
index 9f773667af..30370f8cab 100644
--- a/src/main.c
+++ b/src/main.c
@@ -804,6 +804,7 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){
{ SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys },
{ SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger },
{ SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer },
+ { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension },
};
unsigned int i;
rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index d50d826b41..795236f587 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -1932,12 +1932,30 @@ struct sqlite3_mem_methods {
** following this call. The second parameter may be a NULL pointer, in
** which case the new setting is not reported back.
**
+** SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION
+** ^This option is used to enable or disable the [sqlite3_load_extension()]
+** interface independently of the [load_extension()] SQL function.
+** The [sqlite3_enable_load_extension()] API enables or disables both the
+** C-API [sqlite3_load_extension()] and the SQL function [load_extension()].
+** There should be two additional arguments.
+** When the first argument to this interface is 1, then only the C-API is
+** enabled and the SQL function remains disabled. If the first argment to
+** this interface is 0, then both the C-API and the SQL function are disabled.
+** If the first argument is -1, then no changes are made to state of either the
+** C-API or the SQL function.
+** The second parameter is a pointer to an integer into which
+** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface
+** is disabled or enabled following this call. The second parameter may
+** be a NULL pointer, in which case the new setting is not reported back.
+**
+**
**
*/
#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
+#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
/*
@@ -5474,9 +5492,18 @@ int sqlite3_table_column_metadata(
** should free this memory by calling [sqlite3_free()].
**
** ^Extension loading must be enabled using
-** [sqlite3_enable_load_extension()] prior to calling this API,
+** [sqlite3_enable_load_extension()] or
+** [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],1,NULL)
+** prior to calling this API,
** otherwise an error will be returned.
**
+** Security warning: It is recommended that the
+** [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method be used to enable only this
+** interface. The use of the [sqlite3_enable_load_extension()] interface
+** should be avoided. This will keep the SQL function [load_extension()]
+** disabled and prevent SQL injections from giving attackers
+** access to extension loading capabilities.
+**
** See also the [load_extension() SQL function].
*/
int sqlite3_load_extension(
@@ -5499,6 +5526,17 @@ int sqlite3_load_extension(
** ^Call the sqlite3_enable_load_extension() routine with onoff==1
** to turn extension loading on and call it with onoff==0 to turn
** it back off again.
+**
+** ^This interface enables or disables both the C-API
+** [sqlite3_load_extension()] and the SQL function [load_extension()].
+** Use [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],..)
+** to enable or disable only the C-API.
+**
+** Security warning: It is recommended that extension loading
+** be disabled using the [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method
+** rather than this interface, so the [load_extension()] SQL function
+** remains disabled. This will prevent SQL injections from giving attackers
+** access to extension loading capabilities.
*/
int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index fe7203b8e1..7bb15d0bf5 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -1382,13 +1382,14 @@ struct sqlite3 {
#define SQLITE_AutoIndex 0x00100000 /* Enable automatic indexes */
#define SQLITE_PreferBuiltin 0x00200000 /* Preference to built-in funcs */
#define SQLITE_LoadExtension 0x00400000 /* Enable load_extension */
-#define SQLITE_EnableTrigger 0x00800000 /* True to enable triggers */
-#define SQLITE_DeferFKs 0x01000000 /* Defer all FK constraints */
-#define SQLITE_QueryOnly 0x02000000 /* Disable database changes */
-#define SQLITE_VdbeEQP 0x04000000 /* Debug EXPLAIN QUERY PLAN */
-#define SQLITE_Vacuum 0x08000000 /* Currently in a VACUUM */
-#define SQLITE_CellSizeCk 0x10000000 /* Check btree cell sizes on load */
-#define SQLITE_Fts3Tokenizer 0x20000000 /* Enable fts3_tokenizer(2) */
+#define SQLITE_LoadExtFunc 0x00800000 /* Enable load_extension() SQL func */
+#define SQLITE_EnableTrigger 0x01000000 /* True to enable triggers */
+#define SQLITE_DeferFKs 0x02000000 /* Defer all FK constraints */
+#define SQLITE_QueryOnly 0x04000000 /* Disable database changes */
+#define SQLITE_VdbeEQP 0x08000000 /* Debug EXPLAIN QUERY PLAN */
+#define SQLITE_Vacuum 0x10000000 /* Currently in a VACUUM */
+#define SQLITE_CellSizeCk 0x20000000 /* Check btree cell sizes on load */
+#define SQLITE_Fts3Tokenizer 0x40000000 /* Enable fts3_tokenizer(2) */
/*
diff --git a/src/test1.c b/src/test1.c
index 0c5af822c9..5478a72549 100644
--- a/src/test1.c
+++ b/src/test1.c
@@ -6988,6 +6988,7 @@ static int test_sqlite3_db_config(
{ "FKEY", SQLITE_DBCONFIG_ENABLE_FKEY },
{ "TRIGGER", SQLITE_DBCONFIG_ENABLE_TRIGGER },
{ "FTS3_TOKENIZER", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
+ { "LOAD_EXTENSION", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
};
int i;
int v;