oss-sec mailing list archives

Security issues in JasPer (CVE-2016-1577 and CVE-2016-2116)


From: Tyler Hicks <tyhicks () canonical com>
Date: Thu, 3 Mar 2016 08:36:12 -0600

-------------
CVE-2016-1577
-------------

Jacob Baines discovered[1] that a double free vulnerability in the
jas_iccattrval_destroy function in JasPer 1.900.1 and earlier allows
remote attackers to cause a denial of service (crash) or possibly
execute arbitrary code via a crafted ICC color profile in a JPEG 2000
image file, a different vulnerability than CVE-2014-8137. This double
free issue was assigned CVE-2016-1577.

In the code snippet below, attrval variable is assigned on line 298 and freed
with the call to jas_iccattrval_destroy() on line 302. If the tests on lines
312, 321, or 324 are true, the same pointer will be passed a second time
to jas_iccattrval_destroy() on line 357.

src/libjasper/base/jas_icc.c:
258     jas_iccprof_t *jas_iccprof_load(jas_stream_t *in)
259     {
...
294             for (i = 0; i < numtags; ++i) {
295                     tagtabent = &prof->tagtab.ents[i];
296                     if (tagtabent->off == JAS_CAST(jas_iccuint32_t, prevoff)) {
297                             if (prevattrval) {
298                                     if (!(attrval = jas_iccattrval_clone(prevattrval)))
299                                             goto error;
300                                     if (jas_iccprof_setattr(prof, tagtabent->tag, attrval))
301                                             goto error;
302                                     jas_iccattrval_destroy(attrval);
303                             } else {
304     #if 0
305                                     jas_eprintf("warning: skipping unknown tag type\n");
306     #endif
307                             }
308                             continue;
309                     }
310                     reloff = tagtabent->off - curoff;
311                     if (reloff > 0) {
312                             if (jas_stream_gobble(in, reloff) != reloff)
313                                     goto error;
314                             curoff += reloff;
315                     } else if (reloff < 0) {
316                             /* This should never happen since we read the tagged
317                             element data in a single pass. */
318                             abort();
319                     }
320                     prevoff = curoff;
321                     if (jas_iccgetuint32(in, &type)) {
322                             goto error;
323                     }
324                     if (jas_stream_gobble(in, 4) != 4) {
325                             goto error;
326                     }
327                     curoff += 8;
328                     if (!(attrvalinfo = jas_iccattrvalinfo_lookup(type))) {
329     #if 0
330                             jas_eprintf("warning: skipping unknown tag type\n");
331     #endif
332                             prevattrval = 0;
333                             continue;
334                     }
335                     if (!(attrval = jas_iccattrval_create(type))) {
336                             goto error;
337                     }
...
353     error:
354             if (prof)
355                     jas_iccprof_destroy(prof);
356             if (attrval)
357                     jas_iccattrval_destroy(attrval);
358             return 0;
359     }

I've attached a patch to fix the issue by setting the attrval variable
to NULL after it is initially freed. See the original bug report[1] for
an image file to reproduce this issue.

-------------
CVE-2016-2116
-------------

While testing the fix for the issue above, I discovered that a memory
leak in the jas_iccprof_createfrombuf function in JasPer 1.900.1 and
earlier allows remote attackers to cause a denial of service (memory
consumption) via a crafted ICC color profile in a JPEG 2000 image file.
This memory leak issue was assigned CVE-2016-2116. 

Valgrind says 8,352 bytes are leaked per call to jas_image_decode():

$ valgrind --leak-check=full imginfo -f bad.jp2 
==3131== Memcheck, a memory error detector
==3131== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==3131== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==3131== Command: imginfo -f bad.jp2
==3131== 
error: failed to parse ICC profile
cannot load image
==3131== 
==3131== HEAP SUMMARY:
==3131==     in use at exit: 20,772 bytes in 6 blocks
==3131==   total heap usage: 1,116 allocs, 1,110 frees, 502,815 bytes allocated
==3131== 
==3131== 8,352 (104 direct, 8,248 indirect) bytes in 1 blocks are definitely lost in loss record 5 of 6
==3131==    at 0x4C2BBCF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3131==    by 0x4E4AF0D: ??? (in /usr/lib/x86_64-linux-gnu/libjasper.so.1.0.0)
==3131==    by 0x4E4BFF4: jas_stream_memopen (in /usr/lib/x86_64-linux-gnu/libjasper.so.1.0.0)
==3131==    by 0x4E49E7A: jas_iccprof_createfrombuf (in /usr/lib/x86_64-linux-gnu/libjasper.so.1.0.0)
==3131==    by 0x4E50571: jp2_decode (in /usr/lib/x86_64-linux-gnu/libjasper.so.1.0.0)
==3131==    by 0x4E44EAC: jas_image_decode (in /usr/lib/x86_64-linux-gnu/libjasper.so.1.0.0)
==3131==    by 0x400C71: ??? (in /usr/bin/imginfo)
==3131==    by 0x50AF9FF: (below main) (libc-start.c:289)
==3131== 
==3131== 12,420 (104 direct, 12,316 indirect) bytes in 1 blocks are definitely lost in loss record 6 of 6
==3131==    at 0x4C2BBCF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3131==    by 0x4E4AF0D: ??? (in /usr/lib/x86_64-linux-gnu/libjasper.so.1.0.0)
==3131==    by 0x4E4B384: jas_stream_fopen (in /usr/lib/x86_64-linux-gnu/libjasper.so.1.0.0)
==3131==    by 0x400C47: ??? (in /usr/bin/imginfo)
==3131==    by 0x50AF9FF: (below main) (libc-start.c:289)
==3131== 
==3131== LEAK SUMMARY:
==3131==    definitely lost: 208 bytes in 2 blocks
==3131==    indirectly lost: 20,564 bytes in 4 blocks
==3131==      possibly lost: 0 bytes in 0 blocks
==3131==    still reachable: 0 bytes in 0 blocks
==3131==         suppressed: 0 bytes in 0 blocks
==3131== 
==3131== For counts of detected and suppressed errors, rerun with: -v
==3131== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

Ignore the second memory leak (12,420 bytes) as it is a leak in imginfo and not
libjasper.

In the following snippet, the jas_stream_t allocated by the call to
jas_stream_memopen() is leaked if jas_iccprof_load() fails on line 1691.

src/libjasper/base/jas_icc.c:
1685    jas_iccprof_t *jas_iccprof_createfrombuf(uchar *buf, int len)
1686    {
1687            jas_stream_t *in;
1688            jas_iccprof_t *prof;
1689            if (!(in = jas_stream_memopen(JAS_CAST(char *, buf), len)))
1690                    goto error;
1691            if (!(prof = jas_iccprof_load(in)))
1692                    goto error;
1693            jas_stream_close(in);
1694            return prof;
1695    error:
1696            return 0;
1697    }

I've attached a patch that fixes the issue by closing the jas_stream_t
in the error path.

[1] https://launchpad.net/bugs/1547865

Tyler

Attachment: CVE-2016-1577.patch
Description:

Attachment: CVE-2016-2116.patch
Description:

Attachment: signature.asc
Description:


Current thread: