CVE-2016-9394: Improper Input Validation (CWE-20)
value: The jas_seq2d_create function in jas_seq.c in JasPer before 1.900.17 allows remote attackers to cause a denial of service (assertion failure) via a crafted file.
CWE description: The product receives input or data, but it does
        not validate or incorrectly validates that the input has the
        properties that are required to process the data safely and
        correctly.
CVSS v3 base score: 5.5
Published: 2017-03-23T18:59Z
Repository: https://github.com/mdadams/jasper
Language: C
Files changed: src/libjasper/jpc/jpc_cs.c
Commit date: 2016-10-27 20:11:57 -0700
Commit message: Added some missing sanity checks on the data in a SIZ marker segment.

Diff: diff --git a/src/libjasper/jpc/jpc_cs.c b/src/libjasper/jpc/jpc_cs.c
index cf7199e..37cfa98 100644
--- a/src/libjasper/jpc/jpc_cs.c
+++ b/src/libjasper/jpc/jpc_cs.c
@@ -487,10 +487,12 @@ static int jpc_siz_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate,
 {
 	jpc_siz_t *siz = &ms->parms.siz;
 	unsigned int i;
 	uint_fast8_t tmp;
 
+	siz->comps = 0;
+
 	/* Eliminate compiler warning about unused variables. */
 	cstate = 0;
 
 	if (jpc_getuint16(in, &siz->caps) ||
 	  jpc_getuint32(in, &siz->width) ||
@@ -500,48 +502,71 @@ static int jpc_siz_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate,
 	  jpc_getuint32(in, &siz->tilewidth) ||
 	  jpc_getuint32(in, &siz->tileheight) ||
 	  jpc_getuint32(in, &siz->tilexoff) ||
 	  jpc_getuint32(in, &siz->tileyoff) ||
 	  jpc_getuint16(in, &siz->numcomps)) {
-		return -1;
+		goto error;
 	}
-	if (!siz->width || !siz->height || !siz->tilewidth ||
-	  !siz->tileheight || !siz->numcomps || siz->numcomps > 16384) {
-		return -1;
+	if (!siz->width || !siz->height) {
+		jas_eprintf("reference grid cannot have zero area\n");
+		goto error;
 	}
-	if (siz->tilexoff >= siz->width || siz->tileyoff >= siz->height) {
-		jas_eprintf("all tiles are outside the image area\n");
-		return -1;
+	if (!siz->tilewidth || !siz->tileheight) {
+		jas_eprintf("tile cannot have zero area\n");
+		goto error;
+	}
+	if (!siz->numcomps || siz->numcomps > 16384) {
+		jas_eprintf("number of components not in permissible range\n");
+		goto error;
 	}
+	if (siz->xoff >= siz->width) {
+		jas_eprintf("XOsiz not in permissible range\n");
+		goto error;
+	}
+	if (siz->yoff >= siz->height) {
+		jas_eprintf("YOsiz not in permissible range\n");
+		goto error;
+	}
+	if (siz->tilexoff > siz->xoff || siz->tilexoff + siz->tilewidth <= siz->xoff) {
+		jas_eprintf("XTOsiz not in permissible range\n");
+		goto error;
+	}
+	if (siz->tileyoff > siz->yoff || siz->tileyoff + siz->tileheight <= siz->yoff) {
+		jas_eprintf("YTOsiz not in permissible range\n");
+		goto error;
+	}
+
 	if (!(siz->comps = jas_alloc2(siz->numcomps, sizeof(jpc_sizcomp_t)))) {
-		return -1;
+		goto error;
 	}
 	for (i = 0; i < siz->numcomps; ++i) {
 		if (jpc_getuint8(in, &tmp) ||
 		  jpc_getuint8(in, &siz->comps[i].hsamp) ||
 		  jpc_getuint8(in, &siz->comps[i].vsamp)) {
-			jas_free(siz->comps);
-			return -1;
+			goto error;
 		}
 		if (siz->comps[i].hsamp == 0 || siz->comps[i].hsamp > 255) {
 			jas_eprintf("invalid XRsiz value %d\n", siz->comps[i].hsamp);
-			jas_free(siz->comps);
-			return -1;
+			goto error;
 		}
 		if (siz->comps[i].vsamp == 0 || siz->comps[i].vsamp > 255) {
 			jas_eprintf("invalid YRsiz value %d\n", siz->comps[i].vsamp);
-			jas_free(siz->comps);
-			return -1;
+			goto error;
 		}
 		siz->comps[i].sgnd = (tmp >> 7) & 1;
 		siz->comps[i].prec = (tmp & 0x7f) + 1;
 	}
 	if (jas_stream_eof(in)) {
-		jas_free(siz->comps);
-		return -1;
+		goto error;
 	}
 	return 0;
+
+error:
+	if (siz->comps) {
+		jas_free(siz->comps);
+	}
+	return -1;
 }
 
 static int jpc_siz_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
 {
 	jpc_siz_t *siz = &ms->parms.siz;

Vulnerable code: 		return -1;
	if (!siz->width || !siz->height || !siz->tilewidth ||
	  !siz->tileheight || !siz->numcomps || siz->numcomps > 16384) {
		return -1;
	if (siz->tilexoff >= siz->width || siz->tileyoff >= siz->height) {
		jas_eprintf("all tiles are outside the image area\n");
		return -1;
		return -1;
			jas_free(siz->comps);
			return -1;
			jas_free(siz->comps);
			return -1;
			jas_free(siz->comps);
			return -1;
		jas_free(siz->comps);
		return -1;
Fixed code: 	siz->comps = 0;

		goto error;
	if (!siz->width || !siz->height) {
		jas_eprintf("reference grid cannot have zero area\n");
		goto error;
	if (!siz->tilewidth || !siz->tileheight) {
		jas_eprintf("tile cannot have zero area\n");
		goto error;
	}
	if (!siz->numcomps || siz->numcomps > 16384) {
		jas_eprintf("number of components not in permissible range\n");
		goto error;
	if (siz->xoff >= siz->width) {
		jas_eprintf("XOsiz not in permissible range\n");
		goto error;
	}
	if (siz->yoff >= siz->height) {
		jas_eprintf("YOsiz not in permissible range\n");
		goto error;
	}
	if (siz->tilexoff > siz->xoff || siz->tilexoff + siz->tilewidth <= siz->xoff) {
		jas_eprintf("XTOsiz not in permissible range\n");
		goto error;
	}
	if (siz->tileyoff > siz->yoff || siz->tileyoff + siz->tileheight <= siz->yoff) {
		jas_eprintf("YTOsiz not in permissible range\n");
		goto error;
	}

		goto error;
			goto error;
			goto error;
			goto error;
		goto error;

error:
	if (siz->comps) {
		jas_free(siz->comps);
	}
	return -1;