From: Dmitry Shulga Date: January 27 2011 2:19pm Subject: bzr commit into mysql-5.1-bugteam branch (Dmitry.Shulga:3514) Bug#58026 List-Archive: http://lists.mysql.com/commits/129781 X-Bug: 58026 Message-Id: <201101271423.p0REN0Qr010281@rcsinet13.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============2985015735254035931==" --===============2985015735254035931== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///Users/shulga/projects/mysql/5.1-bugteam-bug58026/ based on revid:davi.arnaut@stripped 3514 Dmitry Shulga 2011-01-27 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 === 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-01-27 14:19:00 +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-01-27 14:19:00 +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-01-27 14:19:00 +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-01-27 14:19:00 +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 class if needed */ 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-01-27 14:19:00 +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 2010-11-09 14:45:13 +0000 +++ b/sql/mysqld.cc 2011-01-27 14:19:00 +0000 @@ -3032,6 +3032,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. @@ -3412,7 +3425,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 --===============2985015735254035931== 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\ # 418vs5q0eayrmwmi # target_branch: file:///Users/shulga/projects/mysql/5.1-bugteam-\ # bug58026/ # testament_sha1: 3815e4cbd2a0f525d4e746473f734020e2f5e250 # timestamp: 2011-01-27 20:19:21 +0600 # base_revision_id: davi.arnaut@stripped\ # l0f3bxmcwibcplxq # # Begin bundle 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 FOFCQ6FW9Pw= --===============2985015735254035931==--