CVE-2016-9388: Other (NVD-CWE-Other)
value: The ras_getcmap function in ras_dec.c in JasPer before 1.900.14 allows remote attackers to cause a denial of service (assertion failure) via a crafted image file.
CWE description: NVD is only using a subset of CWE for mapping instead of the entire CWE, and the weakness type is not covered by that subset.
CVSS v3 base score: 5.5
Published: 2017-03-23T18:59Z
Repository: https://github.com/mdadams/jasper
Language: C
Files changed: src/libjasper/ras/ras_dec.c, src/libjasper/ras/ras_enc.c
Commit date: 2016-10-24 06:56:08 -0700
Commit message: Fixed a few bugs in the RAS encoder and decoder where errors were tested
with assertions instead of being gracefully handled.

Diff: diff --git a/src/libjasper/ras/ras_dec.c b/src/libjasper/ras/ras_dec.c
index 7e2e22e..ec85aac 100644
--- a/src/libjasper/ras/ras_dec.c
+++ b/src/libjasper/ras/ras_dec.c
@@ -258,24 +258,31 @@ static int ras_getdatastd(jas_stream_t *in, ras_hdr_t *hdr, ras_cmap_t *cmap,
 
 /* Note: This function does not properly handle images with a colormap. */
 	/* Avoid compiler warnings about unused parameters. */
 	cmap = 0;
 
+	assert(jas_image_numcmpts(image) <= 3);
+
+	for (i = 0; i < 3; ++i) {
+		data[i] = 0;
+	}
+
 	for (i = 0; i < jas_image_numcmpts(image); ++i) {
-		data[i] = jas_matrix_create(1, jas_image_width(image));
-		assert(data[i]);
+		if (!(data[i] = jas_matrix_create(1, jas_image_width(image)))) {
+			goto error;
+		}
 	}
 
 	pad = RAS_ROWSIZE(hdr) - (hdr->width * hdr->depth + 7) / 8;
 
 	for (y = 0; y < hdr->height; y++) {
 		nz = 0;
 		z = 0;
 		for (x = 0; x < hdr->width; x++) {
 			while (nz < hdr->depth) {
 				if ((c = jas_stream_getc(in)) == EOF) {
-					return -1;
+					goto error;
 				}
 				z = (z << 8) | c;
 				nz += 8;
 			}
 
@@ -291,26 +298,35 @@ static int ras_getdatastd(jas_stream_t *in, ras_hdr_t *hdr, ras_cmap_t *cmap,
 				jas_matrix_setv(data[0], x, (v));
 			}
 		}
 		if (pad) {
 			if ((c = jas_stream_getc(in)) == EOF) {
-				return -1;
+				goto error;
 			}
 		}
 		for (i = 0; i < jas_image_numcmpts(image); ++i) {
 			if (jas_image_writecmpt(image, i, 0, y, hdr->width, 1,
 			  data[i])) {
-				return -1;
+				goto error;
 			}
 		}
 	}
 
 	for (i = 0; i < jas_image_numcmpts(image); ++i) {
 		jas_matrix_destroy(data[i]);
+		data[i] = 0;
 	}
 
 	return 0;
+
+error:
+	for (i = 0; i < 3; ++i) {
+		if (data[i]) {
+			jas_matrix_destroy(data[i]);
+		}
+	}
+	return -1;
 }
 
 static int ras_getcmap(jas_stream_t *in, ras_hdr_t *hdr, ras_cmap_t *cmap)
 {
 	int i;
@@ -325,11 +341,13 @@ static int ras_getcmap(jas_stream_t *in, ras_hdr_t *hdr, ras_cmap_t *cmap)
 		break;
 	case RAS_MT_EQUALRGB:
 		{
 		jas_eprintf("warning: palettized images not fully supported\n");
 		numcolors = 1 << hdr->depth;
-		assert(numcolors <= RAS_CMAP_MAXSIZ);
+		if (numcolors > RAS_CMAP_MAXSIZ) {
+			return -1;
+		}
 		actualnumcolors = hdr->maplength / 3;
 		for (i = 0; i < numcolors; i++) {
 			cmap->data[i] = 0;
 		}
 		if ((hdr->maplength % 3) || hdr->maplength < 0 ||
diff --git a/src/libjasper/ras/ras_enc.c b/src/libjasper/ras/ras_enc.c
index 075bc0b..c7366a9 100644
--- a/src/libjasper/ras/ras_enc.c
+++ b/src/libjasper/ras/ras_enc.c
@@ -228,13 +228,21 @@ static int ras_putdatastd(jas_stream_t *out, ras_hdr_t *hdr, jas_image_t *image,
 	int y;
 	int v;
 	jas_matrix_t *data[3];
 	int i;
 
+	assert(numcmpts <= 3);
+
+	for (i = 0; i < 3; ++i) {
+		data[i] = 0;
+	}
+
 	for (i = 0; i < numcmpts; ++i) {
-		data[i] = jas_matrix_create(jas_image_height(image), jas_image_width(image));
-		assert(data[i]);
+		if (!(data[i] = jas_matrix_create(jas_image_height(image),
+		  jas_image_width(image)))) {
+			goto error;
+		}
 	}
 
 	rowsize = RAS_ROWSIZE(hdr);
 	pad = rowsize - (hdr->width * hdr->depth + 7) / 8;
 
@@ -242,11 +250,11 @@ static int ras_putdatastd(jas_stream_t *out, ras_hdr_t *hdr, jas_image_t *image,
 
 	for (y = 0; y < hdr->height; y++) {
 		for (i = 0; i < numcmpts; ++i) {
 			if (jas_image_readcmpt(image, cmpts[i], 0, y,
 					jas_image_width(image), 1, data[i])) {
-				return -1;
+				goto error;
 			}
 		}
 		z = 0;
 		nz = 0;
 		for (x = 0; x < hdr->width; x++) {
@@ -261,34 +269,43 @@ static int ras_putdatastd(jas_stream_t *out, ras_hdr_t *hdr, jas_image_t *image,
 			z |= v & RAS_ONES(hdr->depth);
 			nz += hdr->depth;
 			while (nz >= 8) {
 				c = (z >> (nz - 8)) & 0xff;
 				if (jas_stream_putc(out, c) == EOF) {
-					return -1;
+					goto error;
 				}
 				nz -= 8;
 				z &= RAS_ONES(nz);
 			}
 		}
 		if (nz > 0) {
 			c = (z >> (8 - nz)) & RAS_ONES(nz);
 			if (jas_stream_putc(out, c) == EOF) {
-				return -1;
+				goto error;
 			}
 		}
 		if (pad % 2) {
 			if (jas_stream_putc(out, 0) == EOF) {
-				return -1;
+				goto error;
 			}
 		}
 	}
 
 	for (i = 0; i < numcmpts; ++i) {
 		jas_matrix_destroy(data[i]);
+		data[i] = 0;
 	}
 
 	return 0;
+
+error:
+	for (i = 0; i < numcmpts; ++i) {
+		if (data[i]) {
+			jas_matrix_destroy(data[i]);
+		}
+	}
+	return -1;
 }
 
 static int ras_puthdr(jas_stream_t *out, ras_hdr_t *hdr)
 {
 	if (ras_putint(out, RAS_MAGIC) || ras_putint(out, hdr->width) ||

Vulnerable code: 		data[i] = jas_matrix_create(1, jas_image_width(image));
		assert(data[i]);
					return -1;
				return -1;
				return -1;
		assert(numcolors <= RAS_CMAP_MAXSIZ);
		data[i] = jas_matrix_create(jas_image_height(image), jas_image_width(image));
		assert(data[i]);
				return -1;
					return -1;
				return -1;
				return -1;
Fixed code: 	assert(jas_image_numcmpts(image) <= 3);

	for (i = 0; i < 3; ++i) {
		data[i] = 0;
	}

		if (!(data[i] = jas_matrix_create(1, jas_image_width(image)))) {
			goto error;
		}
					goto error;
				goto error;
				goto error;
		data[i] = 0;

error:
	for (i = 0; i < 3; ++i) {
		if (data[i]) {
			jas_matrix_destroy(data[i]);
		}
	}
	return -1;
		if (numcolors > RAS_CMAP_MAXSIZ) {
			return -1;
		}
	assert(numcmpts <= 3);

	for (i = 0; i < 3; ++i) {
		data[i] = 0;
	}

		if (!(data[i] = jas_matrix_create(jas_image_height(image),
		  jas_image_width(image)))) {
			goto error;
		}
				goto error;
					goto error;
				goto error;
				goto error;
		data[i] = 0;

error:
	for (i = 0; i < numcmpts; ++i) {
		if (data[i]) {
			jas_matrix_destroy(data[i]);
		}
	}
	return -1;