An issue was discovered in JasPer 2.0.14. There is a heap-based buffer over-read of size 8 in the function jas_image_depalettize in libjasper/base/jas_image.c. References: https://github.com/mdadams/jasper/issues/182
Created jasper tracking bugs for this issue: Affects: fedora-all [bug 1658787] Created mingw-jasper tracking bugs for this issue: Affects: epel-7 [bug 1658789] Affects: fedora-all [bug 1658788]
``` ==30795== Memcheck, a memory error detector ==30795== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==30795== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==30795== Command: jasper --input jasper_bug_1.jp2 --output-format mif ==30795== warning: number of components mismatch ==30795== Invalid read of size 8 ==30795== at 0x4E47AAE: jas_image_depalettize (jas_image.c:904) ==30795== by 0x4E5949B: jp2_decode (jp2_dec.c:365) ==30795== by 0x4E46337: jas_image_decode (jas_image.c:388) ==30795== by 0x401554: main (jasper.c:229) ==30795== Address 0x6d28668 is 8 bytes before a block of size 0 alloc'd ==30795== at 0x4C29BC3: malloc (vg_replace_malloc.c:299) ==30795== by 0x4E4F0FC: jas_malloc (jas_malloc.c:109) ==30795== by 0x4E4F21E: jas_alloc2 (jas_malloc.c:141) ==30795== by 0x4E5936E: jp2_decode (jp2_dec.c:360) ==30795== by 0x4E46337: jas_image_decode (jas_image.c:388) ==30795== by 0x401554: main (jasper.c:229) ==30795== ``` Brings us here: ```c v = jas_image_readcmptsample(image, cmptno, i, j); if (v < 0) { v = 0; } else if (v >= numlutents) { v = numlutents - 1; } jas_image_writecmptsample(image, newcmptno, i, j, lutents[v]); } ``` In this vulnerability, numlutents can be set to 0. Thus, v = numlutents - 1 = -1. This is then indexed into the lutents[v] array read passed to jas_image_writecmtsample. ``` (gdb) print sizeof(lutents[v]) $37 = 8 (gdb) ptype lutents[v] type = long ``` hence the read of size 8. lutents[-1] is out-of-bounds. This value is passed into jas_image_writecmptsample. ``` if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * y + x) * cmpt->cps_, SEEK_SET) < 0) { return; } t = inttobits(v, cmpt->prec_, cmpt->sgnd_); for (k = cmpt->cps_; k > 0; --k) { c = (t >> (8 * (cmpt->cps_ - 1))) & 0xff; if (jas_stream_putc(cmpt->stream_, (unsigned char) c) == EOF) { return; } t <<= 8; } } ``` v modifies t, which is then masked to one byte, which is then written to cmpt->stream_. Thus, it appears that this is an out-of-bounds read that may be able to leak a byte of information before the lutents array (which I presume is heap metadata based on `lutents = jas_alloc2(pclrd->numlutents, sizeof(int_fast32_t));`) So, while it is always possibe that this could somehow lead to code execution downstream (ruling that out is vastly time consuming and often nearly impossible), it seems highly unlikely in this case. What is more likely, but still challenging, would be some sort of minor information leak. Upgraded CVE to 4.4/CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:L because of this. Low still feels highly appropriate as I don't have any evidence of DoS or an infoleak at this point -- just theoretical.
Accidentally set I:L instead of C:L. Was thinking (I)nformation leak and made a mistake last Friday. Updated.