Commit 8506878b authored by Hans Wennborg's avatar Hans Wennborg
Browse files

Merging r228507:

------------------------------------------------------------------------
r228507 | joerg | 2015-02-07 13:24:06 -0800 (Sat, 07 Feb 2015) | 4 lines

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: 228511
parent 9d94c97a
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -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);