File openjpeg2-CVE-2016-1923.patch of Package openjpeg2.36921
diff --git a/src/lib/openjp2/opj_includes.h b/src/lib/openjp2/opj_includes.h
index d9238b1..a86fd5e 100644
--- a/src/lib/openjp2/opj_includes.h
+++ b/src/lib/openjp2/opj_includes.h
@@ -46,6 +46,7 @@
*/
#include <memory.h>
#include <stdlib.h>
+#include <limits.h>
#include <string.h>
#include <math.h>
#include <float.h>
diff --git a/src/lib/openjp2/opj_intmath.h b/src/lib/openjp2/opj_intmath.h
index f0b3e51..120ea7c 100644
--- a/src/lib/openjp2/opj_intmath.h
+++ b/src/lib/openjp2/opj_intmath.h
@@ -116,7 +116,7 @@ static INLINE OPJ_INT32 opj_int_abs(OPJ_INT32 a) {
Divide an integer and round upwards
@return Returns a divided by b
*/
-static INLINE OPJ_INT32 opj_int_ceildiv(OPJ_INT32 a, OPJ_INT32 b) {
+static INLINE OPJ_INT64 opj_int_ceildiv(OPJ_INT64 a, OPJ_INT64 b) {
assert(b);
return (a + b - 1) / b;
}
@@ -140,7 +140,7 @@ static INLINE OPJ_INT32 opj_int_ceildivpow2(OPJ_INT32 a, OPJ_INT32 b) {
Divide an integer by a power of 2 and round downwards
@return Returns a divided by 2^b
*/
-static INLINE OPJ_INT32 opj_int_floordivpow2(OPJ_INT32 a, OPJ_INT32 b) {
+static INLINE OPJ_INT64 opj_int_floordivpow2(OPJ_INT64 a, OPJ_INT64 b) {
return a >> b;
}
/**
diff --git a/src/lib/openjp2/pi.c b/src/lib/openjp2/pi.c
index e27930b..23c4421 100644
--- a/src/lib/openjp2/pi.c
+++ b/src/lib/openjp2/pi.c
@@ -437,14 +437,39 @@ OPJ_BOOL opj_pi_next_pcrl(opj_pi_iterator_t * pi) {
OPJ_INT32 trx1, try1;
OPJ_UINT32 rpx, rpy;
OPJ_INT32 prci, prcj;
+ if (pi->resno >= comp->numresolutions) {
+ continue;
+ }
res = &comp->resolutions[pi->resno];
levelno = comp->numresolutions - 1 - pi->resno;
+ /* Avoids division by zero */
+ /* Relates to id_000004,sig_06,src_000679,op_arith8,pos_49,val_-17 */
+ /* of https://github.com/uclouvain/openjpeg/issues/938 */
+ if (levelno >= 32 ||
+ ((comp->dx << levelno) >> levelno) != comp->dx ||
+ ((comp->dy << levelno) >> levelno) != comp->dy) {
+ continue;
+ }
+ if ((comp->dx << levelno) > INT_MAX ||
+ (comp->dy << levelno) > INT_MAX) {
+ continue;
+ }
trx0 = opj_int_ceildiv(pi->tx0, (OPJ_INT32)(comp->dx << levelno));
try0 = opj_int_ceildiv(pi->ty0, (OPJ_INT32)(comp->dy << levelno));
trx1 = opj_int_ceildiv(pi->tx1, (OPJ_INT32)(comp->dx << levelno));
try1 = opj_int_ceildiv(pi->ty1, (OPJ_INT32)(comp->dy << levelno));
rpx = res->pdx + levelno;
rpy = res->pdy + levelno;
+
+ /* To avoid divisions by zero / undefined behaviour on shift */
+ /* in below tests */
+ /* Fixes reading id:000026,sig:08,src:002419,op:int32,pos:60,val:+32 */
+ /* of https://github.com/uclouvain/openjpeg/issues/938 */
+ if (rpx >= 31 || ((comp->dx << rpx) >> rpx) != comp->dx ||
+ rpy >= 31 || ((comp->dy << rpy) >> rpy) != comp->dy) {
+ continue;
+ }
+
if (!((pi->y % (OPJ_INT32)(comp->dy << rpy) == 0) || ((pi->y == pi->ty0) && ((try0 << levelno) % (1 << rpy))))){
continue;
}
@@ -456,10 +481,10 @@ OPJ_BOOL opj_pi_next_pcrl(opj_pi_iterator_t * pi) {
if ((trx0==trx1)||(try0==try1)) continue;
- prci = opj_int_floordivpow2(opj_int_ceildiv(pi->x, (OPJ_INT32)(comp->dx << levelno)), (OPJ_INT32)res->pdx)
- - opj_int_floordivpow2(trx0, (OPJ_INT32)res->pdx);
- prcj = opj_int_floordivpow2(opj_int_ceildiv(pi->y, (OPJ_INT32)(comp->dy << levelno)), (OPJ_INT32)res->pdy)
- - opj_int_floordivpow2(try0, (OPJ_INT32)res->pdy);
+ prci = opj_int_floordivpow2(opj_int_ceildiv(pi->x, (OPJ_INT64)(comp->dx << levelno)), (OPJ_INT64)res->pdx)
+ - opj_int_floordivpow2(trx0, (OPJ_INT64)res->pdx);
+ prcj = opj_int_floordivpow2(opj_int_ceildiv(pi->y, (OPJ_INT64)(comp->dy << levelno)), (OPJ_INT64)res->pdy)
+ - opj_int_floordivpow2(try0, (OPJ_INT64)res->pdy);
pi->precno = (OPJ_UINT32)(prci + prcj * (OPJ_INT32)res->pw);
for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) {
index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;