CVE-2016-9391 (published 2017-03-23T18:59Z)

The jpc_bitstream_getbits function in jpc_bs.c in JasPer before 2.0.10 allows remote attackers to cause a denial of service (assertion failure) via a very large integer.

Severity: MEDIUM
CVSS v2 base score: 5.0 (AV:N/AC:L/Au:N/C:N/I:N/A:P)
CVSS v3 base score: 7.5, HIGH (CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: NVD-CWE-Other
cwe_name: Other
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.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/mdadams/jasper
commit_details: repo_url: https://github.com/mdadams/jasper
author: Michael Adams
author_date: 2016-10-25 07:01:50-07:00
msg: Changed the JPC bitstream code to more gracefully handle a request
for a larger sized integer than what can be handled (i.e., return
with an error instead of failing an assert).
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: jpc_bs.c
change_type: ModificationType.MODIFY
diff: @@ -194,7 +194,10 @@ long jpc_bitstream_getbits(jpc_bitstream_t *bitstream, int n)
 
 	/* We can reliably get at most 31 bits since ISO/IEC 9899 only
 	  guarantees that a long can represent values up to 2^31-1. */
-	assert(n >= 0 && n < 32);
+	//assert(n >= 0 && n < 32);
+	if (n < 0 || n >= 32) {
+		return -1;
+	}
 
 	/* Get the number of bits requested from the specified bit stream. */
 	v = 0;
@@ -214,7 +217,10 @@ int jpc_bitstream_putbits(jpc_bitstream_t *bitstream, int n, long v)
 
 	/* We can reliably put at most 31 bits since ISO/IEC 9899 only
 	  guarantees that a long can represent values up to 2^31-1. */
-	assert(n >= 0 && n < 32);
+	//assert(n >= 0 && n < 32);
+	if (n < 0 || n >= 32) {
+		return EOF;
+	}
 	/* Ensure that only the bits to be output are nonzero. */
 	assert(!(v & (~JAS_ONES(n))));
 

programming_language: C
filename: jpc_cs.c
change_type: ModificationType.MODIFY
diff: @@ -904,8 +904,8 @@ static int jpc_qcd_dumpparms(jpc_ms_t *ms, FILE *out)
 	  (int) qcd->compparms.qntsty, qcd->compparms.numguard, qcd->compparms.numstepsizes);
 	for (i = 0; i < qcd->compparms.numstepsizes; ++i) {
 		fprintf(out, "expn[%d] = 0x%04x; mant[%d] = 0x%04x;\n",
-		  i, (unsigned) JPC_QCX_GETEXPN(qcd->compparms.stepsizes[i]),
-		  i, (unsigned) JPC_QCX_GETMANT(qcd->compparms.stepsizes[i]));
+		  i, JAS_CAST(unsigned, JPC_QCX_GETEXPN(qcd->compparms.stepsizes[i])),
+		  i, JAS_CAST(unsigned, JPC_QCX_GETMANT(qcd->compparms.stepsizes[i])));
 	}
 	return 0;
 }

programming_language: C
filename: jpc_dec.c
change_type: ModificationType.MODIFY
diff: @@ -1641,6 +1641,7 @@ static void calcstepsizes(uint_fast16_t refstepsize, int numrlvls,
 	mant = JPC_QCX_GETMANT(refstepsize);
 	numbands = 3 * numrlvls - 2;
 	for (bandno = 0; bandno < numbands; ++bandno) {
+//jas_eprintf("DEBUG %d %d %d %d %d\n", bandno, expn, numrlvls, bandno, ((numrlvls - 1) - (numrlvls - 1 - ((bandno > 0) ? ((bandno + 2) / 3) : (0)))));
 		stepsizes[bandno] = JPC_QCX_MANT(mant) | JPC_QCX_EXPN(expn +
 		  (numrlvls - 1) - (numrlvls - 1 - ((bandno > 0) ? ((bandno + 2) / 3) : (0))));
 	}

programming_language: C