------------- 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