Blob Blame History Raw
Backport of the upstream commit:

From b35a05635e56f554870ce85f64293a3868793f69 Mon Sep 17 00:00:00 2001
From: Michael Adams <mdadams@ece.uvic.ca>
Date: Wed, 19 Oct 2016 08:42:25 -0700
Subject: [PATCH] Fixed potential integer overflow problem.

Further enhanced by a change from d42b2388f7f8e0332c846675133acea151fc557a to
use jas_safe_size_mul3() and an explicit check to ensure that size not only
fits into size_t, but that it also does not exceed INT_MAX.  This is similar
approach to what upstream used in a712a2041085e7cd5f2b153e1532ac2a2954ffaa.

This also adds all jas_safe_size_*() functions, including changes from the
following upstream commits:

f596a0766825b48cdc07b28d2051977a382cfb95
65536647d380571d1a9a6c91fa03775fb5bbd256
3afacc174867cc9d1f74ef2683bc780de4b0b2df
d42b2388f7f8e0332c846675133acea151fc557a

diff -pruN jasper-1.900.1.orig/src/libjasper/base/jas_image.c jasper-1.900.1/src/libjasper/base/jas_image.c
--- jasper-1.900.1.orig/src/libjasper/base/jas_image.c	2017-03-24 16:09:34.000000000 +0100
+++ jasper-1.900.1/src/libjasper/base/jas_image.c	2017-03-24 22:28:46.620880896 +0100
@@ -76,6 +76,7 @@
 #include <string.h>
 #include <assert.h>
 #include <ctype.h>
+#include <limits.h>
 
 #include "jasper/jas_math.h"
 #include "jasper/jas_image.h"
@@ -307,10 +308,10 @@ static jas_image_cmpt_t *jas_image_cmpt_
   height, uint_fast16_t depth, bool sgnd, uint_fast32_t inmem)
 {
 	jas_image_cmpt_t *cmpt;
-	long size;
+	size_t size;
 
 	if (!(cmpt = jas_malloc(sizeof(jas_image_cmpt_t)))) {
-		return 0;
+		goto error;
 	}
 
 	cmpt->type_ = JAS_IMAGE_CT_UNKNOWN;
@@ -325,11 +326,14 @@ static jas_image_cmpt_t *jas_image_cmpt_
 	cmpt->stream_ = 0;
 	cmpt->cps_ = (depth + 7) / 8;
 
-	size = cmpt->width_ * cmpt->height_ * cmpt->cps_;
+	//size = cmpt->width_ * cmpt->height_ * cmpt->cps_;
+	if (!jas_safe_size_mul3(cmpt->width_, cmpt->height_, cmpt->cps_, &size) ||
+		size > INT_MAX) {
+		goto error;
+	}
 	cmpt->stream_ = (inmem) ? jas_stream_memopen(0, size) : jas_stream_tmpfile();
 	if (!cmpt->stream_) {
-		jas_image_cmpt_destroy(cmpt);
-		return 0;
+		goto error;
 	}
 
 	/* Zero the component data.  This isn't necessary, but it is
@@ -337,11 +341,16 @@ static jas_image_cmpt_t *jas_image_cmpt_
 	if (jas_stream_seek(cmpt->stream_, size - 1, SEEK_SET) < 0 ||
 	  jas_stream_putc(cmpt->stream_, 0) == EOF ||
 	  jas_stream_seek(cmpt->stream_, 0, SEEK_SET) < 0) {
-		jas_image_cmpt_destroy(cmpt);
-		return 0;
+		goto error;
 	}
 
 	return cmpt;
+
+error:
+	if (cmpt) {
+		jas_image_cmpt_destroy(cmpt);
+	}
+	return 0;
 }
 
 static void jas_image_cmpt_destroy(jas_image_cmpt_t *cmpt)
diff -pruN jasper-1.900.1.orig/src/libjasper/include/jasper/jas_math.h jasper-1.900.1/src/libjasper/include/jasper/jas_math.h
--- jasper-1.900.1.orig/src/libjasper/include/jasper/jas_math.h	2007-01-19 22:43:04.000000000 +0100
+++ jasper-1.900.1/src/libjasper/include/jasper/jas_math.h	2017-03-24 22:29:36.085024105 +0100
@@ -76,9 +76,13 @@
 
 #include <jasper/jas_config.h>
 
-#include	<assert.h>
-#include	<stdio.h>
-#include	<string.h>
+#include <jasper/jas_types.h>
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include <stdint.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -110,6 +114,62 @@ extern "C" {
 #define	JAS_ONES(n) \
   ((1 << (n)) - 1)
 
+/******************************************************************************\
+* Safe integer arithmetic (i.e., with overflow checking).
+\******************************************************************************/
+
+/* Compute the product of two size_t integers with overflow checking. */
+inline static bool jas_safe_size_mul(size_t x, size_t y, size_t *result)
+{
+	/* Check if overflow would occur */
+	if (x && y > SIZE_MAX / x) {
+		/* Overflow would occur. */
+		return false;
+	}
+	if (result) {
+		*result = x * y;
+	}
+	return true;
+}
+
+inline static bool jas_safe_size_mul3(size_t a, size_t b, size_t c,
+  size_t *result)
+{
+	size_t tmp;
+	if (!jas_safe_size_mul(a, b, &tmp) ||
+	  !jas_safe_size_mul(tmp, c, &tmp)) {
+		return false;
+	}
+	if (result) {
+		*result = tmp;
+	}
+	return true;
+}
+
+/* Compute the sum of two size_t integer with overflow checking. */
+inline static bool jas_safe_size_add(size_t x, size_t y, size_t *result)
+{
+	if (y > SIZE_MAX - x) {
+		return false;
+	}
+	if (result) {
+		*result = x + y;
+	}
+	return true;
+}
+
+/* Compute the difference of two size_t integer with overflow checking. */
+inline static bool jas_safe_size_sub(size_t x, size_t y, size_t *result)
+{
+	if (y > x) {
+		return false;
+	}
+	if (result) {
+		*result = x - y;
+	}
+	return true;
+}
+
 #ifdef __cplusplus
 }
 #endif