diff options
Diffstat (limited to 'lib/libc/regex/regcomp.c')
| -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 2ecb88c54a93..ae92f6a3ef82 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) {  | 
