summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authordelphij <delphij@FreeBSD.org>2015-02-17 19:14:16 +0000
committerdelphij <delphij@FreeBSD.org>2015-02-17 19:14:16 +0000
commita45941e76cf65f24d9ea5ecde45212c0f88269a6 (patch)
tree9f7ed25e582531dde29949c8dd83df8d8fda817e /lib
parent28f489d0bda741de6f8573020e7b5c45e8744414 (diff)
downloadFreeBSD-src-a45941e76cf65f24d9ea5ecde45212c0f88269a6.zip
FreeBSD-src-a45941e76cf65f24d9ea5ecde45212c0f88269a6.tar.gz
MFC r278739:
Disallow pattern spaces which would cause intermediate calculations to overflow size_t. Obtained from: DragonFly (2841837793bd095a82f477e9c370cfe6cfb3862c dillon) Security: CERT VU#695940
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/regex/regcomp.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/lib/libc/regex/regcomp.c b/lib/libc/regex/regcomp.c
index 2ecb88c..ae92f6a 100644
--- a/lib/libc/regex/regcomp.c
+++ b/lib/libc/regex/regcomp.c
@@ -192,6 +192,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
@@ -213,7 +214,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) {
OpenPOWER on IntegriCloud