diff options
| author | Joerg Sonnenberger <joerg@bec.de> | 2015-02-07 21:24:06 +0000 |
|---|---|---|
| committer | Joerg Sonnenberger <joerg@bec.de> | 2015-02-07 21:24:06 +0000 |
| commit | a73284a2a4e8a0c1d3431eae3de376901717f6ba (patch) | |
| tree | a0dcbe55fda84ee62f59f406b94ebca074011cd6 /llvm/lib | |
| parent | cbc3b2fdc28228064a858df381812badd7833c5b (diff) | |
| download | bcm5719-llvm-a73284a2a4e8a0c1d3431eae3de376901717f6ba.tar.gz bcm5719-llvm-a73284a2a4e8a0c1d3431eae3de376901717f6ba.zip | |
Avoid integer overflows around realloc calls resulting in potential
heap. Problem identified by Guido Vranken. Changes differ from original
OpenBSD sources by not depending on non-portable reallocarray.
llvm-svn: 228507
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Support/regcomp.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/llvm/lib/Support/regcomp.c b/llvm/lib/Support/regcomp.c index 0b5b765f89e..b7969296647 100644 --- a/llvm/lib/Support/regcomp.c +++ b/llvm/lib/Support/regcomp.c @@ -49,6 +49,14 @@ #include "regcclass.h" #include "regcname.h" +#include "llvm/Config/config.h" +#if HAVE_STDINT_H +#include <stdint.h> +#else +/* Pessimistically bound memory use */ +#define SIZE_MAX UINT_MAX +#endif + /* * parse structure, passed up and down to avoid global variables and * other clumsinesses @@ -1069,6 +1077,8 @@ allocset(struct parse *p) p->ncsalloc += CHAR_BIT; nc = p->ncsalloc; + if (nc > SIZE_MAX / sizeof(cset)) + goto nomem; assert(nc % CHAR_BIT == 0); nbytes = nc / CHAR_BIT * css; @@ -1412,6 +1422,11 @@ enlarge(struct parse *p, sopno size) if (p->ssize >= size) return; + if ((unsigned long)size > SIZE_MAX / sizeof(sop)) { + SETERROR(REG_ESPACE); + return; + } + sp = (sop *)realloc(p->strip, size*sizeof(sop)); if (sp == NULL) { SETERROR(REG_ESPACE); @@ -1428,6 +1443,12 @@ static void stripsnug(struct parse *p, struct re_guts *g) { g->nstates = p->slen; + if ((unsigned long)p->slen > SIZE_MAX / sizeof(sop)) { + g->strip = p->strip; + SETERROR(REG_ESPACE); + return; + } + g->strip = (sop *)realloc((char *)p->strip, p->slen * sizeof(sop)); if (g->strip == NULL) { SETERROR(REG_ESPACE); |

