diff options
author | drh <drh@noemail.net> | 2018-11-03 16:09:59 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2018-11-03 16:09:59 +0000 |
commit | a296cda016dfcf81674b04c041637fa0a4f426ac (patch) | |
tree | cfd8eb3a5a7162130268f7bbabce562b4026e732 /src | |
parent | c6e519f335af83d8a816b4a0501ebd30f6057548 (diff) | |
download | sqlite-a296cda016dfcf81674b04c041637fa0a4f426ac.tar.gz sqlite-a296cda016dfcf81674b04c041637fa0a4f426ac.zip |
Add the SQLITE_DBCONFIG_DEFENSIVE flag.
FossilOrigin-Name: af3f29d49359af2291b1d9e06e0db76fd000fbd24b4ac84d2668a0d1322efd83
Diffstat (limited to 'src')
-rw-r--r-- | src/btree.c | 4 | ||||
-rw-r--r-- | src/build.c | 2 | ||||
-rw-r--r-- | src/dbpage.c | 4 | ||||
-rw-r--r-- | src/delete.c | 2 | ||||
-rw-r--r-- | src/main.c | 1 | ||||
-rw-r--r-- | src/shell.c.in | 1 | ||||
-rw-r--r-- | src/sqlite.h.in | 26 | ||||
-rw-r--r-- | src/sqliteInt.h | 1 |
8 files changed, 37 insertions, 4 deletions
diff --git a/src/btree.c b/src/btree.c index b4f3d73f6..9b2e43a9f 100644 --- a/src/btree.c +++ b/src/btree.c @@ -3112,7 +3112,9 @@ static int lockBtree(BtShared *pBt){ pageSize-usableSize); return rc; } - if( (pBt->db->flags & SQLITE_WriteSchema)==0 && nPage>nPageFile ){ + if( (pBt->db->flags & (SQLITE_WriteSchema|SQLITE_Defensive))==0 + && nPage>nPageFile + ){ rc = SQLITE_CORRUPT_BKPT; goto page1_init_failed; } diff --git a/src/build.c b/src/build.c index 2b73f4564..da72509da 100644 --- a/src/build.c +++ b/src/build.c @@ -806,7 +806,7 @@ int sqlite3TwoPartName( */ int sqlite3CheckObjectName(Parse *pParse, const char *zName){ if( !pParse->db->init.busy && pParse->nested==0 - && (pParse->db->flags & SQLITE_WriteSchema)==0 + && (pParse->db->flags & (SQLITE_WriteSchema|SQLITE_Defensive))==0 && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){ sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName); return SQLITE_ERROR; diff --git a/src/dbpage.c b/src/dbpage.c index 5b19abd35..a73ea01bd 100644 --- a/src/dbpage.c +++ b/src/dbpage.c @@ -313,6 +313,10 @@ static int dbpageUpdate( Pager *pPager; int szPage; + if( pTab->db->flags & SQLITE_Defensive ){ + zErr = "read-only"; + goto update_fail; + } if( argc==1 ){ zErr = "cannot delete"; goto update_fail; diff --git a/src/delete.c b/src/delete.c index 746f6725b..64e7639c1 100644 --- a/src/delete.c +++ b/src/delete.c @@ -63,7 +63,7 @@ int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){ if( ( IsVirtual(pTab) && sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 ) || ( (pTab->tabFlags & TF_Readonly)!=0 - && (pParse->db->flags & SQLITE_WriteSchema)==0 + && (pParse->db->flags & (SQLITE_WriteSchema|SQLITE_Defensive))==0 && pParse->nested==0 ) ){ sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName); diff --git a/src/main.c b/src/main.c index 8935a19d7..01d8bca86 100644 --- a/src/main.c +++ b/src/main.c @@ -835,6 +835,7 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){ { SQLITE_DBCONFIG_ENABLE_QPSG, SQLITE_EnableQPSG }, { SQLITE_DBCONFIG_TRIGGER_EQP, SQLITE_TriggerEQP }, { SQLITE_DBCONFIG_RESET_DATABASE, SQLITE_ResetDatabase }, + { SQLITE_DBCONFIG_DEFENSIVE, SQLITE_Defensive }, }; unsigned int i; rc = SQLITE_ERROR; /* IMP: R-42790-23372 */ diff --git a/src/shell.c.in b/src/shell.c.in index 4fcd93c01..177a948cb 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -5956,6 +5956,7 @@ static int do_meta_command(char *zLine, ShellState *p){ { "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG }, { "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP }, { "reset_database", SQLITE_DBCONFIG_RESET_DATABASE }, + { "defensive", SQLITE_DBCONFIG_DEFENSIVE }, }; int ii, v; open_db(p, 0); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 9ead2b7aa..18593a644 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2158,6 +2158,29 @@ struct sqlite3_mem_methods { ** Because resetting a database is destructive and irreversible, the ** process requires the use of this obscure API and multiple steps to help ** ensure that it does not happen by accident. +** +** <dt>SQLITE_DBCONFIG_DEFENSIVE</dt> +** <dd>The SQLITE_DBCONFIG_DEFENSIVE option actives or deactivates the +** "defensive" flag for a database connection. When the defensive +** flag is enabled, some obscure features of SQLite are disabled in order +** to reduce the attack surface. Applications that run untrusted SQL +** can activate this flag to reduce the risk of zero-day exploits. +** <p> +** Features disabled by the defensive flag include: +** <ul> +** <li>The [PRAGMA writable_schema=ON] statement. +** <li>Writes to the [sqlite_dbpage] virtual table. +** </ul> +** New restrictions may be added in future releases. +** <p> +** To be clear: It should never be possible for hostile SQL to cause +** arbitrary memory reads, memory leaks, buffer overflows, assertion +** faults, arbitrary code execution, crashes, or other mischief, regardless +** of the value of the defensive flag. Any occurrance of these problems +** is considered a serious bug and will be fixed promptly. It is not +** necessary to enable the defensive flag in order to make SQLite secure +** against attack. The defensive flag merely provides an additional layer +** of defense against unknown vulnerabilities. ** </dd> ** </dl> */ @@ -2171,7 +2194,8 @@ struct sqlite3_mem_methods { #define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */ #define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */ #define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */ -#define SQLITE_DBCONFIG_MAX 1009 /* Largest DBCONFIG */ +#define SQLITE_DBCONFIG_DEFENSIVE 1010 /* int int* */ +#define SQLITE_DBCONFIG_MAX 1010 /* Largest DBCONFIG */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 20db52de3..0482db21d 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1540,6 +1540,7 @@ struct sqlite3 { #define SQLITE_ResetDatabase 0x02000000 /* Reset the database */ #define SQLITE_LegacyAlter 0x04000000 /* Legacy ALTER TABLE behaviour */ #define SQLITE_NoSchemaError 0x08000000 /* Do not report schema parse errors*/ +#define SQLITE_Defensive 0x10000000 /* Input SQL is likely hostile */ /* Flags used only if debugging */ #define HI(X) ((u64)(X)<<32) |