diff options
author | Dmitry Shulga <Dmitry.Shulga@oracle.com> | 2011-02-04 10:47:46 +0600 |
---|---|---|
committer | Dmitry Shulga <Dmitry.Shulga@oracle.com> | 2011-02-04 10:47:46 +0600 |
commit | 378091e434d66dcc7081f991a07db2244dbb8cda (patch) | |
tree | d9c23034dd5cc3bd26c4dce059805d050030408d /regex/regcomp.c | |
parent | a265fde655316a4c1b1702bb97dd7fdde621f55c (diff) | |
download | mariadb-git-378091e434d66dcc7081f991a07db2244dbb8cda.tar.gz |
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.
Diffstat (limited to 'regex/regcomp.c')
-rw-r--r-- | regex/regcomp.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/regex/regcomp.c b/regex/regcomp.c index 81c435ed552..e163a9ba7f4 100644 --- a/regex/regcomp.c +++ b/regex/regcomp.c @@ -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 end at */ /* 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('|')) |