Commit 8f297058 authored by Shishir Jaiswal's avatar Shishir Jaiswal

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.
parent ab5932f8
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment