CVE-2016-9583 (C, published 2018-08-01T17:29Z)
Description: value: An out-of-bounds heap read vulnerability was found in the jpc_pi_nextpcrl() function of jasper before 2.0.6 when processing crafted input.
Severity: MEDIUM (CVSS v3 base score: 7.8)
Weakness: CWE-125 \u2014 Out-of-bounds Read
The product reads data past the end, or before the beginning, of the intended buffer.
Repository: https://github.com/mdadams/jasper
Files changed:
src/libjasper/include/jasper/jas_types.h
src/libjasper/jpc/jpc_t2cod.c
src/libjasper/jpc/jpc_t2dec.c
Commit message: Fixed numerous integer overflow problems in the code for packet iterators
in the JPC decoder.


Vulnerable code:
			  pi->compno < JAS_CAST(int, pchg->compnoend); ++pi->compno, ++pi->picomp) {
				xstep = picomp->hsamp * (1 << (pirlvl->prcwidthexpn +
				  picomp->numrlvls - rlvlno - 1));
				ystep = picomp->vsamp * (1 << (pirlvl->prcheightexpn +
				  picomp->numrlvls - rlvlno - 1));
					if (((pi->x == pi->xstart && ((trx0 << r) % (1 << rpx)))
					  || !(pi->x % (1 << rpx))) &&
					  ((pi->y == pi->ystart && ((try0 << r) % (1 << rpy)))
					  || !(pi->y % (1 << rpy)))) {
						prchind = JPC_FLOORDIVPOW2(JPC_CEILDIV(pi->x, pi->picomp->hsamp
						  << r), pi->pirlvl->prcwidthexpn) - JPC_FLOORDIVPOW2(trx0,
						  pi->pirlvl->prcwidthexpn);
						prcvind = JPC_FLOORDIVPOW2(JPC_CEILDIV(pi->y, pi->picomp->vsamp
						  << r), pi->pirlvl->prcheightexpn) - JPC_FLOORDIVPOW2(try0,
						  pi->pirlvl->prcheightexpn);
						  pi->numlyrs && pi->lyrno < JAS_CAST(int, pchg->lyrnoend); ++pi->lyrno) {
				xstep = picomp->hsamp * (1 <<
				  (pirlvl->prcwidthexpn + picomp->numrlvls -
				  rlvlno - 1));
				ystep = picomp->vsamp * (1 <<
				  (pirlvl->prcheightexpn + picomp->numrlvls -
				  rlvlno - 1));
				pi->xstep = (!pi->xstep) ? xstep :
				  JAS_MIN(pi->xstep, xstep);
				pi->ystep = (!pi->ystep) ? ystep :
				  JAS_MIN(pi->ystep, ystep);
					if (((pi->x == pi->xstart && ((trx0 << r) % (1 << rpx))) ||
					  ((pi->y == pi->ystart && ((try0 << r) % (1 << rpy))) ||
						prchind = JPC_FLOORDIVPOW2(JPC_CEILDIV(pi->x, pi->picomp->hsamp
						  << r), pi->pirlvl->prcwidthexpn) - JPC_FLOORDIVPOW2(trx0,
						  pi->pirlvl->prcwidthexpn);
						prcvind = JPC_FLOORDIVPOW2(JPC_CEILDIV(pi->y, pi->picomp->vsamp
						  << r), pi->pirlvl->prcheightexpn) - JPC_FLOORDIVPOW2(try0,
						  pi->pirlvl->prcheightexpn);
						  pi->lyrno < JAS_CAST(int, pchg->lyrnoend); ++pi->lyrno) {
	for (pi->compno = pchg->compnostart, pi->picomp =
	  &pi->picomps[pi->compno]; pi->compno < JAS_CAST(int, pchg->compnoend) && pi->compno < pi->numcomps; ++pi->compno,
	  ++pi->picomp) {
					if (((pi->x == pi->xstart && ((trx0 << r) % (1 << rpx))) ||
					  ((pi->y == pi->ystart && ((try0 << r) % (1 << rpy))) ||
						prchind = JPC_FLOORDIVPOW2(JPC_CEILDIV(pi->x, pi->picomp->hsamp
						  << r), pi->pirlvl->prcwidthexpn) - JPC_FLOORDIVPOW2(trx0,
						  pi->pirlvl->prcwidthexpn);
						prcvind = JPC_FLOORDIVPOW2(JPC_CEILDIV(pi->y, pi->picomp->vsamp
						  << r), pi->pirlvl->prcheightexpn) - JPC_FLOORDIVPOW2(try0,
						  pi->pirlvl->prcheightexpn);
						pi->prcno = prcvind *
						  pi->pirlvl->numhprcs +
						  prchind;
						assert(pi->prcno <
						  pi->pirlvl->numprcs);
						for (pi->lyrno = 0; pi->lyrno <
						  pi->numlyrs && pi->lyrno < JAS_CAST(int, pchg->lyrnoend); ++pi->lyrno) {
if (!tile->pkthdrstream || jas_stream_peekc(tile->pkthdrstream) == EOF) {
		switch (jpc_dec_lookahead(in)) {
		case JPC_MS_EOC:
		case JPC_MS_SOT:
			return 0;
			break;
		case JPC_MS_SOP:
		case JPC_MS_EPH:
		case 0:
			break;
		default:
			return -1;
			break;
}
if (dec->maxpkts >= 0 && dec->numpkts >= dec->maxpkts) {
	jas_eprintf("warning: stopping decode prematurely as requested\n");
	return 0;
}
		if (jpc_dec_decodepkt(dec, pkthdrstream, in, jpc_pi_cmptno(pi), jpc_pi_rlvlno(pi),
		  jpc_pi_prcno(pi), jpc_pi_lyrno(pi))) {
++dec->numpkts;

Fixed code:
/* The number of bits in the integeral type uint_fast32_t. */
/* NOTE: This could underestimate the size on some exotic architectures. */
#define JAS_UINTFAST32_NUMBITS (8 * sizeof(uint_fast32_t))

			  pi->compno < JAS_CAST(int, pchg->compnoend); ++pi->compno,
			  ++pi->picomp) {
				// Check for the potential for overflow problems.
				if (pirlvl->prcwidthexpn + pi->picomp->numrlvls >
				  JAS_UINTFAST32_NUMBITS - 2 ||
				  pirlvl->prcheightexpn + pi->picomp->numrlvls >
				  JAS_UINTFAST32_NUMBITS - 2) {
					return -1;
				}
				xstep = picomp->hsamp * (JAS_CAST(uint_fast32_t, 1) <<
				  (pirlvl->prcwidthexpn + picomp->numrlvls - rlvlno - 1));
				ystep = picomp->vsamp * (JAS_CAST(uint_fast32_t, 1) <<
				  (pirlvl->prcheightexpn + picomp->numrlvls - rlvlno - 1));
					if (((pi->x == pi->xstart &&
					  ((trx0 << r) % (JAS_CAST(uint_fast32_t, 1) << rpx)))
					  || !(pi->x % (JAS_CAST(uint_fast32_t, 1) << rpx))) &&
					  ((pi->y == pi->ystart &&
					  ((try0 << r) % (JAS_CAST(uint_fast32_t, 1) << rpy)))
					  || !(pi->y % (JAS_CAST(uint_fast32_t, 1) << rpy)))) {
						prchind = JPC_FLOORDIVPOW2(JPC_CEILDIV(pi->x,
						  pi->picomp->hsamp << r), pi->pirlvl->prcwidthexpn) -
						  JPC_FLOORDIVPOW2(trx0, pi->pirlvl->prcwidthexpn);
						prcvind = JPC_FLOORDIVPOW2(JPC_CEILDIV(pi->y,
						  pi->picomp->vsamp << r), pi->pirlvl->prcheightexpn) -
						  JPC_FLOORDIVPOW2(try0, pi->pirlvl->prcheightexpn);
						  pi->numlyrs && pi->lyrno < JAS_CAST(int,
						  pchg->lyrnoend); ++pi->lyrno) {
				// Check for the potential for overflow problems.
				if (pirlvl->prcwidthexpn + pi->picomp->numrlvls >
				  JAS_UINTFAST32_NUMBITS - 2 ||
				  pirlvl->prcheightexpn + pi->picomp->numrlvls >
				  JAS_UINTFAST32_NUMBITS - 2) {
					return -1;
				}
				xstep = picomp->hsamp * (JAS_CAST(uint_fast32_t, 1) <<
				  (pirlvl->prcwidthexpn + picomp->numrlvls - rlvlno - 1));
				ystep = picomp->vsamp * (JAS_CAST(uint_fast32_t, 1) <<
				  (pirlvl->prcheightexpn + picomp->numrlvls - rlvlno - 1));
				pi->xstep = (!pi->xstep) ? xstep : JAS_MIN(pi->xstep, xstep);
				pi->ystep = (!pi->ystep) ? ystep : JAS_MIN(pi->ystep, ystep);
					if (((pi->x == pi->xstart &&
					  ((trx0 << r) % (JAS_CAST(uint_fast32_t, 1) << rpx))) ||
					  ((pi->y == pi->ystart &&
					  ((try0 << r) % (JAS_CAST(uint_fast32_t, 1) << rpy))) ||
						prchind = JPC_FLOORDIVPOW2(JPC_CEILDIV(pi->x,
						  pi->picomp->hsamp << r), pi->pirlvl->prcwidthexpn) -
						  JPC_FLOORDIVPOW2(trx0, pi->pirlvl->prcwidthexpn);
						prcvind = JPC_FLOORDIVPOW2(JPC_CEILDIV(pi->y,
						  pi->picomp->vsamp << r), pi->pirlvl->prcheightexpn) -
						  JPC_FLOORDIVPOW2(try0, pi->pirlvl->prcheightexpn);
						  pi->lyrno < JAS_CAST(int, pchg->lyrnoend);
						  ++pi->lyrno) {
	for (pi->compno = pchg->compnostart, pi->picomp = &pi->picomps[pi->compno];
	  pi->compno < JAS_CAST(int, pchg->compnoend) && pi->compno < pi->numcomps;
	  ++pi->compno, ++pi->picomp) {
		// Check for the potential for overflow problems.
		if (pirlvl->prcwidthexpn + pi->picomp->numrlvls >
		  JAS_UINTFAST32_NUMBITS - 2 ||
		  pirlvl->prcheightexpn + pi->picomp->numrlvls >
		  JAS_UINTFAST32_NUMBITS - 2) {
			return -1;
		}
					if (((pi->x == pi->xstart &&
					  ((trx0 << r) % (JAS_CAST(uint_fast32_t, 1) << rpx))) ||
					  ((pi->y == pi->ystart &&
					  ((try0 << r) % (JAS_CAST(uint_fast32_t, 1) << rpy))) ||
						prchind = JPC_FLOORDIVPOW2(JPC_CEILDIV(pi->x,
						  pi->picomp->hsamp << r), pi->pirlvl->prcwidthexpn) -
						  JPC_FLOORDIVPOW2(trx0, pi->pirlvl->prcwidthexpn);
						prcvind = JPC_FLOORDIVPOW2(JPC_CEILDIV(pi->y,
						  pi->picomp->vsamp << r), pi->pirlvl->prcheightexpn) -
						  JPC_FLOORDIVPOW2(try0, pi->pirlvl->prcheightexpn);
						pi->prcno = prcvind * pi->pirlvl->numhprcs + prchind;
						assert(pi->prcno < pi->pirlvl->numprcs);
						for (pi->lyrno = 0; pi->lyrno < pi->numlyrs &&
						  pi->lyrno < JAS_CAST(int, pchg->lyrnoend);
						  ++pi->lyrno) {
		if (!tile->pkthdrstream || jas_stream_peekc(tile->pkthdrstream) == EOF) {
			switch (jpc_dec_lookahead(in)) {
			case JPC_MS_EOC:
			case JPC_MS_SOT:
				return 0;
				break;
			case JPC_MS_SOP:
			case JPC_MS_EPH:
			case 0:
				break;
			default:
				return -1;
				break;
			}
		if (dec->maxpkts >= 0 && dec->numpkts >= dec->maxpkts) {
			jas_eprintf("warning: stopping decode prematurely as requested\n");
			return 0;
		}
		if (jpc_dec_decodepkt(dec, pkthdrstream, in, jpc_pi_cmptno(pi),
		  jpc_pi_rlvlno(pi), jpc_pi_prcno(pi), jpc_pi_lyrno(pi))) {
		++dec->numpkts;