From bb7d62bd0a2a8e0e1fdb4d603f3305f955158c52 Mon Sep 17 00:00:00 2001 From: Michael Adams Date: Tue, 29 Jul 2025 20:16:35 -0700 Subject: [PATCH] Fixes #400. Added a check for a missing color component in the jas_image_chclrspc function. CVE: CVE-2025-8835 Upstream: https://github.com/jasper-software/jasper/commit/bb7d62bd0a2a8e0e1fdb4d603f3305f955158c52 [thomas: backport to v2.0.33] Signed-off-by: Thomas Perale --- src/libjasper/base/jas_image.c | 71 ++++++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 12 deletions(-) diff --git a/src/libjasper/base/jas_image.c b/src/libjasper/base/jas_image.c index 68a94e1..cd99ba2 100644 --- a/src/libjasper/base/jas_image.c +++ b/src/libjasper/base/jas_image.c @@ -112,6 +112,8 @@ static long convert(long val, bool oldsgnd, unsigned oldprec, bool newsgnd, unsigned newprec); static void jas_image_calcbbox2(const jas_image_t *image, jas_image_coord_t *tlx, jas_image_coord_t *tly, jas_image_coord_t *brx, jas_image_coord_t *bry); +static jas_cmcmptfmt_t* jas_cmcmptfmt_array_create(int n); +static void jas_cmcmptfmt_array_destroy(jas_cmcmptfmt_t* cmptfmts, int n); /******************************************************************************\ * Global data. @@ -409,6 +411,31 @@ static void jas_image_cmpt_destroy(jas_image_cmpt_t *cmpt) jas_free(cmpt); } +static jas_cmcmptfmt_t* jas_cmcmptfmt_array_create(int n) +{ + jas_cmcmptfmt_t* cmptfmts; + if (!(cmptfmts = jas_alloc2(n, sizeof(jas_cmcmptfmt_t)))) { + return 0; + } + for (int i = 0; i < n; ++i) { + cmptfmts[i].buf = 0; + } + return cmptfmts; +} + +static void jas_cmcmptfmt_array_destroy(jas_cmcmptfmt_t* cmptfmts, int n) +{ + assert(cmptfmts); + assert(n > 0); + for (int i = 0; i < n; ++i) { + if (cmptfmts[i].buf) { + jas_free(cmptfmts[i].buf); + } + cmptfmts[i].buf = 0; + } + jas_free(cmptfmts); +} + /******************************************************************************\ * Load and save operations. \******************************************************************************/ @@ -1470,19 +1497,25 @@ jas_image_t *jas_image_chclrspc(jas_image_t *image, const jas_cmprof_t *outprof, jas_cmcmptfmt_t *incmptfmts; jas_cmcmptfmt_t *outcmptfmts; + assert(image); + assert(outprof); + #if 0 jas_eprintf("IMAGE\n"); jas_image_dump(image, stderr); #endif - if (image->numcmpts_ == 0) + if (!jas_image_numcmpts(image)) { /* can't work with a file with no components; continuing would crash because we'd attempt to obtain information about the first component */ return NULL; + } outimage = 0; xform = 0; + incmptfmts = 0; + outcmptfmts = 0; if (!(inimage = jas_image_copy(image))) goto error; image = 0; @@ -1565,15 +1598,21 @@ jas_image_dump(image, stderr); } inpixmap.numcmpts = numinclrchans; - if (!(incmptfmts = jas_alloc2(numinclrchans, sizeof(jas_cmcmptfmt_t)))) { + assert(numinclrchans != 0); + if (!(incmptfmts = jas_cmcmptfmt_array_create(numinclrchans))) { abort(); } inpixmap.cmptfmts = incmptfmts; for (unsigned i = 0; i < numinclrchans; ++i) { const int j = jas_image_getcmptbytype(inimage, JAS_IMAGE_CT_COLOR(i)); + if (j < 0) { + jas_eprintf("missing color component %d\n", i); + goto error; + } if (!(incmptfmts[i].buf = jas_alloc2(width, sizeof(long)))) { goto error; } + assert(j >= 0 && j < jas_image_numcmpts(inimage)); incmptfmts[i].prec = jas_image_cmptprec(inimage, j); incmptfmts[i].sgnd = jas_image_cmptsgnd(inimage, j); incmptfmts[i].width = width; @@ -1581,15 +1620,21 @@ jas_image_dump(image, stderr); } outpixmap.numcmpts = numoutclrchans; - if (!(outcmptfmts = jas_alloc2(numoutclrchans, sizeof(jas_cmcmptfmt_t)))) { + if (!(outcmptfmts = jas_cmcmptfmt_array_create(numoutclrchans))) { abort(); } outpixmap.cmptfmts = outcmptfmts; for (unsigned i = 0; i < numoutclrchans; ++i) { const int j = jas_image_getcmptbytype(outimage, JAS_IMAGE_CT_COLOR(i)); - if (!(outcmptfmts[i].buf = jas_alloc2(width, sizeof(long)))) + if (j < 0) { + jas_eprintf("missing color component %d\n", i); goto error; + } + if (!(outcmptfmts[i].buf = jas_alloc2(width, sizeof(long)))) { + goto error; + } + assert(j >= 0 && j < jas_image_numcmpts(outimage)); outcmptfmts[i].prec = jas_image_cmptprec(outimage, j); outcmptfmts[i].sgnd = jas_image_cmptsgnd(outimage, j); outcmptfmts[i].width = width; @@ -1612,14 +1657,8 @@ jas_image_dump(image, stderr); } } - for (unsigned i = 0; i < numoutclrchans; ++i) { - jas_free(outcmptfmts[i].buf); - } - jas_free(outcmptfmts); - for (unsigned i = 0; i < numinclrchans; ++i) { - jas_free(incmptfmts[i].buf); - } - jas_free(incmptfmts); + jas_cmcmptfmt_array_destroy(outcmptfmts, numoutclrchans); + jas_cmcmptfmt_array_destroy(incmptfmts, numinclrchans); jas_cmxform_destroy(xform); jas_image_destroy(inimage); @@ -1631,6 +1670,14 @@ jas_image_dump(outimage, stderr); #endif return outimage; error: + if (incmptfmts) { + assert(numinclrchans); + jas_cmcmptfmt_array_destroy(incmptfmts, numinclrchans); + } + if (outcmptfmts) { + assert(numoutclrchans); + jas_cmcmptfmt_array_destroy(outcmptfmts, numoutclrchans); + } if (xform) jas_cmxform_destroy(xform); if (inimage) -- 2.39.5