CVE-2016-9391: Other (NVD-CWE-Other)
value: 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.
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: 7.5
Published: 2017-03-23T18:59Z
Repository: https://github.com/mdadams/jasper
Language: C
Files changed: src/libjasper/jpc/jpc_bs.c, src/libjasper/jpc/jpc_cs.c, src/libjasper/jpc/jpc_dec.c
Commit date: 2016-10-25 07:01:50 -0700
Commit message: 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).

Diff: diff --git a/src/libjasper/jpc/jpc_bs.c b/src/libjasper/jpc/jpc_bs.c
index f87a40c..43b0f79 100644
--- a/src/libjasper/jpc/jpc_bs.c
+++ b/src/libjasper/jpc/jpc_bs.c
@@ -192,11 +192,14 @@ long jpc_bitstream_getbits(jpc_bitstream_t *bitstream, int n)
 	long v;
 	int u;
 
 	/* 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;
 	while (--n >= 0) {
 		if ((u = jpc_bitstream_getbit(bitstream)) < 0) {
@@ -212,11 +215,14 @@ int jpc_bitstream_putbits(jpc_bitstream_t *bitstream, int n, long v)
 {
 	int m;
 
 	/* 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))));
 
 	/* Put the desired number of bits to the specified bit stream. */
 	m = n - 1;
diff --git a/src/libjasper/jpc/jpc_cs.c b/src/libjasper/jpc/jpc_cs.c
index 0c855f5..1e0c9af 100644
--- a/src/libjasper/jpc/jpc_cs.c
+++ b/src/libjasper/jpc/jpc_cs.c
@@ -902,12 +902,12 @@ static int jpc_qcd_dumpparms(jpc_ms_t *ms, FILE *out)
 	int i;
 	fprintf(out, "qntsty = %d; numguard = %d; numstepsizes = %d\n",
 	  (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;
 }
 
 /******************************************************************************\
diff --git a/src/libjasper/jpc/jpc_dec.c b/src/libjasper/jpc/jpc_dec.c
index 95ac7c6..a023a7b 100644
--- a/src/libjasper/jpc/jpc_dec.c
+++ b/src/libjasper/jpc/jpc_dec.c
@@ -1639,10 +1639,11 @@ static void calcstepsizes(uint_fast16_t refstepsize, int numrlvls,
 	uint_fast16_t mant;
 	expn = JPC_QCX_GETEXPN(refstepsize);
 	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))));
 	}
 }
 

Vulnerable code: 	assert(n >= 0 && n < 32);
	assert(n >= 0 && n < 32);
		  i, (unsigned) JPC_QCX_GETEXPN(qcd->compparms.stepsizes[i]),
		  i, (unsigned) JPC_QCX_GETMANT(qcd->compparms.stepsizes[i]));
Fixed code: 	//assert(n >= 0 && n < 32);
	if (n < 0 || n >= 32) {
		return -1;
	}
	//assert(n >= 0 && n < 32);
	if (n < 0 || n >= 32) {
		return EOF;
	}
		  i, JAS_CAST(unsigned, JPC_QCX_GETEXPN(qcd->compparms.stepsizes[i])),
		  i, JAS_CAST(unsigned, JPC_QCX_GETMANT(qcd->compparms.stepsizes[i])));
//jas_eprintf("DEBUG %d %d %d %d %d\n", bandno, expn, numrlvls, bandno, ((numrlvls - 1) - (numrlvls - 1 - ((bandno > 0) ? ((bandno + 2) / 3) : (0)))));