diff options
| author | Xin LI <delphij@FreeBSD.org> | 2015-02-17 19:15:07 +0000 |
|---|---|---|
| committer | Xin LI <delphij@FreeBSD.org> | 2015-02-17 19:15:07 +0000 |
| commit | 8f67f3ae4b202b7b8ad3f3981bf9c7d6ccfd6b99 (patch) | |
| tree | ee3ba1b5120dd0c1d2ec0ed0ab4ad0b30facfb3a | |
| parent | c3a04ad893fdcf623e0b97c132eba2a7394a49f6 (diff) | |
Notes
| -rw-r--r-- | lib/libc/regex/regcomp.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/lib/libc/regex/regcomp.c b/lib/libc/regex/regcomp.c index 7bb8b552f991..bff534a637fb 100644 --- a/lib/libc/regex/regcomp.c +++ b/lib/libc/regex/regcomp.c @@ -187,6 +187,7 @@ regcomp(regex_t * __restrict preg, struct parse *p = &pa; int i; size_t len; + size_t maxlen; #ifdef REDEBUG # define GOODFLAGS(f) (f) #else @@ -208,7 +209,23 @@ regcomp(regex_t * __restrict preg, g = (struct re_guts *)malloc(sizeof(struct re_guts)); if (g == NULL) return(REG_ESPACE); + /* + * Limit the pattern space to avoid a 32-bit overflow on buffer + * extension. Also avoid any signed overflow in case of conversion + * so make the real limit based on a 31-bit overflow. + * + * Likely not applicable on 64-bit systems but handle the case + * generically (who are we to stop people from using ~715MB+ + * patterns?). + */ + maxlen = ((size_t)-1 >> 1) / sizeof(sop) * 2 / 3; + if (len >= maxlen) { + free((char *)g); + return(REG_ESPACE); + } p->ssize = len/(size_t)2*(size_t)3 + (size_t)1; /* ugh */ + assert(p->ssize >= len); + p->strip = (sop *)malloc(p->ssize * sizeof(sop)); p->slen = 0; if (p->strip == NULL) { |
