CVE-2016-8884: NULL Pointer Dereference (CWE-476)
value: The bmp_getdata function in libjasper/bmp/bmp_dec.c in JasPer 1.900.5 allows remote attackers to cause a denial of service (NULL pointer dereference) by calling the imginfo command with a crafted BMP image. NOTE: this vulnerability exists because of an incomplete fix for CVE-2016-8690.
CWE description: The product dereferences a pointer that it expects to be valid but is NULL.
CVSS v3 base score: 5.5
Published: 2017-03-28T14:59Z
Repository: https://github.com/mdadams/jasper
Language: C
Files changed: src/libjasper/base/jas_seq.c, src/libjasper/bmp/bmp_dec.c
Commit date: 2016-10-19 20:13:06 -0700
Commit message: Fixed a problem with a null pointer dereference in the BMP decoder.

Diff: diff --git a/src/libjasper/base/jas_seq.c b/src/libjasper/base/jas_seq.c
index a76bbde..cac20e2 100644
--- a/src/libjasper/base/jas_seq.c
+++ b/src/libjasper/base/jas_seq.c
@@ -100,10 +100,14 @@ jas_matrix_t *jas_seq2d_create(int xstart, int ystart, int xend, int yend)
 jas_matrix_t *jas_matrix_create(int numrows, int numcols)
 {
 	jas_matrix_t *matrix;
 	int i;
 
+	if (numrows < 0 || numcols < 0) {
+		return 0;
+	}
+
 	if (!(matrix = jas_malloc(sizeof(jas_matrix_t)))) {
 		return 0;
 	}
 	matrix->flags_ = 0;
 	matrix->numrows_ = numrows;
diff --git a/src/libjasper/bmp/bmp_dec.c b/src/libjasper/bmp/bmp_dec.c
index 6e7d880..d5a903f 100644
--- a/src/libjasper/bmp/bmp_dec.c
+++ b/src/libjasper/bmp/bmp_dec.c
@@ -105,10 +105,13 @@ jas_image_t *bmp_decode(jas_stream_t *in, char *optstr)
 	jas_image_cmptparm_t cmptparms[3];
 	jas_image_cmptparm_t *cmptparm;
 	uint_fast16_t numcmpts;
 	long n;
 
+	image = 0;
+	info = 0;
+
 	if (optstr) {
 		jas_eprintf("warning: ignoring BMP decoder options\n");
 	}
 
 	jas_eprintf(
@@ -119,47 +122,61 @@ jas_image_t *bmp_decode(jas_stream_t *in, char *optstr)
 	  );
 
 	/* Read the bitmap header. */
 	if (bmp_gethdr(in, &hdr)) {
 		jas_eprintf("cannot get header\n");
-		return 0;
+		goto error;
+		//return 0;
 	}
 	JAS_DBGLOG(1, (
 	  "BMP header: magic 0x%x; siz %d; res1 %d; res2 %d; off %d\n",
 	  hdr.magic, hdr.siz, hdr.reserved1, hdr.reserved2, hdr.off
 	  ));
 
 	/* Read the bitmap information. */
 	if (!(info = bmp_getinfo(in))) {
 		jas_eprintf("cannot get info\n");
-		return 0;
+		//return 0;
+		goto error;
 	}
 	JAS_DBGLOG(1,
-	  ("BMP information: len %d; width %d; height %d; numplanes %d; "
-	  "depth %d; enctype %d; siz %d; hres %d; vres %d; numcolors %d; "
-	  "mincolors %d\n", info->len, info->width, info->height, info->numplanes,
-	  info->depth, info->enctype, info->siz, info->hres, info->vres,
-	  info->numcolors, info->mincolors));
+	  ("BMP information: len %ld; width %ld; height %ld; numplanes %d; "
+	  "depth %d; enctype %ld; siz %ld; hres %ld; vres %ld; numcolors %ld; "
+	  "mincolors %ld\n", JAS_CAST(long, info->len),
+	  JAS_CAST(long, info->width), JAS_CAST(long, info->height),
+	  JAS_CAST(long, info->numplanes), JAS_CAST(long, info->depth),
+	  JAS_CAST(long, info->enctype), JAS_CAST(long, info->siz),
+	  JAS_CAST(long, info->hres), JAS_CAST(long, info->vres),
+	  JAS_CAST(long, info->numcolors), JAS_CAST(long, info->mincolors)));
+
+	if (info->width < 0 || info->height < 0 || info->numplanes < 0 ||
+	  info->depth < 0 || info->siz < 0 || info->hres < 0 || info->vres < 0) {
+		jas_eprintf("corrupt bit stream\n");
+		goto error;
+	}
 
 	/* Ensure that we support this type of BMP file. */
 	if (!bmp_issupported(&hdr, info)) {
 		jas_eprintf("error: unsupported BMP encoding\n");
-		bmp_info_destroy(info);
-		return 0;
+		//bmp_info_destroy(info);
+		//return 0;
+		goto error;
 	}
 
 	/* Skip over any useless data between the end of the palette
 	  and start of the bitmap data. */
 	if ((n = hdr.off - (BMP_HDRLEN + BMP_INFOLEN + BMP_PALLEN(info))) < 0) {
 		jas_eprintf("error: possibly bad bitmap offset?\n");
-		return 0;
+		goto error;
+		//return 0;
 	}
 	if (n > 0) {
 		jas_eprintf("skipping unknown data in BMP file\n");
 		if (bmp_gobble(in, n)) {
-			bmp_info_destroy(info);
-			return 0;
+			//bmp_info_destroy(info);
+			//return 0;
+			goto error;
 		}
 	}
 
 	/* Get the number of components. */
 	numcmpts = bmp_numcmpts(info);
@@ -177,12 +194,13 @@ jas_image_t *bmp_decode(jas_stream_t *in, char *optstr)
 	}
 
 	/* Create image object. */
 	if (!(image = jas_image_create(numcmpts, cmptparms,
 	  JAS_CLRSPC_UNKNOWN))) {
-		bmp_info_destroy(info);
-		return 0;
+		//bmp_info_destroy(info);
+		//return 0;
+		goto error;
 	}
 
 	if (numcmpts == 3) {
 		jas_image_setclrspc(image, JAS_CLRSPC_SRGB);
 		jas_image_setcmpttype(image, 0,
@@ -197,18 +215,28 @@ jas_image_t *bmp_decode(jas_stream_t *in, char *optstr)
 		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y));
 	}
 
 	/* Read the bitmap data. */
 	if (bmp_getdata(in, info, image)) {
-		bmp_info_destroy(info);
-		jas_image_destroy(image);
-		return 0;
+		//bmp_info_destroy(info);
+		//jas_image_destroy(image);
+		//return 0;
+		goto error;
 	}
 
 	bmp_info_destroy(info);
 
 	return image;
+
+error:
+	if (info) {
+		bmp_info_destroy(info);
+	}
+	if (image) {
+		jas_image_destroy(image);
+	}
+	return 0;
 }
 
 int bmp_validate(jas_stream_t *in)
 {
 	int n;

Vulnerable code: 		return 0;
		return 0;
	  ("BMP information: len %d; width %d; height %d; numplanes %d; "
	  "depth %d; enctype %d; siz %d; hres %d; vres %d; numcolors %d; "
	  "mincolors %d\n", info->len, info->width, info->height, info->numplanes,
	  info->depth, info->enctype, info->siz, info->hres, info->vres,
	  info->numcolors, info->mincolors));
		bmp_info_destroy(info);
		return 0;
		return 0;
			bmp_info_destroy(info);
			return 0;
		bmp_info_destroy(info);
		return 0;
		bmp_info_destroy(info);
		jas_image_destroy(image);
		return 0;
Fixed code: 	if (numrows < 0 || numcols < 0) {
		return 0;
	}

	image = 0;
	info = 0;

		goto error;
		//return 0;
		//return 0;
		goto error;
	  ("BMP information: len %ld; width %ld; height %ld; numplanes %d; "
	  "depth %d; enctype %ld; siz %ld; hres %ld; vres %ld; numcolors %ld; "
	  "mincolors %ld\n", JAS_CAST(long, info->len),
	  JAS_CAST(long, info->width), JAS_CAST(long, info->height),
	  JAS_CAST(long, info->numplanes), JAS_CAST(long, info->depth),
	  JAS_CAST(long, info->enctype), JAS_CAST(long, info->siz),
	  JAS_CAST(long, info->hres), JAS_CAST(long, info->vres),
	  JAS_CAST(long, info->numcolors), JAS_CAST(long, info->mincolors)));

	if (info->width < 0 || info->height < 0 || info->numplanes < 0 ||
	  info->depth < 0 || info->siz < 0 || info->hres < 0 || info->vres < 0) {
		jas_eprintf("corrupt bit stream\n");
		goto error;
	}
		//bmp_info_destroy(info);
		//return 0;
		goto error;
		goto error;
		//return 0;
			//bmp_info_destroy(info);
			//return 0;
			goto error;
		//bmp_info_destroy(info);
		//return 0;
		goto error;
		//bmp_info_destroy(info);
		//jas_image_destroy(image);
		//return 0;
		goto error;

error:
	if (info) {
		bmp_info_destroy(info);
	}
	if (image) {
		jas_image_destroy(image);
	}
	return 0;