summaryrefslogtreecommitdiff
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
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.
-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);