CVE-2019-19924: Improper Handling of Exceptional Conditions (CWE-755)
value: SQLite 3.30.1 mishandles certain parser-tree rewriting, related to expr.c, vdbeaux.c, and window.c. This is caused by incorrect sqlite3WindowRewrite() error handling.
CWE description: The product does not handle or incorrectly handles an exceptional condition.
CVSS v3 base score: 5.3
Published: 2019-12-24T16:15Z
Repository: https://github.com/sqlite/sqlite
Language: C
Files changed: manifest, manifest.uuid, src/expr.c, src/vdbeaux.c, src/window.c
Commit date: 2019-12-19 20:37:32 +0000
Commit message: When an error occurs while rewriting the parser tree for window functions
in the sqlite3WindowRewrite() routine, make sure that pParse->nErr is set,
and make sure that this shuts down any subsequent code generation that might
depend on the transformations that were implemented.  This fixes a problem
discovered by the Yongheng and Rui fuzzer.

FossilOrigin-Name: e2bddcd4c55ba3cbe0130332679ff4b048630d0ced9a8899982edb5a3569ba7f
Diff: diff --git a/manifest b/manifest
index 6e61b4d4f1d..f741b1369ee 100644
--- a/manifest
+++ b/manifest
@@ -1,7 +1,7 @@
-C Detect\sthe\sinvalid\suse\sof\sNULLS\sLAST\son\san\sINTEGER\sPRIMARY\sKEY\sdefinition\nof\sa\sWITHOUT\sROWID\stable.
-D 2019-12-19T17:42:27.314
+C When\san\serror\soccurs\swhile\srewriting\sthe\sparser\stree\sfor\swindow\sfunctions\nin\sthe\ssqlite3WindowRewrite()\sroutine,\smake\ssure\sthat\spParse->nErr\sis\sset,\nand\smake\ssure\sthat\sthis\sshuts\sdown\sany\ssubsequent\scode\sgeneration\sthat\smight\ndepend\son\sthe\stransformations\sthat\swere\simplemented.\s\sThis\sfixes\sa\sproblem\ndiscovered\sby\sthe\sYongheng\sand\sRui\sfuzzer.
+D 2019-12-19T20:37:32.070
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
 F Makefile.in d3a862c9742f5a08230a3b295c0a47fd3067f19356dc39935280135f90474b04
 F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241
@@ -477,11 +477,11 @@ F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
 F src/ctime.c 1b0724e66f95f33b160b1af85caaf9cceb325d22abf39bd24df4f54a73982251
 F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041
 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7
 F src/dbstat.c 6c407e549406c10fde9ac3987f6d734459205239ad370369bc5fcd683084a4fa
 F src/delete.c a5c59b9c0251cf7682bc52af0d64f09b1aefc6781a63592c8f1136f7b73c66e4
-F src/expr.c 8f873d6a411483a0ba14367aebf63c1f9f4346ef755739ec11feb14fa662002d
+F src/expr.c 5099de2d6cca77f7c3b5131e0035787fc64ca3d27c267020e7e8bec0e226336c
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
 F src/fkey.c 92a248ec0fa4ed8ab60c98d9b188ce173aaf218f32e7737ba77deb2a684f9847
 F src/func.c ed33e38cd642058182a31a3f518f2e34f4bbe53aa483335705c153c4d3e50b12
 F src/global.c a1a8d698762ddd9a1543aac26c1e0029b20fcc3fcb56bfa41ec8cea2368f2798
 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
@@ -601,11 +601,11 @@ F src/util.c 2c92bc706bbdb1c45a25180291e7e05a56e297aa5dd7b2bcd2b1c47e8bb05b17
 F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf
 F src/vdbe.c ab3f6e647235fe4fa16b71496468313a1da435eb3a2125c3ffdbb0be0d1cbcba
 F src/vdbe.h fdbc0a11e5768a702b46ce63286f60e22e71351a29bd98b3666405e1fccc7802
 F src/vdbeInt.h bd589b8b7273286858950717e0e1ec5c88b18af45079a3366dc1371865cea704
 F src/vdbeapi.c 1252d80c548711e47a6d84dae88ed4e95d3fbb4e7bd0eaa1347299af7efddf02
-F src/vdbeaux.c ede199fe272656338741dd831da86362a3b60e42fb12ef5389ea1325823e9686
+F src/vdbeaux.c 858bb43a9d98846cc23fa8c8d0970ada805dd75bc6a01b69e972da608f7f59b1
 F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1
 F src/vdbemem.c 2eb00a4d1a7d2c97510a4d1ccaf4e12c9143f2ced1c6b96b5eddc372183c9121
 F src/vdbesort.c a3be032cc3fee0e3af31773af4a7a6f931b7230a34f53282ccf1d9a2a72343be
 F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0
 F src/vtab.c 2736f853a1bd270581f76bae8e5d2e840b6258f3d85c1fa382e9454b3c414d1d
@@ -615,11 +615,11 @@ F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a
 F src/walker.c a137468bf36c92e64d2275caa80c83902e3a0fc59273591b96c6416d3253d05d
 F src/where.c c51ebd505c8417285ca1db8f94933a12224bf636ad93f27d821c07f93d59c035
 F src/whereInt.h 4a296fd4fa79fdcbc2b5e8c1b898901617655811223e1082b899c23ecb092217
 F src/wherecode.c 7efa97f4dc2f95548611deba68f0210ab357725899a9bae5391a525e48271875
 F src/whereexpr.c 39b6a538804c6e1248c22b33e09d00f89ae6a099c849c4d841ce3995562287b4
-F src/window.c 913a10696f5197adae32738a7c7cabc03e1f1553240d6c9ce868ee57f5cee88e
+F src/window.c da010455914c81037dcb5b0c6f4273f8a32c94567865c46a60060b937b018a96
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
 F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 F test/aggnested.test 12106f0748e8e9bfc1a8e6840e203e051eae06a26ed13fc9fd5db108a8d6db54
@@ -1850,9 +1850,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 a80f84b511231204658304226de3e075a55afc2e3f39ac063716f7a57f585c06
-R 7a95b86f1a40201b7706c8c6219ee188
+P 4417c5bf0aabb34ed174f01afd981c924ae965a42128719d8d6735536631d12f
+R f9500979ead80e4e63134871bf8fc127
 U drh
-Z a9ed89712b19f96611f174486447a3a5
+Z b61065dbf7c71aac52e79a354be5735d
diff --git a/manifest.uuid b/manifest.uuid
index 7dcbbe2a5c5..741caa8d4e8 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-4417c5bf0aabb34ed174f01afd981c924ae965a42128719d8d6735536631d12f
\ No newline at end of file
+e2bddcd4c55ba3cbe0130332679ff4b048630d0ced9a8899982edb5a3569ba7f
\ No newline at end of file
diff --git a/src/expr.c b/src/expr.c
index 2aef5756793..6ea8ff73f09 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -374,10 +374,11 @@ static int codeCompare(
 ){
   int p5;
   int addr;
   CollSeq *p4;
 
+  if( pParse->nErr ) return 0;
   if( isCommuted ){
     p4 = sqlite3BinaryCompareCollSeq(pParse, pRight, pLeft);
   }else{
     p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight);
   }
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index 311be9af9f5..8b9488e9e79 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -1301,11 +1301,12 @@ void sqlite3VdbeSetP4KeyInfo(Parse *pParse, Index *pIdx){
 ** makes the code easier to read during debugging.  None of this happens
 ** in a production build.
 */
 static void vdbeVComment(Vdbe *p, const char *zFormat, va_list ap){
   assert( p->nOp>0 || p->aOp==0 );
-  assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed );
+  assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed
+          || p->pParse->nErr>0 );
   if( p->nOp ){
     assert( p->aOp );
     sqlite3DbFree(p->db, p->aOp[p->nOp-1].zComment);
     p->aOp[p->nOp-1].zComment = sqlite3VMPrintf(p->db, zFormat, ap);
   }
diff --git a/src/window.c b/src/window.c
index 1f1c57f0684..f4e12f5fdbc 100644
--- a/src/window.c
+++ b/src/window.c
@@ -932,11 +932,11 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
     Window *pWin;                 /* Window object iterator */
     Table *pTab;
 
     pTab = sqlite3DbMallocZero(db, sizeof(Table));
     if( pTab==0 ){
-      return SQLITE_NOMEM;
+      return sqlite3ErrorToParser(db, SQLITE_NOMEM);
     }
 
     p->pSrc = 0;
     p->pWhere = 0;
     p->pGroupBy = 0;
@@ -1037,10 +1037,14 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
     }
     if( db->mallocFailed ) rc = SQLITE_NOMEM;
     sqlite3DbFree(db, pTab);
   }
 
+  if( rc && pParse->nErr==0 ){
+    assert( pParse->db->mallocFailed );
+    return sqlite3ErrorToParser(pParse->db, SQLITE_NOMEM);
+  }
   return rc;
 }
 
 /*
 ** Unlink the Window object from the Select to which it is attached,

Vulnerable code: C Detect\sthe\sinvalid\suse\sof\sNULLS\sLAST\son\san\sINTEGER\sPRIMARY\sKEY\sdefinition\nof\sa\sWITHOUT\sROWID\stable.
D 2019-12-19T17:42:27.314
F src/expr.c 8f873d6a411483a0ba14367aebf63c1f9f4346ef755739ec11feb14fa662002d
F src/vdbeaux.c ede199fe272656338741dd831da86362a3b60e42fb12ef5389ea1325823e9686
F src/window.c 913a10696f5197adae32738a7c7cabc03e1f1553240d6c9ce868ee57f5cee88e
P a80f84b511231204658304226de3e075a55afc2e3f39ac063716f7a57f585c06
R 7a95b86f1a40201b7706c8c6219ee188
Z a9ed89712b19f96611f174486447a3a5
4417c5bf0aabb34ed174f01afd981c924ae965a42128719d8d6735536631d12f
  assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed );
      return SQLITE_NOMEM;
Fixed code: C When\san\serror\soccurs\swhile\srewriting\sthe\sparser\stree\sfor\swindow\sfunctions\nin\sthe\ssqlite3WindowRewrite()\sroutine,\smake\ssure\sthat\spParse->nErr\sis\sset,\nand\smake\ssure\sthat\sthis\sshuts\sdown\sany\ssubsequent\scode\sgeneration\sthat\smight\ndepend\son\sthe\stransformations\sthat\swere\simplemented.\s\sThis\sfixes\sa\sproblem\ndiscovered\sby\sthe\sYongheng\sand\sRui\sfuzzer.
D 2019-12-19T20:37:32.070
F src/expr.c 5099de2d6cca77f7c3b5131e0035787fc64ca3d27c267020e7e8bec0e226336c
F src/vdbeaux.c 858bb43a9d98846cc23fa8c8d0970ada805dd75bc6a01b69e972da608f7f59b1
F src/window.c da010455914c81037dcb5b0c6f4273f8a32c94567865c46a60060b937b018a96
P 4417c5bf0aabb34ed174f01afd981c924ae965a42128719d8d6735536631d12f
R f9500979ead80e4e63134871bf8fc127
Z b61065dbf7c71aac52e79a354be5735d
e2bddcd4c55ba3cbe0130332679ff4b048630d0ced9a8899982edb5a3569ba7f
  if( pParse->nErr ) return 0;
  assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed
          || p->pParse->nErr>0 );
      return sqlite3ErrorToParser(db, SQLITE_NOMEM);
  if( rc && pParse->nErr==0 ){
    assert( pParse->db->mallocFailed );
    return sqlite3ErrorToParser(pParse->db, SQLITE_NOMEM);
  }