From: drh Date: Sat, 2 May 2015 18:25:25 +0000 (+0000) Subject: Add the SQLITE_LIMIT_PRINTF_WIDTH setting for sqlite3_limit() and associated X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fheads%2Flimit-printf-width;p=thirdparty%2Fsqlite.git Add the SQLITE_LIMIT_PRINTF_WIDTH setting for sqlite3_limit() and associated logic for preventing DOS attacks using printf() with oversized widths or precisions. FossilOrigin-Name: f8b159794c3855cad86d755cc7422ddc21722200 --- diff --git a/manifest b/manifest index dc584aea02..b35da2907d 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index 940f87c4fd..0c7efa98ff 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -803cb60e75e0b09a526eefec11139cb3e8ae8c7c \ No newline at end of file +f8b159794c3855cad86d755cc7422ddc21722200 \ No newline at end of file diff --git a/src/func.c b/src/func.c index 62abf13d4d..bcd658cefb 100644 --- a/src/func.c +++ b/src/func.c @@ -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); + } + } } } diff --git a/src/main.c b/src/main.c index 69365b7848..4b3878b650 100644 --- a/src/main.c +++ b/src/main.c @@ -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; diff --git a/src/printf.c b/src/printf.c index 05f2ff5a62..54d80eef86 100644 --- a/src/printf.c +++ b/src/printf.c @@ -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; diff --git a/src/shell.c b/src/shell.c index 8b5695ac18..278a633741 100644 --- a/src/shell.c +++ b/src/shell.c @@ -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); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 163bc69fe7..f7cd01cba4 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -3190,6 +3190,17 @@ int sqlite3_limit(sqlite3*, int id, int newVal); ** [[SQLITE_LIMIT_WORKER_THREADS]] ^(
SQLITE_LIMIT_WORKER_THREADS
**
The maximum number of auxiliary worker threads that a single ** [prepared statement] may start.
)^ +** +** [[SQLITE_LIMIT_PRINTF_WIDTH]] ^(
SQLITE_LIMIT_PRINTF_WIDTH
+**
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.

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. ** */ #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 diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7b9542a96e..b20a5f2240 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -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 diff --git a/src/sqliteLimit.h b/src/sqliteLimit.h index 75cad1274b..a5d6037364 100644 --- a/src/sqliteLimit.h +++ b/src/sqliteLimit.h @@ -208,3 +208,11 @@ #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 diff --git a/src/test1.c b/src/test1.c index a87fcd859d..00114e1f92 100644 --- a/src/test1.c +++ b/src/test1.c @@ -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;