CVE-2016-7163 OpenJPEG opj_pi_create_decode Integer Overflow Vulnerability

Disclosed: 2019-11-12 23:54:28 By binvul To ibb
Unknown
Vulnerability Details
# OpenJPEG opj_pi_create_decode Integer Overflow Vulnerability ## 1. About OpenJPEG OpenJPEG is an open-source JPEG 2000 codec written in C language. It's widely used in lots of Linux OSes such as Ubuntu, RedHat, Debian, Fedora, and so on. The official repository of the OpenJPEG project is available at [GitHub](https://github.com/uclouvain/openjpeg). ## 2. Credit This vulnerability was discovered by Ke Liu of Tencent's Xuanwu LAB. ## 3. Testing Environments + **OS**: Ubuntu + **OpenJPEG**: [4a2a869](https://github.com/uclouvain/openjpeg/archive/4a2a8693e5a02207a8813b02a375abdc4e43c49b.zip) (Master version before Aug/6/2016) + **Compiler**: Clang + **CFLAGS**: ``-g -O0 -fsanitize=address`` ## 4. Reproduce Steps Please copy file ``poc.jp2`` to directory ``openjpeg/bin`` before executing ``opj_decompress``. ``` wget https://github.com/uclouvain/openjpeg/archive/4a2a8693e5a02207a8813b02a375abdc4e43c49b.zip unzip -q 4a2a8693e5a02207a8813b02a375abdc4e43c49b.zip mv openjpeg-4a2a8693e5a02207a8813b02a375abdc4e43c49b openjpeg cd openjpeg export CC='/usr/bin/clang -g -O0 -fsanitize=address' cmake . make cd bin ./opj_decompress -o image.pgm -i poc.jp2 ``` ## 5. Vulnerability Details An integer overflow issue exists in function opj_pi_create_decode of pi.c. It can lead to Out-Of-Bounds Read and Out-Of-Bounds Write in function opj_pi_next_cprl of pi.c (function opj_pi_next_lrcp, opj_pi_next_rlcp, opj_pi_next_rpcl, opj_pi_next_pcrl may also be vulnerable). + OOB read and OOB write exist in function opj_pi_next_cprl, function opj_pi_next_lrcp, opj_pi_next_rlcp, opj_pi_next_rpcl, opj_pi_next_pcrl may also be vulnerable. ``` static OPJ_BOOL opj_pi_next_cprl(opj_pi_iterator_t * pi) { // ... for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) { index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; if (!pi->include[index]) { // ----> Out-Of-Bounds Read!!! pi->include[index] = 1; // ----> Out-Of-Bounds Write!!! return OPJ_TRUE; } // ... return OPJ_FALSE; } ``` + Integer overflow exists in function opj_pi_create_decode. ``` opj_pi_iterator_t *opj_pi_create_decode(opj_image_t *p_image, opj_cp_t *p_cp, OPJ_UINT32 p_tile_no) { // ... l_step_p = 1; l_step_c = l_max_prec * l_step_p; l_step_r = p_image->numcomps * l_step_c; l_step_l = l_max_res * l_step_r; /* set values for first packet iterator */ l_current_pi = l_pi; /* memory allocation for include */ l_current_pi->include = (OPJ_INT16*) opj_calloc( (l_tcp->numlayers +1) * l_step_l, sizeof(OPJ_INT16)); // ----> Integer Overflow!!! // ... } ``` + AddressSanitizer output the following exception information. ``` ==10074==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xad9370a0 at pc 0xb767ba50 bp 0xbff1ad78 sp 0xbff1ad70 READ of size 2 at 0xad9370a0 thread T0 #0 0xb767ba4f in opj_pi_next_cprl src/lib/openjp2/pi.c:541:12 #1 0xb76644e7 in opj_pi_next src/lib/openjp2/pi.c:1872:11 #2 0xb76cd0af in opj_t2_decode_packets src/lib/openjp2/t2.c:412:24 #3 0xb771ee6e in opj_tcd_t2_decode src/lib/openjp2/tcd.c:1547:15 #4 0xb771de16 in opj_tcd_decode_tile src/lib/openjp2/tcd.c:1286:15 #5 0xb74d7a0e in opj_j2k_decode_tile src/lib/openjp2/j2k.c:8134:15 #6 0xb7563354 in opj_j2k_decode_tiles src/lib/openjp2/j2k.c:9761:23 #7 0xb74bce4c in opj_j2k_exec src/lib/openjp2/j2k.c:7350:43 #8 0xb74f378b in opj_j2k_decode src/lib/openjp2/j2k.c:9959:15 #9 0xb75b80de in opj_jp2_decode src/lib/openjp2/jp2.c:1492:8 #10 0xb7622eb8 in opj_decode src/lib/openjp2/openjpeg.c:412:10 #11 0x8140304 in main src/bin/jp2/opj_decompress.c:1332:10 #12 0xb71b9af2 in __libc_start_main /build/eglibc-X4bnBz/eglibc-2.19/csu/libc-start.c:287 #13 0x80781eb in _start (bin/opj_decompress+0x80781eb) AddressSanitizer can not describe address in more detail (wild memory access suspected). SUMMARY: AddressSanitizer: heap-buffer-overflow src/lib/openjp2/pi.c:541 opj_pi_next_cprl Shadow bytes around the buggy address: 0x35b26dc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x35b26dd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x35b26de0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x35b26df0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x35b26e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa =>0x35b26e10: fa fa fa fa[fa]fa fa fa fa fa fa fa fa fa fa fa 0x35b26e20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x35b26e30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x35b26e40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x35b26e50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x35b26e60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Heap right redzone: fb Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==10074==ABORTING ``` ## 6. Timeline + 2016.08.20 - Found + 2016.08.22 - Reported to OpenJPEG via [email protected] + 2016.09.08 - Fixed + 2016.09.08 - Publicly disclosed ## 7. References + [OpenJPEG Patch 1](https://github.com/uclouvain/openjpeg/commit/c16bc057ba3f125051c9966cf1f5b68a05681de4) + [OpenJPEG Patch 2](https://github.com/uclouvain/openjpeg/commit/ef01f18dfc6780b776d0674ed3e7415c6ef54d24) + [oss-sec CVE Request](http://seclists.org/oss-sec/2016/q3/439)
Actions
View on HackerOne
Report Stats
  • Report ID: 167512
  • State: Closed
  • Substate: resolved
  • Upvotes: 3
Share this report