From: Dmitry Shulga Date: February 4 2011 5:16am Subject: bzr push into mysql-5.1 branch (Dmitry.Shulga:3574 to 3575) Bug#58026 List-Archive: http://lists.mysql.com/commits/130353 X-Bug: 58026 Message-Id: <201102040516.p145GsWe019921@acsinet15.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0282750865247707469==" --===============0282750865247707469== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline 3575 Dmitry Shulga 2011-02-04 Fixed bug#58026 - massive recursion and crash in regular expression handling. The problem was that parsing of nested regular expression involved recursive calls. Such recursion didn't take into account the amount of available stack space, which ended up leading to stack overflow crashes. @ mysql-test/t/not_embedded_server.test Added test for bug#58026. @ regex/my_regex.h added pointer to function as last argument of my_regex_init() for check enough memory in stack. @ regex/regcomp.c p_ere() was modified: added call to function for check enough memory in stack. Function for check available stack space specified by global variable my_regex_enough_mem_in_stack. This variable set to NULL for embedded mysqld and to a pointer to function check_enough_stack_size otherwise. @ regex/reginit.c my_regex_init was modified: pass a pointer to a function for check enough memory in stack space. Reset this pointer to NULL in my_regex_end. @ sql/mysqld.cc Added function check_enough_stack_size() for check enough memory in stack. Passed this function as second argument to my_regex_init. For embedded mysqld passed NULL as second argument. modified: mysql-test/r/not_embedded_server.result mysql-test/t/not_embedded_server.test regex/my_regex.h regex/regcomp.c regex/reginit.c sql/mysqld.cc 3574 Georgi Kodinov 2011-02-02 [merge] merge modified: mysql-test/r/func_time.result mysql-test/t/func_time.test === modified file 'mysql-test/r/not_embedded_server.result' --- a/mysql-test/r/not_embedded_server.result 2009-04-30 10:29:19 +0000 +++ b/mysql-test/r/not_embedded_server.result 2011-02-04 04:47:46 +0000 @@ -4,3 +4,7 @@ select 1; SHOW VARIABLES like 'slave_skip_errors'; Variable_name Value slave_skip_errors OFF +# +# Bug#58026: massive recursion and crash in regular expression handling +# +SELECT '1' RLIKE RPAD('1', 10000, '('); === modified file 'mysql-test/t/not_embedded_server.test' --- a/mysql-test/t/not_embedded_server.test 2009-04-30 10:29:19 +0000 +++ b/mysql-test/t/not_embedded_server.test 2011-02-04 04:47:46 +0000 @@ -42,4 +42,14 @@ select 1; SHOW VARIABLES like 'slave_skip_errors'; +--echo # +--echo # Bug#58026: massive recursion and crash in regular expression handling +--echo # + +--disable_result_log +--error ER_STACK_OVERRUN_NEED_MORE +SELECT '1' RLIKE RPAD('1', 10000, '('); +--enable_result_log + + # End of 5.1 tests === modified file 'regex/my_regex.h' --- a/regex/my_regex.h 2005-09-29 00:08:24 +0000 +++ b/regex/my_regex.h 2011-02-04 04:47:46 +0000 @@ -28,6 +28,7 @@ typedef struct { /* === regcomp.c === */ +typedef int (*my_regex_stack_check_t)(); extern int my_regcomp(my_regex_t *, const char *, int, CHARSET_INFO *charset); #define REG_BASIC 0000 #define REG_EXTENDED 0001 @@ -76,7 +77,8 @@ extern void my_regfree(my_regex_t *); /* === reginit.c === */ -extern void my_regex_init(CHARSET_INFO *cs); /* Should be called for multithread progs */ +/* Should be called for multithread progs */ +extern void my_regex_init(CHARSET_INFO *cs, my_regex_stack_check_t func); extern void my_regex_end(void); /* If one wants a clean end */ #ifdef __cplusplus === modified file 'regex/regcomp.c' --- a/regex/regcomp.c 2010-07-09 19:37:52 +0000 +++ b/regex/regcomp.c 2011-02-04 04:47:46 +0000 @@ -31,6 +31,9 @@ struct parse { CHARSET_INFO *charset; /* for ctype things */ }; +/* Check if there is enough stack space for recursion. */ +my_regex_stack_check_t my_regex_enough_mem_in_stack= NULL; + #include "regcomp.ih" static char nuls[10]; /* place to point scanner in event of error */ @@ -117,7 +120,7 @@ CHARSET_INFO *charset; # define GOODFLAGS(f) ((f)&~REG_DUMP) #endif - my_regex_init(charset); /* Init cclass if neaded */ + my_regex_init(charset, NULL); /* Init cclass if neaded */ preg->charset=charset; cflags = GOODFLAGS(cflags); if ((cflags®_EXTENDED) && (cflags®_NOSPEC)) @@ -222,7 +225,15 @@ int stop; /* character this ERE should /* do a bunch of concatenated expressions */ conc = HERE(); while (MORE() && (c = PEEK()) != '|' && c != stop) - p_ere_exp(p); + { + if (my_regex_enough_mem_in_stack && + my_regex_enough_mem_in_stack()) + { + SETERROR(REG_ESPACE); + return; + } + p_ere_exp(p); + } if(REQUIRE(HERE() != conc, REG_EMPTY)) {}/* require nonempty */ if (!EAT('|')) === modified file 'regex/reginit.c' --- a/regex/reginit.c 2008-02-18 22:29:39 +0000 +++ b/regex/reginit.c 2011-02-04 04:47:46 +0000 @@ -4,10 +4,12 @@ #include #include #include "cclass.h" +#include "my_regex.h" static my_bool regex_inited=0; +extern my_regex_stack_check_t my_regex_enough_mem_in_stack; -void my_regex_init(CHARSET_INFO *cs) +void my_regex_init(CHARSET_INFO *cs, my_regex_stack_check_t func) { char buff[CCLASS_LAST][256]; int count[CCLASS_LAST]; @@ -16,6 +18,7 @@ void my_regex_init(CHARSET_INFO *cs) if (!regex_inited) { regex_inited=1; + my_regex_enough_mem_in_stack= func; bzero((uchar*) &count,sizeof(count)); for (i=1 ; i<= 255; i++) @@ -74,6 +77,7 @@ void my_regex_end() int i; for (i=0; i < CCLASS_LAST ; i++) free((char*) cclasses[i].chars); + my_regex_enough_mem_in_stack= NULL; regex_inited=0; } } === modified file 'sql/mysqld.cc' --- a/sql/mysqld.cc 2011-02-02 17:05:28 +0000 +++ b/sql/mysqld.cc 2011-02-04 04:47:46 +0000 @@ -3034,6 +3034,19 @@ sizeof(load_default_groups)/sizeof(load_ #endif +#ifndef EMBEDDED_LIBRARY +static +int +check_enough_stack_size() +{ + uchar stack_top; + + return check_stack_overrun(current_thd, STACK_MIN_SIZE, + &stack_top); +} +#endif + + /** Initialize one of the global date/time format variables. @@ -3415,7 +3428,11 @@ static int init_common_variables(const c #endif mysys_uses_curses=0; #ifdef USE_REGEX - my_regex_init(&my_charset_latin1); +#ifndef EMBEDDED_LIBRARY + my_regex_init(&my_charset_latin1, check_enough_stack_size); +#else + my_regex_init(&my_charset_latin1, NULL); +#endif #endif /* Process a comma-separated character set list and choose --===============0282750865247707469== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/dmitry.shulga@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: dmitry.shulga@stripped\ # sakc2ctbjb9n7tqv # target_branch: file:///Users/shulga/projects/mysql/mysql-5.1-\ # bug58026/ # testament_sha1: 206b98935fd5a3d02595f4dfc982c70c1faefe17 # timestamp: 2011-02-04 11:16:14 +0600 # source_branch: file:///Users/shulga/projects/mysql/5.1-bugteam-\ # bug58026/ # base_revision_id: georgi.kodinov@stripped\ # 43bd41beoas8nlcd # # Begin bundle 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 nlnJR0SqFsmNLgoa1v+LuSKcKEhVsv6HgA== --===============0282750865247707469==--