CVE-2017-6850 (published 2017-03-15T14:59Z)

The jp2_cdef_destroy function in jp2_cod.c in JasPer before 2.0.13 allows remote attackers to cause a denial of service (NULL pointer dereference) via a crafted image.

Severity: MEDIUM
CVSS v2 base score: 4.3 (AV:N/AC:M/Au:N/C:N/I:N/A:P)
CVSS v3 base score: 5.5, MEDIUM (CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-476
cwe_name: NULL Pointer Dereference
description: The product dereferences a pointer that it expects to be valid but is NULL.
extended_description: 
            
            
            
         
         

Fix information:
repo_url: https://github.com/mdadams/jasper
commit_details: repo_url: https://github.com/mdadams/jasper
author: Michael Adams
author_date: 2017-03-04 14:43:24-08:00
msg: Fixed bugs due to uninitialized data in the JP2 decoder.
Also, added some comments marking I/O stream interfaces that probably
need to be changed (in the long term) to fix integer overflow problems.
repository: repo_url: https://github.com/mdadams/jasper
repo_name: jasper-software/jasper
description: Official Repository for the JasPer Image Coding Toolkit
repo_language: C
owner: mdadams
file_changes: filename: jas_stream.c
change_type: ModificationType.MODIFY
diff: @@ -664,6 +664,7 @@ int jas_stream_ungetc(jas_stream_t *stream, int c)
 	return 0;
 }
 
+/* FIXME integral type */
 int jas_stream_read(jas_stream_t *stream, void *buf, int cnt)
 {
 	int n;
@@ -690,6 +691,7 @@ int jas_stream_read(jas_stream_t *stream, void *buf, int cnt)
 	return n;
 }
 
+/* FIXME integral type */
 int jas_stream_write(jas_stream_t *stream, const void *buf, int cnt)
 {
 	int n;
@@ -742,6 +744,7 @@ int jas_stream_puts(jas_stream_t *stream, const char *s)
 	return 0;
 }
 
+/* FIXME integral type */
 char *jas_stream_gets(jas_stream_t *stream, char *buf, int bufsize)
 {
 	int c;
@@ -765,6 +768,7 @@ char *jas_stream_gets(jas_stream_t *stream, char *buf, int bufsize)
 	return buf;
 }
 
+/* FIXME integral type */
 int jas_stream_gobble(jas_stream_t *stream, int n)
 {
 	int m;
@@ -783,6 +787,7 @@ int jas_stream_gobble(jas_stream_t *stream, int n)
 	return n;
 }
 
+/* FIXME integral type */
 int jas_stream_pad(jas_stream_t *stream, int n, int c)
 {
 	int m;
@@ -885,6 +890,7 @@ long jas_stream_tell(jas_stream_t *stream)
 * Buffer initialization code.
 \******************************************************************************/
 
+/* FIXME integral type */
 static void jas_stream_initbuf(jas_stream_t *stream, int bufmode, char *buf,
   int bufsize)
 {
@@ -1060,6 +1066,7 @@ static int jas_strtoopenmode(const char *s)
 	return openmode;
 }
 
+/* FIXME integral type */
 int jas_stream_copy(jas_stream_t *out, jas_stream_t *in, int n)
 {
 	int all;
@@ -1085,6 +1092,7 @@ int jas_stream_copy(jas_stream_t *out, jas_stream_t *in, int n)
 	return 0;
 }
 
+/* FIXME integral type */
 long jas_stream_setrwcount(jas_stream_t *stream, long rwcnt)
 {
 	int old;
@@ -1094,6 +1102,7 @@ long jas_stream_setrwcount(jas_stream_t *stream, long rwcnt)
 	return old;
 }
 
+/* FIXME integral type */
 int jas_stream_display(jas_stream_t *stream, FILE *fp, int n)
 {
 	unsigned char buf[16];
@@ -1168,6 +1177,7 @@ long jas_stream_length(jas_stream_t *stream)
 * Memory stream object.
 \******************************************************************************/
 
+/* FIXME integral type */
 static int mem_read(jas_stream_obj_t *obj, char *buf, int cnt)
 {
 	ssize_t n;
@@ -1209,6 +1219,7 @@ static int mem_resize(jas_stream_memobj_t *m, size_t bufsize)
 	return 0;
 }
 
+/* FIXME integral type */
 static int mem_write(jas_stream_obj_t *obj, char *buf, int cnt)
 {
 	size_t n;
@@ -1264,6 +1275,7 @@ static int mem_write(jas_stream_obj_t *obj, char *buf, int cnt)
 	return ret;
 }
 
+/* FIXME integral type */
 static long mem_seek(jas_stream_obj_t *obj, long offset, int origin)
 {
 	jas_stream_memobj_t *m = (jas_stream_memobj_t *)obj;
@@ -1310,6 +1322,7 @@ static int mem_close(jas_stream_obj_t *obj)
 * File stream object.
 \******************************************************************************/
 
+/* FIXME integral type */
 static int file_read(jas_stream_obj_t *obj, char *buf, int cnt)
 {
 	jas_stream_fileobj_t *fileobj;
@@ -1318,6 +1331,7 @@ static int file_read(jas_stream_obj_t *obj, char *buf, int cnt)
 	return read(fileobj->fd, buf, cnt);
 }
 
+/* FIXME integral type */
 static int file_write(jas_stream_obj_t *obj, char *buf, int cnt)
 {
 	jas_stream_fileobj_t *fileobj;
@@ -1326,6 +1340,7 @@ static int file_write(jas_stream_obj_t *obj, char *buf, int cnt)
 	return write(fileobj->fd, buf, cnt);
 }
 
+/* FIXME integral type */
 static long file_seek(jas_stream_obj_t *obj, long offset, int origin)
 {
 	jas_stream_fileobj_t *fileobj;
@@ -1352,6 +1367,7 @@ static int file_close(jas_stream_obj_t *obj)
 * Stdio file stream object.
 \******************************************************************************/
 
+/* FIXME integral type */
 static int sfile_read(jas_stream_obj_t *obj, char *buf, int cnt)
 {
 	FILE *fp;
@@ -1367,6 +1383,7 @@ static int sfile_read(jas_stream_obj_t *obj, char *buf, int cnt)
 	return result;
 }
 
+/* FIXME integral type */
 static int sfile_write(jas_stream_obj_t *obj, char *buf, int cnt)
 {
 	FILE *fp;
@@ -1377,6 +1394,7 @@ static int sfile_write(jas_stream_obj_t *obj, char *buf, int cnt)
 	return (n != JAS_CAST(size_t, cnt)) ? (-1) : cnt;
 }
 
+/* FIXME integral type */
 static long sfile_seek(jas_stream_obj_t *obj, long offset, int origin)
 {
 	FILE *fp;

programming_language: C
filename: jp2_cod.c
change_type: ModificationType.MODIFY
diff: @@ -183,15 +183,28 @@ jp2_boxinfo_t jp2_boxinfo_unk = {
 * Box constructor.
 \******************************************************************************/
 
-jp2_box_t *jp2_box_create(int type)
+jp2_box_t *jp2_box_create0()
 {
 	jp2_box_t *box;
-	jp2_boxinfo_t *boxinfo;
-
 	if (!(box = jas_malloc(sizeof(jp2_box_t)))) {
 		return 0;
 	}
 	memset(box, 0, sizeof(jp2_box_t));
+	box->type = 0;
+	box->len = 0;
+	// Mark the box data as never having been constructed
+	// so that we will not errantly attempt to destroy it later.
+	box->ops = &jp2_boxinfo_unk.ops;
+	return box;
+}
+
+jp2_box_t *jp2_box_create(int type)
+{
+	jp2_box_t *box;
+	jp2_boxinfo_t *boxinfo;
+	if (!(box = jp2_box_create0())) {
+		return 0;
+	}
 	box->type = type;
 	box->len = 0;
 	if (!(boxinfo = jp2_boxinfolookup(type))) {
@@ -248,14 +261,9 @@ jp2_box_t *jp2_box_get(jas_stream_t *in)
 	box = 0;
 	tmpstream = 0;
 
-	if (!(box = jas_malloc(sizeof(jp2_box_t)))) {
+	if (!(box = jp2_box_create0())) {
 		goto error;
 	}
-
-	// Mark the box data as never having been constructed
-	// so that we will not errantly attempt to destroy it later.
-	box->ops = &jp2_boxinfo_unk.ops;
-
 	if (jp2_getuint32(in, &len) || jp2_getuint32(in, &box->type)) {
 		goto error;
 	}
@@ -263,10 +271,12 @@ jp2_box_t *jp2_box_get(jas_stream_t *in)
 	box->info = boxinfo;
 	box->len = len;
 	JAS_DBGLOG(10, (
-	  "preliminary processing of JP2 box: type=%c%s%c (0x%08x); length=%d\n",
+	  "preliminary processing of JP2 box: "
+	  "type=%c%s%c (0x%08x); length=%"PRIuFAST32"\n",
 	  '"', boxinfo->name, '"', box->type, box->len
 	  ));
 	if (box->len == 1) {
+		JAS_DBGLOG(10, ("big length\n"));
 		if (jp2_getuint64(in, &extlen)) {
 			goto error;
 		}
@@ -382,6 +392,7 @@ static int jp2_bpcc_getdata(jp2_box_t *box, jas_stream_t *in)
 {
 	jp2_bpcc_t *bpcc = &box->data.bpcc;
 	unsigned int i;
+	bpcc->bpcs = 0;
 	bpcc->numcmpts = box->datalen;
 	if (!(bpcc->bpcs = jas_alloc2(bpcc->numcmpts, sizeof(uint_fast8_t)))) {
 		return -1;
@@ -462,6 +473,7 @@ static int jp2_cdef_getdata(jp2_box_t *box, jas_stream_t *in)
 	jp2_cdef_t *cdef = &box->data.cdef;
 	jp2_cdefchan_t *chan;
 	unsigned int channo;
+	cdef->ents = 0;
 	if (jp2_getuint16(in, &cdef->numchans)) {
 		return -1;
 	}
@@ -518,7 +530,9 @@ int jp2_box_put(jp2_box_t *box, jas_stream_t *out)
 	}
 
 	if (dataflag) {
-		if (jas_stream_copy(out, tmpstream, box->len - JP2_BOX_HDRLEN(false))) {
+		if (jas_stream_copy(out, tmpstream, box->len -
+		  JP2_BOX_HDRLEN(false))) {
+			jas_eprintf("cannot copy box data\n");
 			goto error;
 		}
 		jas_stream_close(tmpstream);
@@ -777,6 +791,7 @@ static int jp2_cmap_getdata(jp2_box_t *box, jas_stream_t *in)
 	jp2_cmap_t *cmap = &box->data.cmap;
 	jp2_cmapent_t *ent;
 	unsigned int i;
+	cmap->ents = 0;
 
 	cmap->numchans = (box->datalen) / 4;
 	if (!(cmap->ents = jas_alloc2(cmap->numchans, sizeof(jp2_cmapent_t)))) {
@@ -835,6 +850,7 @@ static int jp2_pclr_getdata(jp2_box_t *box, jas_stream_t *in)
 	int_fast32_t x;
 
 	pclr->lutdata = 0;
+	pclr->bpc = 0;
 
 	if (jp2_getuint16(in, &pclr->numlutents) ||
 	  jp2_getuint8(in, &pclr->numchans)) {
@@ -869,9 +885,9 @@ static int jp2_pclr_putdata(jp2_box_t *box, jas_stream_t *out)
 #if 0
 	jp2_pclr_t *pclr = &box->data.pclr;
 #endif
-/* Eliminate warning about unused variable. */
-box = 0;
-out = 0;
+	/* Eliminate warning about unused variable. */
+	box = 0;
+	out = 0;
 	return -1;
 }
 

programming_language: C