diff options
author | Shishir Jaiswal <shishir.j.jaiswal@oracle.com> | 2016-11-29 11:19:30 +0530 |
---|---|---|
committer | Shishir Jaiswal <shishir.j.jaiswal@oracle.com> | 2016-11-29 11:19:30 +0530 |
commit | 8f297058512e6744b8d9f0bafe35689c702fce67 (patch) | |
tree | 2218c9b10808aa10e024da300020eac299b6c437 | |
parent | ab5932f851da38d05bd1e401467ed197bdc2836d (diff) | |
download | mariadb-git-8f297058512e6744b8d9f0bafe35689c702fce67.tar.gz |
Bug#24449090 - BUFFER OVERFLOW IN FUNCTION DUPL
DESCRIPTION
===========
Performing a pattern match of a Regex resulting into a very
large string, leads to crash due to failed realloc().
ANALYSIS
========
dupl() calls enlarge(). It in turn calls realloc() for
pointer p->strip. This eventually fails due to OOM.
However we are still using the same pointer in memcpy()
causing a SEGFAULT!
FIX
===
1) In dupl(), checking for error code (which would be set
if realloc fails) immediately after call to enlarge().
Returning now with this error code.
2) Handling the same in the caller functions.
-rw-r--r-- | regex/regcomp.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/regex/regcomp.c b/regex/regcomp.c index b1074a1d79c..e7feb9301e6 100644 --- a/regex/regcomp.c +++ b/regex/regcomp.c @@ -3,7 +3,7 @@ This file was modified by Oracle on 2015-05-18 for 32-bit compatibility. - Modifications copyright (c) 2015, Oracle and/or its affiliates. All rights + Modifications copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. */ #include <my_global.h> @@ -551,6 +551,8 @@ int starordinary; /* is a leading * an ordinary character? */ assert(OP(p->strip[p->pbegin[i]]) == OLPAREN); assert(OP(p->strip[p->pend[i]]) == ORPAREN); (void) dupl(p, p->pbegin[i]+1, p->pend[i]); + if (p->error != 0) + break; /* purecov: inspected */ EMIT(O_BACK, i); } else SETERROR(REG_ESUBREG); @@ -1031,6 +1033,8 @@ int to; /* to this number of times (maybe RE_INFINITY) */ AHEAD(THERE()); /* ...so fix it */ ASTERN(O_CH, THERETHERE()); copy = dupl(p, start+1, finish+1); + if (p->error != 0) + return; /* purecov: inspected */ assert(copy == finish+4); repeat(p, copy, 1, to-1); break; @@ -1040,10 +1044,14 @@ int to; /* to this number of times (maybe RE_INFINITY) */ break; case REP(N, N): /* as xx{m-1,n-1} */ copy = dupl(p, start, finish); + if (p->error != 0) + return; repeat(p, copy, from-1, to-1); break; case REP(N, INF): /* as xx{n-1,INF} */ copy = dupl(p, start, finish); + if (p->error != 0) + return; /* purecov: inspected */ repeat(p, copy, from-1, to); break; default: /* "can't happen" */ @@ -1366,6 +1374,9 @@ sopno finish; /* to this less one */ if (len == 0) return(ret); enlarge(p, p->ssize + len); /* this many unexpected additions */ + if (p->error != 0) + return(p->error); + assert(p->ssize >= p->slen + len); (void) memcpy((char *)(p->strip + p->slen), (char *)(p->strip + start), (size_t)len*sizeof(sop)); @@ -1482,6 +1493,14 @@ register sopno size; if (p->ssize >= size) return; + DBUG_EXECUTE_IF("bug24449090_simulate_oom", + { + p->strip= NULL; + p->ssize= 0; + SETERROR(REG_ESPACE); + return; + }); + sp = (sop *)realloc(p->strip, size*sizeof(sop)); if (sp == NULL) { SETERROR(REG_ESPACE); |