CVE-2019-19603: Insufficient Information (NVD-CWE-noinfo)
value: SQLite 3.30.1 mishandles certain SELECT statements with a nonexistent VIEW, leading to an application crash.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
CVSS v3 base score: 7.5
Published: 2019-12-09T19:15Z
Repository: https://github.com/sqlite/sqlite
Language: Other
Files changed: manifest, manifest.uuid, src/build.c, src/sqliteInt.h, test/altertab.test
Commit date: 2019-11-16 14:15:19 +0000
Commit message: Do not allow CREATE TABLE or CREATE VIEW of an object with a name that looks
like a shadow table name.

FossilOrigin-Name: 6aef58b629d89955f85f65191ba2be67b2adfac4f0327fe9a7141cb2705dbc00
Diff: diff --git a/manifest b/manifest
index e59a0ca798..dc7ae2077e 100644
--- a/manifest
+++ b/manifest
@@ -1,7 +1,7 @@
-C Break\sout\sthe\stest\sfor\swritable\sshadow\stables\sinto\sa\sseparate\ssubroutine.
-D 2019-11-16T13:51:31.727
+C Do\snot\sallow\sCREATE\sTABLE\sor\sCREATE\sVIEW\sof\san\sobject\swith\sa\sname\sthat\slooks\nlike\sa\sshadow\stable\sname.
+D 2019-11-16T14:15:19.202
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
 F Makefile.in bf24a9abbb277afa2fbe6bac80a181f22be6c48de771cd260c9851ecf6165dc1
 F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241
@@ -468,11 +468,11 @@ F src/backup.c f70077d40c08b7787bfe934e4d1da8030cb0cc57d46b345fba2294b7d1be23ab
 F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
 F src/btree.c 12e251f8c3eaad05e6d0db94772bf779b3a644e18d884025da6bcbc98cad1d22
 F src/btree.h f27a33c49280209a93385e218306c4ee5f46ba8d7649d2f81a7166b282232484
 F src/btreeInt.h 91806f01fd1145a9a86ba3042f25c38d8faf6002701bf5e780742cf88bcff437
-F src/build.c 0001fed71cad92f94b3ed3ca38007de9cf61e1d48b209ba22feaeb606bbe6de1
+F src/build.c fe0b0b6dfab27a6f5778bd3dba8db879fda114c1d524a9597e5195ac55c8d01b
 F src/callback.c 88615dfc0a82167b65b452b4b305dbf86be77200b3343c6ffc6d03e92a01d181
 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
 F src/ctime.c 1b0724e66f95f33b160b1af85caaf9cceb325d22abf39bd24df4f54a73982251
 F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041
 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7
@@ -529,11 +529,11 @@ F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
 F src/select.c 50ccaf5fc3566b897fd3090b63bd60605f2f3f38ac5709fda6c482510d71aa6c
 F src/shell.c.in c06961f202f3cc50b819744b7331d3caea3d79d958402f4900b0668248557468
 F src/sqlite.h.in 95f50dc42fddab20064bf308c6756fcf2fdd84998dda15ae404a89c5c8d2cd10
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 72af51aa4e912e14cd495fb6e7fac65f0940db80ed950d90911aff292cc47ce2
-F src/sqliteInt.h 7bce951adf6bc8015accda3c204bc8da8127f7c8fa9e8684a9fcbf25e941206d
+F src/sqliteInt.h 98bc9562acfc361e34182aa25b00e2c73095732ddd3ba4158f984b94f5601f96
 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
 F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
 F src/tclsqlite.c 50c93be3e1c03b4e6cf6756e5197afcfe7f5cd0497d83a7ac317cde09e19b290
 F src/test1.c c654981c1d86ebc90dd23fcc0969e6c85e28112f0acc2e2224a97a2a33e7c42f
@@ -632,11 +632,11 @@ F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256b
 F test/alterauth2.test c0a1ddf5b93d93cb0d15ba7acaf0c5c6fb515bbe861ede75b2d3fabad33b6499
 F test/altercol.test 54374d2ba18af25bb24e23acf18a60270d4ec120b7ec0558078b59d5aa1a31ad
 F test/alterlegacy.test 82022721ce0de29cedc9a7af63bc9fcc078b0ee000f8283b4b6ea9c3eab2f44b
 F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9
 F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b
-F test/altertab.test 8069e5a8cbd3cb35732d3ec680dcc5273c2587ebd8e6a5d51084fa8059e468e5
+F test/altertab.test 4d8b79b0b88b62b90b710390df14fe99e0a3578345526886eaa550e28e3065dc
 F test/altertab2.test 8883693952f6d7fb5f754dbf1d694ed780aa883027bef04cb1fb99a3b88c9272
 F test/altertab3.test f40013d333e273da57e329fac6c2268a58aa09d17c3575936b343eeb2fa09180
 F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
 F test/analyze.test 547bb700f903107b38611b014ca645d6b5bb819f5210d7bf39c40802aafeb7d7
 F test/analyze3.test 01f0b122e3e54ad2544f14f7cc7dcb4c2cb8753cad5e88c6b8d49615b3fd6a2b
@@ -1847,12 +1847,9 @@ F vsixtest/pch.h 9cab7980f2ac4baa40807d8b5e52af32a21cf78c
 F vsixtest/vsixtest.sln 77cadbe4e96c1fe1bf51cd77de9e9b0a12ada547
 F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 70390bbca49e706649ca5b7c031f0baf416fc38798c17e5f3b73746b3e66e3b5
-R eb1e2d60d183f45db7dd5d6f1b4dd659
-T *branch * defensive-improvements
-T *sym-defensive-improvements *
-T -sym-trunk *
+P 8ad34d36a141fa8f5d9bd784dfeb892c983897a6dc6b867607cc668508acf944
+R eb081275a7e8dd518362d4efeb289e7e
 U drh
-Z 25e7114e721d6c257eca936cdc80fddc
+Z 5fd6ba2bd9359116ce6160036d7c9b86
diff --git a/manifest.uuid b/manifest.uuid
index dbc2eb9b26..476f2b2fe2 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-8ad34d36a141fa8f5d9bd784dfeb892c983897a6dc6b867607cc668508acf944
\ No newline at end of file
+6aef58b629d89955f85f65191ba2be67b2adfac4f0327fe9a7141cb2705dbc00
\ No newline at end of file
diff --git a/src/build.c b/src/build.c
index 05b753dbbc..e92596e4a3 100644
--- a/src/build.c
+++ b/src/build.c
@@ -854,17 +854,18 @@ int sqlite3CheckObjectName(
         sqlite3ErrorMsg(pParse, ""); /* corruptSchema() will supply the error */
         return SQLITE_ERROR;
       }
     }
   }else{
-    if( pParse->nested==0 
-     && 0==sqlite3StrNICmp(zName, "sqlite_", 7)
+    if( (pParse->nested==0 && 0==sqlite3StrNICmp(zName, "sqlite_", 7))
+     || (sqlite3ReadOnlyShadowTables(db) && sqlite3ShadowTableName(db, zName))
     ){
       sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s",
                       zName);
       return SQLITE_ERROR;
     }
+
   }
   return SQLITE_OK;
 }
 
 /*
@@ -2127,11 +2128,11 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
 ** connection.
 **
 ** zName is temporarily modified while this routine is running, but is
 ** restored to its original value prior to this routine returning.
 */
-static int isShadowTableName(sqlite3 *db, char *zName){
+int sqlite3ShadowTableName(sqlite3 *db, const char *zName){
   char *zTail;                  /* Pointer to the last "_" in zName */
   Table *pTab;                  /* Table that zName is a shadow of */
   Module *pMod;                 /* Module for the virtual table */
 
   zTail = strrchr(zName, '_');
@@ -2145,12 +2146,10 @@ static int isShadowTableName(sqlite3 *db, char *zName){
   if( pMod==0 ) return 0;
   if( pMod->pModule->iVersion<3 ) return 0;
   if( pMod->pModule->xShadowName==0 ) return 0;
   return pMod->pModule->xShadowName(zTail+1);
 }
-#else
-# define isShadowTableName(x,y) 0
 #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
 
 /*
 ** This routine is called to report the final ")" that terminates
 ** a CREATE TABLE statement.
@@ -2188,11 +2187,11 @@ void sqlite3EndTable(
   }
   assert( !db->mallocFailed );
   p = pParse->pNewTable;
   if( p==0 ) return;
 
-  if( pSelect==0 && isShadowTableName(db, p->zName) ){
+  if( pSelect==0 && sqlite3ShadowTableName(db, p->zName) ){
     p->tabFlags |= TF_Shadow;
   }
 
   /* If the db->init.busy is 1 it means we are reading the SQL off the
   ** "sqlite_master" or "sqlite_temp_master" table on the disk.
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 1ec1018a53..13800efbad 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -4546,10 +4546,15 @@ void sqlite3AutoLoadExtensions(sqlite3*);
      void(*)(void*)
    );
 #  define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
 #endif
 int sqlite3ReadOnlyShadowTables(sqlite3 *db);
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+  int sqlite3ShadowTableName(sqlite3 *db, const char *zName);
+#else
+# define sqlite3ShadowTableName(A,B) 0
+#endif
 int sqlite3VtabEponymousTableInit(Parse*,Module*);
 void sqlite3VtabEponymousTableClear(sqlite3*,Module*);
 void sqlite3VtabMakeWritable(Parse*,Table*);
 void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int);
 void sqlite3VtabFinishParse(Parse*, Token*);
diff --git a/test/altertab.test b/test/altertab.test
index 79b54272a0..3f0398fd5e 100644
--- a/test/altertab.test
+++ b/test/altertab.test
@@ -545,17 +545,33 @@ ifcapable fts3 {
   do_catchsql_test 16.10 {
     INSERT INTO y1_segments VALUES(1, X'1234567890');
   } {1 {table y1_segments may not be modified}}
 
   do_catchsql_test 16.20 {
-    ALTER TABLE y1_segments RENAME TO abc;
-  } {1 {table y1_segments may not be altered}}
-
-  do_catchsql_test 16.21 {
     DROP TABLE y1_segments;
   } {1 {table y1_segments may not be dropped}}
 
+  do_catchsql_test 16.20 {
+    ALTER TABLE y1_segments RENAME TO abc;
+  } {1 {table y1_segments may not be altered}}
+  sqlite3_db_config db DEFENSIVE 0
+  do_catchsql_test 16.22 {
+    ALTER TABLE y1_segments RENAME TO abc;
+  } {0 {}}
+  sqlite3_db_config db DEFENSIVE 1
+  do_catchsql_test 16.23 {
+    CREATE TABLE y1_segments AS SELECT * FROM abc;
+  } {1 {object name reserved for internal use: y1_segments}}
+  do_catchsql_test 16.24 {
+    CREATE VIEW y1_segments AS SELECT * FROM abc;
+  } {1 {object name reserved for internal use: y1_segments}}
+  sqlite3_db_config db DEFENSIVE 0
+  do_catchsql_test 16.25 {
+    ALTER TABLE abc RENAME TO y1_segments;
+  } {0 {}}
+  sqlite3_db_config db DEFENSIVE 1
+
   do_execsql_test 16.30 {
     ALTER TABLE y1 RENAME TO z1;
   }
 
   do_execsql_test 16.40 {

Vulnerable code: C Break\sout\sthe\stest\sfor\swritable\sshadow\stables\sinto\sa\sseparate\ssubroutine.
D 2019-11-16T13:51:31.727
F src/build.c 0001fed71cad92f94b3ed3ca38007de9cf61e1d48b209ba22feaeb606bbe6de1
F src/sqliteInt.h 7bce951adf6bc8015accda3c204bc8da8127f7c8fa9e8684a9fcbf25e941206d
F test/altertab.test 8069e5a8cbd3cb35732d3ec680dcc5273c2587ebd8e6a5d51084fa8059e468e5
P 70390bbca49e706649ca5b7c031f0baf416fc38798c17e5f3b73746b3e66e3b5
R eb1e2d60d183f45db7dd5d6f1b4dd659
T *branch * defensive-improvements
T *sym-defensive-improvements *
T -sym-trunk *
Z 25e7114e721d6c257eca936cdc80fddc
8ad34d36a141fa8f5d9bd784dfeb892c983897a6dc6b867607cc668508acf944
    if( pParse->nested==0 
     && 0==sqlite3StrNICmp(zName, "sqlite_", 7)
static int isShadowTableName(sqlite3 *db, char *zName){
#else
# define isShadowTableName(x,y) 0
  if( pSelect==0 && isShadowTableName(db, p->zName) ){
    ALTER TABLE y1_segments RENAME TO abc;
  } {1 {table y1_segments may not be altered}}

  do_catchsql_test 16.21 {
Fixed code: C Do\snot\sallow\sCREATE\sTABLE\sor\sCREATE\sVIEW\sof\san\sobject\swith\sa\sname\sthat\slooks\nlike\sa\sshadow\stable\sname.
D 2019-11-16T14:15:19.202
F src/build.c fe0b0b6dfab27a6f5778bd3dba8db879fda114c1d524a9597e5195ac55c8d01b
F src/sqliteInt.h 98bc9562acfc361e34182aa25b00e2c73095732ddd3ba4158f984b94f5601f96
F test/altertab.test 4d8b79b0b88b62b90b710390df14fe99e0a3578345526886eaa550e28e3065dc
P 8ad34d36a141fa8f5d9bd784dfeb892c983897a6dc6b867607cc668508acf944
R eb081275a7e8dd518362d4efeb289e7e
Z 5fd6ba2bd9359116ce6160036d7c9b86
6aef58b629d89955f85f65191ba2be67b2adfac4f0327fe9a7141cb2705dbc00
    if( (pParse->nested==0 && 0==sqlite3StrNICmp(zName, "sqlite_", 7))
     || (sqlite3ReadOnlyShadowTables(db) && sqlite3ShadowTableName(db, zName))

int sqlite3ShadowTableName(sqlite3 *db, const char *zName){
  if( pSelect==0 && sqlite3ShadowTableName(db, p->zName) ){
#ifndef SQLITE_OMIT_VIRTUALTABLE
  int sqlite3ShadowTableName(sqlite3 *db, const char *zName);
#else
# define sqlite3ShadowTableName(A,B) 0
#endif
  do_catchsql_test 16.20 {
    ALTER TABLE y1_segments RENAME TO abc;
  } {1 {table y1_segments may not be altered}}
  sqlite3_db_config db DEFENSIVE 0
  do_catchsql_test 16.22 {
    ALTER TABLE y1_segments RENAME TO abc;
  } {0 {}}
  sqlite3_db_config db DEFENSIVE 1
  do_catchsql_test 16.23 {
    CREATE TABLE y1_segments AS SELECT * FROM abc;
  } {1 {object name reserved for internal use: y1_segments}}
  do_catchsql_test 16.24 {
    CREATE VIEW y1_segments AS SELECT * FROM abc;
  } {1 {object name reserved for internal use: y1_segments}}
  sqlite3_db_config db DEFENSIVE 0
  do_catchsql_test 16.25 {
    ALTER TABLE abc RENAME TO y1_segments;
  } {0 {}}
  sqlite3_db_config db DEFENSIVE 1