]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Limit VIEW recursion depth to SQLITE_LIMIT_EXPR_DEPTH to prevent
authordrh <>
Tue, 16 Jun 2026 13:46:54 +0000 (13:46 +0000)
committerdrh <>
Tue, 16 Jun 2026 13:46:54 +0000 (13:46 +0000)
static overflow in malicious schemas with tens of thousands of
levels of recursive views.

FossilOrigin-Name: 38430aa5ed787ab8d24cc4d7f03b5528168e12b1f59ecfce9c471cd755b81cc7

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

index fdad8f6dfd4ed0d3c26d96d0c0527452b2d4b46f..acf3dc03ec27a173d1e6457542d2300d92d3e246 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.
-D 2026-06-16T12:02:02.780
+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.
+D 2026-06-16T13:46:54.341
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -735,12 +735,12 @@ F src/printf.c ed43bcd6b551b590e47b905115aa1c35504267f532680590102e79894230a06b
 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
 F src/resolve.c f5a780a7b604d43b78bca290cace7479bca0c7d8ef9ce855830d9498b975baec
 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
-F src/select.c 5c3a5e3c1e6c3f8ccabeb414e18dce64e6f3e797de225ee93034f2c9e76f289c
+F src/select.c 80ea6935f8470b97d1212bc1b759b7fadb28351797877f493d0cf598be1fef5e
 F src/shell.c.in a92f97101ecc324d7235e28d72bdea681e437aab5e35e450d9572f67461da268
-F src/sqlite.h.in e2915e4a86d5e0783afb5cb72411df38d987c7f3c5aa2d5441b8e74d30b649d8
+F src/sqlite.h.in 17f32e2b049e704f85a27a6571917c05e6f3c812ee867eb0ba5614ee9cb566cd
 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
 F src/sqlite3ext.h 1b7a0ee438bb5c2896d0609c537e917d8057b3340f6ad004d2de44f03e3d3cca
-F src/sqliteInt.h 95f11ae70b1de7821bd1a94174408fdb72b0c5d1385db3466201fe758fb01823
+F src/sqliteInt.h 81a62711771f8efad807ece174c8482e100c0e47dd5a57339eab61fa0a77797a
 F src/sqliteLimit.h c70656b67ab5b96741a8f1c812bdd80c81f2b1c1e443d0cc3ea8c33bb1f1a092
 F src/status.c 7565d63a79aa2f326339a24a0461a60096d0bd2bce711fefb50b5c89335f3592
 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@@ -1954,7 +1954,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
@@ -2200,9 +2200,9 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
 F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
 F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
-P b22709dcb3d967e1ad9a8c0bd0ab7335efda0933d643e734d24e8cfc79325249
-Q +0b72246732fecd7909add28f2d95f1727e1c4dc6c8f3b8e6e3482f6d17c92d34
-R 4561d5a0f4416daf104323f423433062
+P c25ac7af868864f9ec05118c3b8f645e9db00d3c7e6963801fc2489e57218e2b
+Q +3f3fb9b638f59ad982beafb7c117f24ddd3da612e62c862510805fa672ffae06
+R dfec3f958a487ea1d36b9999bd340916
 U drh
-Z 0489565c8d0942b96c5c84117821f449
+Z fd03e59e25d26f052627ca1e8d22364e
 # Remove this line to create a well-formed Fossil manifest.
index c0a0acfae690b8a9544fe7d9c824c308077db63b..7b5a6ad1af27c33e0ff40250dabf67c62ee18956 100644 (file)
@@ -1 +1 @@
-c25ac7af868864f9ec05118c3b8f645e9db00d3c7e6963801fc2489e57218e2b
+38430aa5ed787ab8d24cc4d7f03b5528168e12b1f59ecfce9c471cd755b81cc7
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 9323ce5eeae50703b00139ab0f91409c67149b71..3d66f25d91a5ea0466ae572c55ce17e70d234ee6 100644 (file)
@@ -4366,7 +4366,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
@@ -4397,7 +4398,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 56b96b1a67b07fc0b4b1e12c489414c639f935c4..093cb1a548e222edce7fc05e46375b09742734e8 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