openjpeg
openjpeg copied to clipboard
memory exhauted and hangs long time when use 64bit opj_decompress (CVE-2019-6988)
I found a problem which will cause memory is exhausted, and program hang for 8 minutes. My test server had 112GB of memory. This can cause denial of service.
Steps to Reproduce
- Download and unzip [POC.zip] POC.zip
- Run
opj_decompress -i POC -o /tmp/1.png - When I test it use 32bit opj_decompress with asan, the following is the output information
===========================================
The extension of this file is incorrect.
FOUND p:16. SHOULD BE .j2k or .jpc or .j2c
===========================================
[INFO] Start to read j2k main header (0).
[WARNING] Unknown marker
[WARNING] Unknown marker
[WARNING] Cannot take in charge mct data within multiple MCT records
[WARNING] Unknown marker
[ERROR] Unknown progression order in COD marker
[WARNING] Unknown marker
[WARNING] Cannot take in charge mct data within multiple MCT records
[WARNING] Unknown marker
[ERROR] Unknown progression order in COD marker
[WARNING] Unknown marker
[WARNING] Cannot take in charge mct data within multiple MCT records
[WARNING] Unknown marker
[ERROR] Unknown progression order in COD marker
[WARNING] Unknown marker
[INFO] Main header has been correctly decoded.
[INFO] No decoded area parameters, set the decoded area to the whole image
=================================================================
==26110==ERROR: AddressSanitizer: allocator is out of memory trying to allocate 0x2f4ad890 bytes
#0 0x81083a5 in calloc /soft/clang/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:155:3
#1 0xf7dda139 in opj_calloc ./openjpeg/src/lib/openjp2/opj_malloc.c:204:12
#2 0xf7d7685c in opj_tcd_init_tile ./openjpeg/src/lib/openjp2/tcd.c:1111:56
#3 0xf7d87c0f in opj_tcd_init_decode_tile ./openjpeg/src/lib/openjp2/tcd.c:1184:12
#4 0xf793a827 in opj_j2k_decode_tiles ./openjpeg/src/lib/openjp2/j2k.c:10717:19
#5 0xf785ba1c in opj_j2k_exec ./openjpeg/src/lib/openjp2/j2k.c:8105:33
Analysis
- Alloc too much big memory.
- Maybe too many cycles
System Configuration
- version: git commit 51f097e6d5754ddae93e716276fe8176b44ec548
- Environment: Ubuntu 16.04.3 TLS
- Memery Size: 112GB
- component: 64bit opj_decompress
These vulnerabilities have been found with a more efficient version of the AFL fuzzer.
I have a simple JPEG2000 reader. Using it I found:
NAME(/tmp/POC.j2k)
LENG(2694)
ENTER read_jp2c
[0]marker(0xff4f)
soc len(0)
[2]marker(0xff51)
siz len(50)
capabilities(0)[extended: 0]
x(0 : 2147418112) y(16 : 67108896)
xt(0 : 377547551) yt(0 : 4194336)
IMAGE w(2147418112) h(67108880) TILE w(377547551) h(4194336)
nr_components(4)
component[0] signed(0) prec(2) hsep(1) vsep(231)
component[1] signed(1) prec(12) hsep(1) vsep(255)
component[2] signed(0) prec(2) hsep(1) vsep(1)
component[3] signed(0) prec(1) hsep(222) vsep(255)
[54]marker(0xffff)
test_marker: type(0xffff) prefix(0xff) suffix(0xff)
I :MARKER 0xffff is unknown.
EXIT read_jp2c
end - s ==> -62899
EXIT with end - s ==> 0 (DEC:0)
winfried
Should memory checks be added to the program? Otherwise the memory will be exhausted.
@yanxdd , @rouault ,
j2k.c, line 9497:
==================
/* in the absence of JP2 boxes, consider different bit depth / sign */
/* per component is allowed */
l_j2k->m_cp.allow_different_bit_depth_sign = 1;
j2k.c, line 2237:
==================
} else if (!l_cp->allow_different_bit_depth_sign
&& (l_img_comp->prec != l_prec0 || l_img_comp->sgnd != l_sgnd0)) {
opj_event_msg(p_manager, EVT_WARNING,
"Despite JP2 BPC!=255, precision and/or sgnd values for comp[%d] is different than comp[0]:\n"
" [0] prec(%d) sgnd(%d) [%d] prec(%d) sgnd(%d)\n", i, l_prec0, l_sgnd0,
i, l_img_comp->prec, l_img_comp->sgnd);
}
JP2 BPC!=255 : jp2->bpc gets a value in jp2.c .
Why a WARNING for allowed values?
All decompressors explicitly ask for equal values,
e.g. convertpng.c, line 321:
==================================================
fprintf(stderr,
"imagetopng: All components shall have the same subsampling, same bit depth, same sign.\n");
fprintf(stderr, "\tAborting\n");
Testing dx and dy in j2k.c, I get:
===================================
[INFO] Start to read j2k main header (0).
openjpeg2-2018-12-26/src/lib/openjp2/j2k.c:2248:
[0] prec0(2) prec(2) sgnd0(0) sgnd(0)
openjpeg2-2018-12-26/src/lib/openjp2/j2k.c:2248:
[1] prec0(2) prec(12) sgnd0(0) sgnd(1)
openjpeg2-2018-12-26/src/lib/openjp2/j2k.c:2270:
[1] dx0(1) dx(1) dy0(231) dy(255)
[ERROR] dy(255) != dy0(231)
[ERROR] Marker handler function failed to read the marker segment
ERROR -> opj_decompress: failed to read the header
winfried
This was assigned CVE-2019-6988.
@yanxxd is this issue invalid, or was it fixed at some point?
If this issue is invalid, we should ask for CVE rejection.
@yanxxd pinging you again, has this issue been fixed by now or was it invalid?
I tested it use the latest version, git commit 563ecfb55ca77c0fc5ea19e4885e00f55ec82ca9. The program run about 10 minutes, CPU 100%, MEM 100%. The following is the output:
opj_decompress -i POC -o /tmp/1.png
===========================================
The extension of this file is incorrect.
FOUND /POC. SHOULD BE .j2k or .jpc or .j2c
===========================================
[INFO] Start to read j2k main header (0).
[WARNING] Unknown marker
[WARNING] Unknown marker
[WARNING] Cannot take in charge mct data within multiple MCT records
[WARNING] Unknown marker
[ERROR] Unknown progression order in COD marker
[WARNING] Unknown marker
[WARNING] Cannot take in charge mct data within multiple MCT records
[WARNING] Unknown marker
[ERROR] Unknown progression order in COD marker
[WARNING] Unknown marker
[WARNING] Cannot take in charge mct data within multiple MCT records
[WARNING] Unknown marker
[ERROR] Unknown progression order in COD marker
[WARNING] Unknown marker
[INFO] Main header has been correctly decoded.
[INFO] No decoded area parameters, set the decoded area to the whole image
Killed
You can reproduce it use the POC.
Thanks! Perhaps this issue should be reopened then.
While for this particular file (POC), we could bail out earlier given a number of corruptions in segment markers, this wouldn't fix the underlying issue. This issue is a design one. The library pre-allocates precints and codeblocks related structures, such as tagtree, for a whole tile. In the case of POC, there are for example 37 million codeblocks for one precinct, which represents 4 GB of RAM for the codeblock working memory (and other GB for tagtree etc). Completely legit JPEG2000 images could be built with the same characteristics as those corrupted images, and with sufficient huge amount of RAM could be docoded. As fixing the design of openjpeg would be enormous work, a fix would probably to set some implementation-defined thresholds, not normally reached on "normal" images, and error out if they are reached, and let the user able to override them with some environment variable.
Setting some implementation-defined thresholds may be a viable solution.
Any news on this?
Hiya! Any ETA on this!?
@yanxxd can you reproduce CVE-2019-6988 using opj 2.4.0 ?
Hi, Any update on the issue?
Hi, Any update on the issue?
@yanxxd @rouault
-
I have investigated the problem recently. I found there is commit which has "solved" the problem. The commit is: f3ee448 openjp2/j2k: Validate all SGcod/SPcod/SPcoc parameter values..
-
After some debugging, I found the code which has "solved" the problem:
if (l_tccp->qmfbid > 1) { opj_event_msg(p_manager, EVT_ERROR, "Error reading SPCod SPCoc element, Invalid transformation found\n"); return OPJ_FALSE; } -
l_tccp->qmfbid's value is 255 and it's greater than 1, so the function will return false. Finally, the program will exit. According the spec, l_tccp->qmfbid's valid value shoud be 0 or 1.
-
This is the output: =========================================== The extension of this file is incorrect. FOUND /POC. SHOULD BE .j2k or .jpc or .j2c ===========================================
[INFO] Start to read j2k main header (0). [WARNING] Unknown marker [WARNING] Unknown marker [WARNING] Cannot take in charge mct data within multiple MCT records [WARNING] Unknown marker [ERROR] Unknown progression order in COD marker [ERROR] Error reading SPCod SPCoc element, Invalid transformation found [ERROR] Error reading COD marker [ERROR] Marker handler function failed to read the marker segment ERROR -> opj_decompress: failed to read the header