Blame SOURCES/sqlite-3.26.0-CVE-2019-19603.patch

113387
Subject: [PATCH]  Do not allow CREATE TABLE or CREATE VIEW of an object with a name
113387
 that looks like a shadow table name.
113387
113387
diff --git a/src/build.c b/src/build.c
113387
index 3412670..f273394 100644
113387
--- a/src/build.c
113387
+++ b/src/build.c
113387
@@ -814,6 +814,22 @@ int sqlite3WritableSchema(sqlite3 *db){
113387
   return (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==SQLITE_WriteSchema;
113387
 }
113387
 
113387
+/*
113387
+** Return TRUE if shadow tables should be read-only in the current
113387
+** context.
113387
+*/
113387
+int sqlite3ReadOnlyShadowTables(sqlite3 *db){
113387
+#ifndef SQLITE_OMIT_VIRTUALTABLE
113387
+  if( (db->flags & SQLITE_Defensive)!=0
113387
+   && db->pVtabCtx==0
113387
+   && db->nVdbeExec==0
113387
+  ){
113387
+    return 1;
113387
+  }
113387
+#endif
113387
+  return 0;
113387
+}
113387
+
113387
 /*
113387
 ** This routine is used to check if the UTF-8 string zName is a legal
113387
 ** unqualified name for a new schema object (table, index, view or
113387
@@ -822,9 +838,10 @@ int sqlite3WritableSchema(sqlite3 *db){
113387
 ** is reserved for internal use.
113387
 */
113387
 int sqlite3CheckObjectName(Parse *pParse, const char *zName){
113387
-  if( !pParse->db->init.busy && pParse->nested==0 
113387
+  if(( !pParse->db->init.busy && pParse->nested==0 
113387
           && sqlite3WritableSchema(pParse->db)==0
113387
-          && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
113387
+          && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ) ||
113387
+          (sqlite3ReadOnlyShadowTables(pParse->db) && sqlite3ShadowTableName(pParse->db, zName))){
113387
     sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName);
113387
     return SQLITE_ERROR;
113387
   }
113387
@@ -1929,7 +1946,7 @@ int sqlite3IsShadowTableOf(sqlite3 *db, Table *pTab, const char *zName){
113387
 ** zName is temporarily modified while this routine is running, but is
113387
 ** restored to its original value prior to this routine returning.
113387
 */
113387
-static int isShadowTableName(sqlite3 *db, char *zName){
113387
+int sqlite3ShadowTableName(sqlite3 *db, const char *zName){
113387
   char *zTail;                  /* Pointer to the last "_" in zName */
113387
   Table *pTab;                  /* Table that zName is a shadow of */
113387
 
113387
@@ -1942,8 +1959,6 @@ static int isShadowTableName(sqlite3 *db, char *zName){
113387
   if( !IsVirtual(pTab) ) return 0;
113387
   return sqlite3IsShadowTableOf(db, pTab, zName);
113387
 }
113387
-#else
113387
-# define isShadowTableName(x,y) 0
113387
 #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
113387
 
113387
 /*
113387
@@ -1985,7 +2000,7 @@ void sqlite3EndTable(
113387
   p = pParse->pNewTable;
113387
   if( p==0 ) return;
113387
 
113387
-  if( pSelect==0 && isShadowTableName(db, p->zName) ){
113387
+  if( pSelect==0 && sqlite3ShadowTableName(db, p->zName) ){
113387
     p->tabFlags |= TF_Shadow;
113387
   }
113387
 
113387
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
113387
index 60b2ebd..e5ba8a0 100644
113387
--- a/src/sqliteInt.h
113387
+++ b/src/sqliteInt.h
113387
@@ -4408,6 +4408,11 @@ void sqlite3AutoLoadExtensions(sqlite3*);
113387
    );
113387
 #  define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
113387
 #endif
113387
+#ifndef SQLITE_OMIT_VIRTUALTABLE
113387
+  int sqlite3ShadowTableName(sqlite3 *db, const char *zName);
113387
+#else
113387
+# define sqlite3ShadowTableName(A,B) 0
113387
+#endif
113387
 #ifndef SQLITE_OMIT_VIRTUALTABLE
113387
   int sqlite3IsShadowTableOf(sqlite3*,Table*,const char*);
113387
 #else
113387
diff --git a/test/altertab.test b/test/altertab.test
113387
index 891b081..0705abc 100644
113387
--- a/test/altertab.test
113387
+++ b/test/altertab.test
113387
@@ -547,13 +547,29 @@ ifcapable fts3 {
113387
   } {1 {table y1_segments may not be modified}}
113387
 
113387
   do_catchsql_test 16.20 {
113387
-    ALTER TABLE y1_segments RENAME TO abc;
113387
-  } {1 {table y1_segments may not be altered}}
113387
-
113387
-  do_catchsql_test 16.21 {
113387
     DROP TABLE y1_segments;
113387
   } {1 {table y1_segments may not be dropped}}
113387
 
113387
+  do_catchsql_test 16.20 {
113387
+    ALTER TABLE y1_segments RENAME TO abc;
113387
+  } {1 {table y1_segments may not be altered}}
113387
+  sqlite3_db_config db DEFENSIVE 0
113387
+  do_catchsql_test 16.22 {
113387
+    ALTER TABLE y1_segments RENAME TO abc;
113387
+  } {0 {}}
113387
+  sqlite3_db_config db DEFENSIVE 1
113387
+  do_catchsql_test 16.23 {
113387
+    CREATE TABLE y1_segments AS SELECT * FROM abc;
113387
+  } {1 {object name reserved for internal use: y1_segments}}
113387
+  do_catchsql_test 16.24 {
113387
+    CREATE VIEW y1_segments AS SELECT * FROM abc;
113387
+  } {1 {object name reserved for internal use: y1_segments}}
113387
+  sqlite3_db_config db DEFENSIVE 0
113387
+  do_catchsql_test 16.25 {
113387
+    ALTER TABLE abc RENAME TO y1_segments;
113387
+  } {0 {}}
113387
+  sqlite3_db_config db DEFENSIVE 1
113387
+
113387
   do_execsql_test 16.30 {
113387
     ALTER TABLE y1 RENAME TO z1;
113387
   }