summaryrefslogtreecommitdiff
path: root/regex
diff options
context:
space:
mode:
authorShishir Jaiswal <shishir.j.jaiswal@oracle.com>2016-11-29 11:19:30 +0530
committerShishir Jaiswal <shishir.j.jaiswal@oracle.com>2016-11-29 11:19:30 +0530
commit8f297058512e6744b8d9f0bafe35689c702fce67 (patch)
tree2218c9b10808aa10e024da300020eac299b6c437 /regex
parentab5932f851da38d05bd1e401467ed197bdc2836d (diff)
downloadmariadb-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.
Diffstat (limited to 'regex')
-rw-r--r--regex/regcomp.c21
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);