]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the SQLITE_LIMIT_PRINTF_WIDTH setting for sqlite3_limit() and associated limit-printf-width
authordrh <drh@noemail.net>
Sat, 2 May 2015 18:25:25 +0000 (18:25 +0000)
committerdrh <drh@noemail.net>
Sat, 2 May 2015 18:25:25 +0000 (18:25 +0000)
logic for preventing DOS attacks using printf() with oversized widths or
precisions.

FossilOrigin-Name: f8b159794c3855cad86d755cc7422ddc21722200

manifest
manifest.uuid
src/func.c
src/main.c
src/printf.c
src/shell.c
src/sqlite.h.in
src/sqliteInt.h
src/sqliteLimit.h
src/test1.c

index dc584aea02f10d73c3faad9391d0d58723899d54..b35da2907df482e3dd95b8f56659988d80a3512a 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\sthe\s".limit"\scommand\sto\sthe\scommand-line\sshell.
-D 2015-05-02T17:40:23.555
+C Add\sthe\sSQLITE_LIMIT_PRINTF_WIDTH\ssetting\sfor\ssqlite3_limit()\sand\sassociated\nlogic\sfor\spreventing\sDOS\sattacks\susing\sprintf()\swith\soversized\swidths\sor\nprecisions.
+D 2015-05-02T18:25:25.099
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in e628c50e237251fc7e768bef14ee7e822ad69e69
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -185,7 +185,7 @@ F src/delete.c 37964e6c1d73ff49cbea9ff690c9605fb15f600e
 F src/expr.c 4c05a28eebe63b288fda1db0e8de556a82ca2ec6
 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
 F src/fkey.c c9b63a217d86582c22121699a47f22f524608869
-F src/func.c 5b8b8e77a0fb644eaf8947d413804622e32692b6
+F src/func.c 6b5a0c8364399c0ea6c5dda0e3ef662c4b789f6f
 F src/global.c 4f77cadbc5427d00139ba43d0f3979804cbb700e
 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
@@ -195,7 +195,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
 F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
 F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770
 F src/loadext.c 29255bbe1cfb2ce9bbff2526a5ecfddcb49b9271
-F src/main.c af89a158aa7bd40f6edef527c7b78ef581d72886
+F src/main.c 3fa53630047925acbba0a142c5ca11ce07e20645
 F src/malloc.c 6a370b83d54e4bbf6f94021221c2a311cff26a18
 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
 F src/mem1.c abe6ee469b6c5a35c7f22bfeb9c9bac664a1c987
@@ -226,21 +226,21 @@ F src/pcache1.c 69d137620a305f814398bd29a0c998038c0695e9
 F src/pragma.c c1f4d012ea9f6b1ce52d341b2cd0ad72d560afd7
 F src/pragma.h 09c89bca58e9a44de2116cc8272b8d454657129f
 F src/prepare.c 1fffbdcd6f8a0173a8f70d71f22528f4c0e1e3d3
-F src/printf.c 1f87c24770b2cea3fadbec03bfb6bdcbd353802c
+F src/printf.c c287c1cf15bffc79a2fab2a034da6f341baee869
 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
 F src/resolve.c 13109bc3b5ab404446296efa17039640de5bc35d
 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
 F src/select.c 5e83049a0be1caf88921e815d0118bce49cba827
-F src/shell.c b1e17be8565b5ce4138707d2808df077bf9750d9
-F src/sqlite.h.in ca27603a36fcacdaac5a19d8ee35aaff8ce8516f
+F src/shell.c e83273a73784f8abd344a433b65ea8b4fa133645
+F src/sqlite.h.in 08935b02c117fa3793b193324388befd77592ad3
 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
 F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
-F src/sqliteInt.h 20d9c59fd82774503b8953acfbcc6ecbdd9ee6aa
-F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
+F src/sqliteInt.h 42f804c1a065a4e204d126883bc9731fde6714de
+F src/sqliteLimit.h c647cd30d5228f520a754b46b6204586b6818f63
 F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179
 F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
 F src/tclsqlite.c 14f1992dd6100bfeb1a3dec7e7f449e1c814b8ee
-F src/test1.c 90fbedce75330d48d99eadb7d5f4223e86969585
+F src/test1.c 3cf9b20cc81580b61046628986db73ac1583f7ac
 F src/test2.c 577961fe48961b2f2e5c8b56ee50c3f459d3359d
 F src/test3.c 64d2afdd68feac1bb5e2ffb8226c8c639f798622
 F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e
@@ -1256,7 +1256,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 78c7ec95931265b89a92f6a799fc9b1a9f0476bf
-R b4e016ae5f2b9a1c3d3b22b5f2592000
+P 803cb60e75e0b09a526eefec11139cb3e8ae8c7c
+R 67f13f2b14c81a78caffdc6aae1db680
+T *branch * limit-printf-width
+T *sym-limit-printf-width *
+T -sym-trunk *
 U drh
-Z d46a3572f454bea0b6b400466ab43088
+Z 231851b453c464ec61b44da5b9128378
index 940f87c4fd943677179bb184c8ed59d5b4b0428c..0c7efa98ff13cf8d39e381b03de6d81960ac5489 100644 (file)
@@ -1 +1 @@
-803cb60e75e0b09a526eefec11139cb3e8ae8c7c
\ No newline at end of file
+f8b159794c3855cad86d755cc7422ddc21722200
\ No newline at end of file
index 62abf13d4d9afca6444c8727b93aa4125764d743..bcd658cefb22f67cafe9a2ded3baad818954ea93 100644 (file)
@@ -231,7 +231,6 @@ static void printfFunc(
   PrintfArguments x;
   StrAccum str;
   const char *zFormat;
-  int n;
   sqlite3 *db = sqlite3_context_db_handle(context);
 
   if( argc>=1 && (zFormat = (const char*)sqlite3_value_text(argv[0]))!=0 ){
@@ -240,9 +239,15 @@ static void printfFunc(
     x.apArg = argv+1;
     sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
     sqlite3XPrintf(&str, SQLITE_PRINTF_SQLFUNC, zFormat, &x);
-    n = str.nChar;
-    sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n,
+    sqlite3_result_text(context, sqlite3StrAccumFinish(&str), str.nChar,
                         SQLITE_DYNAMIC);
+    if( str.accError ){
+      if( str.accError==STRACCUM_NOMEM ){
+        sqlite3_result_error_nomem(context);
+      }else{
+        sqlite3_result_error_toobig(context);
+      }
+    }
   }
 }
 
index 69365b78485d4a351c4807df69a26460bea07a31..4b3878b650fc0b496fb2580b977120531d5202dd 100644 (file)
@@ -2288,6 +2288,7 @@ static const int aHardLimit[] = {
   SQLITE_MAX_VARIABLE_NUMBER,      /* IMP: R-38091-32352 */
   SQLITE_MAX_TRIGGER_DEPTH,
   SQLITE_MAX_WORKER_THREADS,
+  SQLITE_MAX_PRINTF_WIDTH,
 };
 
 /*
@@ -2366,7 +2367,8 @@ int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
   assert( aHardLimit[SQLITE_LIMIT_VARIABLE_NUMBER]==SQLITE_MAX_VARIABLE_NUMBER);
   assert( aHardLimit[SQLITE_LIMIT_TRIGGER_DEPTH]==SQLITE_MAX_TRIGGER_DEPTH );
   assert( aHardLimit[SQLITE_LIMIT_WORKER_THREADS]==SQLITE_MAX_WORKER_THREADS );
-  assert( SQLITE_LIMIT_WORKER_THREADS==(SQLITE_N_LIMIT-1) );
+  assert( aHardLimit[SQLITE_LIMIT_PRINTF_WIDTH]==SQLITE_MAX_PRINTF_WIDTH );
+  assert( SQLITE_LIMIT_PRINTF_WIDTH==(SQLITE_N_LIMIT-1) );
 
 
   if( limitId<0 || limitId>=SQLITE_N_LIMIT ){
@@ -2732,6 +2734,7 @@ static int openDatabase(
   assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
   memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
   db->aLimit[SQLITE_LIMIT_WORKER_THREADS] = SQLITE_DEFAULT_WORKER_THREADS;
+  db->aLimit[SQLITE_LIMIT_PRINTF_WIDTH] = 10000;
   db->autoCommit = 1;
   db->nextAutovac = -1;
   db->szMmap = sqlite3GlobalConfig.szMmap;
index 05f2ff5a6287739aa1da12df1bfe81e74480fbd3..54d80eef86691f8f7ba94e7debe0fc87bc6b5acd 100644 (file)
@@ -301,6 +301,16 @@ void sqlite3VXPrintf(
     }else{
       precision = -1;
     }
+
+    /* Check for over-size width or precision and error-out if found */
+    if( bArgList ){
+      int iLimit = pAccum->db->aLimit[SQLITE_LIMIT_PRINTF_WIDTH];
+      if( width>iLimit || precision>iLimit ){
+        setStrAccumError(pAccum, STRACCUM_TOOBIG);
+        return;
+      }
+    }
+
     /* Get the conversion type modifier */
     if( c=='l' ){
       flag_long = 1;
index 8b5695ac181c587f4ae9ac032c917d7e92ed1730..278a633741fd314e31e2273d9ff7daccd13302c3 100644 (file)
@@ -3189,6 +3189,7 @@ static int do_meta_command(char *zLine, ShellState *p){
       { "variable_number",       SQLITE_LIMIT_VARIABLE_NUMBER           },
       { "trigger_depth",         SQLITE_LIMIT_TRIGGER_DEPTH             },
       { "worker_threads",        SQLITE_LIMIT_WORKER_THREADS            },
+      { "printf_width",          SQLITE_LIMIT_PRINTF_WIDTH              },
     };
     int i, n2;
     open_db(p, 0);
index 163bc69fe73236268dc25400552be8239264948e..f7cd01cba4839ea0a7cf1a6d0c936daea7c7717d 100644 (file)
@@ -3190,6 +3190,17 @@ int sqlite3_limit(sqlite3*, int id, int newVal);
 ** [[SQLITE_LIMIT_WORKER_THREADS]] ^(<dt>SQLITE_LIMIT_WORKER_THREADS</dt>
 ** <dd>The maximum number of auxiliary worker threads that a single
 ** [prepared statement] may start.</dd>)^
+**
+** [[SQLITE_LIMIT_PRINTF_WIDTH]] ^(<dt>SQLITE_LIMIT_PRINTF_WIDTH</dt>
+** <dd>The maximum absolute value of the width or precision of a
+** format specifier in the [printf SQL function].)^  ^Any invocation of
+** the [printf SQL function] containing a width or precision larger than
+** this limit (or smaller than the negative of this limit) causes an
+** [SQLITE_TOOBIG] exception to be thrown.  <p>This limit applies
+** to the SQL function printf() only, and not to the various C-language
+** printf-style interfaces such as [sqlite3_mprintf()].  For the C-language
+** interfaces, the width and precision can be any 32-bit signed
+** integer.
 ** </dl>
 */
 #define SQLITE_LIMIT_LENGTH                    0
@@ -3204,6 +3215,7 @@ int sqlite3_limit(sqlite3*, int id, int newVal);
 #define SQLITE_LIMIT_VARIABLE_NUMBER           9
 #define SQLITE_LIMIT_TRIGGER_DEPTH            10
 #define SQLITE_LIMIT_WORKER_THREADS           11
+#define SQLITE_LIMIT_PRINTF_WIDTH             12
 
 /*
 ** CAPI3REF: Compiling An SQL Statement
index 7b9542a96ea8c70324234a426ca8cd7535195f25..b20a5f224016e3a9dba13913447d70a0af58835e 100644 (file)
@@ -1009,7 +1009,7 @@ struct Schema {
 ** The number of different kinds of things that can be limited
 ** using the sqlite3_limit() interface.
 */
-#define SQLITE_N_LIMIT (SQLITE_LIMIT_WORKER_THREADS+1)
+#define SQLITE_N_LIMIT (SQLITE_LIMIT_PRINTF_WIDTH+1)
 
 /*
 ** Lookaside malloc is a set of fixed-size buffers that can be used
index 75cad1274b4241ab579b1736fbf8c19b8409e9a3..a5d60373640122d327c3f6d72175eca65984ad5d 100644 (file)
 #ifndef SQLITE_MAX_TRIGGER_DEPTH
 # define SQLITE_MAX_TRIGGER_DEPTH 1000
 #endif
+
+/*
+** Maximum width or precision of a format specification in the SQL printf()
+** function.
+*/
+#ifndef SQLITE_MAX_PRINTF_WIDTH
+# define SQLITE_MAX_PRINTF_WIDTH 0x7fffffff
+#endif
index a87fcd859de0940e3dd7059432438b176ae2d3fb..00114e1f929100d4e10014c8640a0171708046fa 100644 (file)
@@ -5451,10 +5451,11 @@ static int test_limit(
     { "SQLITE_LIMIT_VARIABLE_NUMBER",     SQLITE_LIMIT_VARIABLE_NUMBER      },
     { "SQLITE_LIMIT_TRIGGER_DEPTH",       SQLITE_LIMIT_TRIGGER_DEPTH        },
     { "SQLITE_LIMIT_WORKER_THREADS",      SQLITE_LIMIT_WORKER_THREADS       },
+    { "SQLITE_LIMIT_PRINTF_WIDTH",        SQLITE_LIMIT_PRINTF_WIDTH         },
     
     /* Out of range test cases */
     { "SQLITE_LIMIT_TOOSMALL",            -1,                               },
-    { "SQLITE_LIMIT_TOOBIG",              SQLITE_LIMIT_WORKER_THREADS+1     },
+    { "SQLITE_LIMIT_TOOBIG",              SQLITE_LIMIT_PRINTF_WIDTH+1       },
   };
   int i, id = 0;
   int val;