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.
This commit is contained in:
parent
ab5932f851
commit
8f29705851
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user