Backport of the upstream commit: From b35a05635e56f554870ce85f64293a3868793f69 Mon Sep 17 00:00:00 2001 From: Michael Adams 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 #include #include +#include #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 -#include -#include -#include +#include + +#include +#include +#include +#include +#include #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