]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Limit VIEW recursion depth to SQLITE_LIMIT_EXPR_DEPTH to prevent master
authordrh <>
Tue, 16 Jun 2026 13:43:08 +0000 (13:43 +0000)
committerdrh <>
Tue, 16 Jun 2026 13:43:08 +0000 (13:43 +0000)
static overflow in malicious schemas with tens of thousands of
levels of recursive views.
[bugs:/info/2026-06-16T04:21:51Z|Bug 2026-06-16T04:21:51Z]

FossilOrigin-Name: 3f3fb9b638f59ad982beafb7c117f24ddd3da612e62c862510805fa672ffae06

manifest
manifest.uuid
src/select.c
src/sqlite.h.in
src/sqliteInt.h
test/view.test

index 3b101b7ce0a1c3109f730c2a79392c303ffc158b..099218cd8459fa50cdc44b62711436a71667b40a 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sinstances\sof\spotential\sbuffer\soverflow\scaused\sby\sloading\sthe\scontents\sof\sa\sstat4\stable\swith\san\sabsurd\snumber\sof\ssamples\sin\sa\s32-bit\sbuild.\sBug\s[bugs:/info/2026-06-16T11:30:52Z\s|\s2026-06-16T11:30:52Z].
-D 2026-06-16T11:53:19.129
+C Limit\sVIEW\srecursion\sdepth\sto\sSQLITE_LIMIT_EXPR_DEPTH\sto\sprevent\s\nstatic\soverflow\sin\smalicious\sschemas\swith\stens\sof\sthousands\sof\nlevels\sof\srecursive\sviews.\n[bugs:/info/2026-06-16T04:21:51Z|Bug\s2026-06-16T04:21:51Z]
+D 2026-06-16T13:43:08.110
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -737,12 +737,12 @@ F src/printf.c 1b3d26ed8ea9a900317832625d5e83b833c7cf14640d7d98a2c235e172b6fefc
 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
 F src/resolve.c d0724113da9f5c0430d2052808ce59519f51ae7c4fbb1f5ef21fe3a832956086
 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
-F src/select.c 5c3a5e3c1e6c3f8ccabeb414e18dce64e6f3e797de225ee93034f2c9e76f289c
+F src/select.c 80ea6935f8470b97d1212bc1b759b7fadb28351797877f493d0cf598be1fef5e
 F src/shell.c.in a4e83895cfa336065ad7f7a7dea8fc2a19d050f7ce7466621c67208acaac9e44
-F src/sqlite.h.in 22674c0fc97b5ee21ace65b9bc1ed805dab35f433326d8022a642676c3b8a9d1
+F src/sqlite.h.in dec2ee22ff17cd37114367a957506ff15c6cae70511b9b61c50e4ed4d612190f
 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
 F src/sqlite3ext.h 9788c301f95370fa30e808861f1d2e6f022a816ddbe2a4f67486784c1b31db2e
-F src/sqliteInt.h 739dd1977fa694a8a39dd2b6e3d711b1cd9e350b8d6d3a9ebaf28d1cce7d3e0d
+F src/sqliteInt.h 1dcfbcc4419a7629c2e6b72aeeba283a48b17000e356b235680bdadc65b977cb
 F src/sqliteLimit.h c70656b67ab5b96741a8f1c812bdd80c81f2b1c1e443d0cc3ea8c33bb1f1a092
 F src/status.c 7565d63a79aa2f326339a24a0461a60096d0bd2bce711fefb50b5c89335f3592
 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@@ -1961,7 +1961,7 @@ F test/values.test 0e037c50789ac2a308746567d07b53b2f6026c1bb3a435d1b099424600e64
 F test/valuesfault.test 2ef23ed965e3bd08e268cdc38a0d11653390ddbbe1e8e2e98d16f55edd30f6e8
 F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62
 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
-F test/view.test 3c23d7a068e9e4a0c4e6907498042772adea725f0630c3d9638ffd4e5a08b92b
+F test/view.test 79cfd77b29ce49c172fee2ed9ec98d34924e70bebc75c8edb65f6a9bcd80d569
 F test/view2.test db32c8138b5b556f610b35dfddd38c5a58a292f07fda5281eedb0851b2672679
 F test/view3.test ad8a8290ee2b55ff6ce66c9ef1ce3f1e47926273a3814e1c425293e128a95456
 F test/vt02.c c2faf56d74470d569cd00741acb3f1719ee95d668f84ef58acc3872635789680
@@ -2208,8 +2208,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
 F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
 F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
-P 2063926473adaf9619ca10fd47b273ef59b1f77136836d575e5db3cfd68987da
-R d56c1c52306492a2482c7269f863986d
-U dan
-Z 2f0503d63ac48c50343b7b81029860f5
+P 0b72246732fecd7909add28f2d95f1727e1c4dc6c8f3b8e6e3482f6d17c92d34
+R 0aa2d61f35a87c7a58d6909964314503
+U drh
+Z 423360f46549491b114d6ada047fd081
 # Remove this line to create a well-formed Fossil manifest.
index 1393502c398d7375d20e837c502816410c0321ad..d8df050953c67524a4b10f097f30444fc3f0344e 100644 (file)
@@ -1 +1 @@
-0b72246732fecd7909add28f2d95f1727e1c4dc6c8f3b8e6e3482f6d17c92d34
+3f3fb9b638f59ad982beafb7c117f24ddd3da612e62c862510805fa672ffae06
index 2cdda672c3cfcab921d75b7ad359c686027f4d7d..4d181f121823032d32284569f9170909e18c9eee 100644 (file)
@@ -2441,6 +2441,13 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect, char aff){
   sqlite3 *db = pParse->db;
   u64 savedFlags;
 
+  pParse->nNestSel++;
+#if SQLITE_MAX_EXPR_DEPTH>0
+  if( pParse->nNestSel >= db->aLimit[SQLITE_LIMIT_EXPR_DEPTH] ){
+    sqlite3ErrorMsg(pParse, "VIEWs and/or subqueries nested too deep");
+    return 0;
+  }
+#endif
   savedFlags = db->flags;
   db->flags &= ~(u64)SQLITE_FullColNames;
   db->flags |= SQLITE_ShortColNames;
@@ -2462,6 +2469,8 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect, char aff){
     sqlite3DeleteTable(db, pTab);
     return 0;
   }
+  pParse->nNestSel--;
+  assert( pParse->nNestSel>=0 );
   return pTab;
 }
 
index 656ecef4dd96c6beb779ed90afaf5860940b7ae4..284cb5f36cedaa08b6f90b4d0d673212fc484377 100644 (file)
@@ -4377,7 +4377,8 @@ int sqlite3_limit(sqlite3*, int id, int newVal);
 ** or in an ORDER BY or GROUP BY clause.</dd>)^
 **
 ** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt>
-** <dd>The maximum depth of the parse tree on any expression.</dd>)^
+** <dd>The maximum depth of the parse tree on any expression and
+** the maximum nesting depth for subqueries and VIEWs</dd>)^
 **
 ** [[SQLITE_LIMIT_PARSER_DEPTH]] ^(<dt>SQLITE_LIMIT_PARSER_DEPTH</dt>
 ** <dd>The maximum depth of the LALR(1) parser stack used to analyze
@@ -4408,7 +4409,8 @@ int sqlite3_limit(sqlite3*, int id, int newVal);
 ** <dd>The maximum index number of any [parameter] in an SQL statement.)^
 **
 ** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt>
-** <dd>The maximum depth of recursion for triggers.</dd>)^
+** <dd>The maximum depth of recursion for triggers, and the maximum
+** nesting depth for separate triggers.</dd>)^
 **
 ** [[SQLITE_LIMIT_WORKER_THREADS]] ^(<dt>SQLITE_LIMIT_WORKER_THREADS</dt>
 ** <dd>The maximum number of auxiliary worker threads that a single
index d8676694ec9c02e002409091e3355e1b7443e3f6..12124e7d36f31afe416bf955ec0d52ac023adb35 100644 (file)
@@ -3919,6 +3919,7 @@ struct Parse {
   int szOpAlloc;       /* Bytes of memory space allocated for Vdbe.aOp[] */
   int iSelfTab;        /* Table associated with an index on expr, or negative
                        ** of the base register during check-constraint eval */
+  int nNestSel;        /* Number of nested SELECT statements and/or VIEWs */
   int nLabel;          /* The *negative* of the number of labels used */
   int nLabelAlloc;     /* Number of slots in aLabel */
   int *aLabel;         /* Space to hold the labels */
index 241742025cd4096f7606cdd7c9f2cda828e51895..5e21f31ee8a4713f2913e23f2bb46388167c6e33 100644 (file)
@@ -823,5 +823,35 @@ do_execsql_test view-31.2 {
   WITH s AS ( VALUES(123), (456) ) SELECT * FROM t3 WHERE b IN s;
 } {123 123}
 
+# Bug 2026-06-16T04:21:51Z
+#
+reset_db
+do_execsql_test view-32.1 {
+  CREATE TABLE t0(a);
+  INSERT INTO t0 VALUES(0);
+  CREATE VIEW v1(a) AS SELECT a+1 FROM t0;
+  CREATE VIEW v2(a) AS SELECT a+1 FROM v1;
+  CREATE VIEW v3(a) AS SELECT a+1 FROM v2;
+  CREATE VIEW v4(a) AS SELECT a+1 FROM v3;
+  CREATE VIEW v5(a) AS SELECT a+1 FROM v4;
+  CREATE VIEW v6(a) AS SELECT a+1 FROM v5;
+  CREATE VIEW v7(a) AS SELECT a+1 FROM v6;
+}
+if {[sqlite3_limit db SQLITE_LIMIT_EXPR_DEPTH -1]>0} {
+  sqlite3_limit db SQLITE_LIMIT_EXPR_DEPTH 7
+  do_catchsql_test view-32.2 {
+    SELECT * FROM v7;
+  } {1 {VIEWs and/or subqueries nested too deep}}
+  sqlite3_limit db SQLITE_LIMIT_EXPR_DEPTH 6
+  db cache flush
+  do_catchsql_test view-32.3 {
+    SELECT * FROM v7;
+  } {1 {VIEWs and/or subqueries nested too deep}}
+  sqlite3_limit db SQLITE_LIMIT_EXPR_DEPTH 8
+  db cache flush
+}
+do_execsql_test view-32.4 {
+  SELECT * FROM v7;
+} 7
 
 finish_test