Project: openjpeg (uclouvain/openjpeg), language: c++
Vulnerability instance: openjpeg.cve-2021-3575
Sanitizer: address

================= Bug Report (1/2) ==================
## Source: GitHub Issue
## URL: https://github.com/uclouvain/openjpeg/issues/1347
## Description:
Issue: uclouvain/openjpeg#1347
Title: Heap-buffer-overflow in color.c:379:42 in sycc420_to_rgb
State: closed
Created by: yuawn
Created at: 2021-04-30 00:10:00+00:00

Issue Body:
Hi,
I found a vulnerability in current master [0bda718](https://github.com/uclouvain/openjpeg/commit/0bda7188b7b545232a341f1d978b1e4feda46fc2), and I also reproduced it on latest released version [v2.4.0](https://github.com/uclouvain/openjpeg/releases/tag/v2.4.0).

**Crash Summary**
A heap-buffer-overflow in color.c:379:42 in sycc420_to_rgb, it can lead to heap-based buffer overflow via a crafted `.j2k` file when decompress it.

**Crash Analysis**
There is insufficient validation of `*cb`.
https://github.com/uclouvain/openjpeg/blob/0bda7188b7b545232a341f1d978b1e4feda46fc2/src/bin/common/color.c#L375-L381

**PoC:**
[poc.j2k.gz](https://github.com/uclouvain/openjpeg/files/6402272/poc.j2k.gz)

**To reproduce (x86-64 Ubuntu 20.04.2 with gcc 9.3.0):**
```bash
CFLAGS='-g -fsanitize=address' cmake .. -DCMAKE_BUILD_TYPE=Release
make

./bin/opj_decompress -i ./poc.j2k -o out.png
```

**ASAN report:**
```
=================================================================
==2371124==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x612000000760 at pc 0x0000004f278c bp 0x7ffd11a3eca0 sp 0x7ffd11a3ec98
READ of size 4 at 0x612000000760 thread T0
    #0 0x4f278b in sycc420_to_rgb /home/yuawn/fuzz-targets/openjpeg/reproduce/openjpeg/src/bin/common/color.c:379:42
    #1 0x4f278b in color_sycc_to_rgb /home/yuawn/fuzz-targets/openjpeg/reproduce/openjpeg/src/bin/common/color.c:416:9
    #2 0x4cb136 in main /home/yuawn/fuzz-targets/openjpeg/reproduce/openjpeg/src/bin/jp2/opj_decompress.c:1589:13
    #3 0x7f653bef10b2 in __libc_start_main /build/glibc-YbNSs7/glibc-2.31/csu/../csu/libc-start.c:308:16
    #4 0x41d4fd in _start (/home/yuawn/fuzz-targets/openjpeg/reproduce/openjpeg/build/bin/opj_decompress+0x41d4fd)

0x612000000760 is located 0 bytes to the right of 288-byte region [0x612000000640,0x612000000760)
allocated by thread T0 here:
    #0 0x498027 in posix_memalign (/home/yuawn/fuzz-targets/openjpeg/reproduce/openjpeg/build/bin/opj_decompress+0x498027)
    #1 0x7f653c38aa5f in opj_aligned_alloc_n /home/yuawn/fuzz-targets/openjpeg/reproduce/openjpeg/src/lib/openjp2/opj_malloc.c:61:9
    #2 0x7f653c38aa5f in opj_aligned_malloc /home/yuawn/fuzz-targets/openjpeg/reproduce/openjpeg/src/lib/openjp2/opj_malloc.c:209:12
    #3 0x7f653c37c257 in opj_alloc_tile_component_data /home/yuawn/fuzz-targets/openjpeg/reproduce/openjpeg/src/lib/openjp2/tcd.c:697:39
    #4 0x7f653c37c257 in opj_tcd_decode_tile /home/yuawn/fuzz-targets/openjpeg/reproduce/openjpeg/src/lib/openjp2/tcd.c:1561:18
    #5 0x7f653c2d6131 in opj_j2k_decode_tile /home/yuawn/fuzz-targets/openjpeg/reproduce/openjpeg/src/lib/openjp2/j2k.c:9727:11
    #6 0x7f653c2f275e in opj_j2k_decode_tiles /home/yuawn/fuzz-targets/openjpeg/reproduce/openjpeg/src/lib/openjp2/j2k.c:11568:15
    #7 0x7f653c2dba43 in opj_j2k_exec /home/yuawn/fuzz-targets/openjpeg/reproduce/openjpeg/src/lib/openjp2/j2k.c:8871:33
    #8 0x7f653c2dba43 in opj_j2k_decode /home/yuawn/fuzz-targets/openjpeg/reproduce/openjpeg/src/lib/openjp2/j2k.c:11871:11

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/yuawn/fuzz-targets/openjpeg/reproduce/openjpeg/src/bin/common/color.c:379:42 in sycc420_to_rgb
Shadow bytes around the buggy address:
  0x0c247fff8090: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c247fff80a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c247fff80b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c247fff80c0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c247fff80d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c247fff80e0: 00 00 00 00 00 00 00 00 00 00 00 00[fa]fa fa fa
  0x0c247fff80f0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c247fff8100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c247fff8110: 00 00 00 00 00 00 00 00 00 00 00 00 fa fa fa fa
  0x0c247fff8120: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c247fff8130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  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
  Shadow gap:              cc
==2371124==ABORTING
```


Comments:
Comment by szukw000 on 2021-05-04 13:58:09+00:00:
@yuawn ,
I use the library from 10.01.2021.

szukw000: opj_decompress -i poc.j2k -o poc.j2k.png

[INFO] Start to read j2k main header (0).
[ERROR] Unknown progression order in COD marker
[WARNING] Unknown marker
[ERROR] Unknown progression order in COD marker
[WARNING] Unknown marker
[WARNING] Unknown marker
[WARNING] Unknown marker
[ERROR] Unknown progression order in COD marker
[WARNING] Unknown marker
[WARNING] Unknown marker
[WARNING] Unknown marker
[INFO] Main header has been correctly decoded.
[INFO] No decoded area parameters, set the decoded area to the whole image
[INFO] Psot value of the current tile-part is equal to zero, we assuming it is the last tile-part of the codestream.
[INFO] Header of tile 1 / 1 has been read.
[INFO] Tile 1/1 has been decoded.
[INFO] Image data has been updated with tile 1.

imagetopng: All components shall have the same subsampling, same bit depth, same sign.
        Aborting
[ERROR] Error generating png file. Outfile poc.j2k.png not generated
         

winfried


---

Comment by szukw000 on 2021-05-04 14:03:27+00:00:
@yuawn ,
using a simple reader read_j2k:

```
NAME(/tmp/1347-poc.j2k)
LENG(1307)

ENTER read_jp2c
[0]marker(0xff4f)
    soc len(0)
[2]marker(0xff51)
    siz len(47)
    capabilities(11776)[extended: 0]
    x(7 : 32) y(7 : 19)
    xt(0 : 73760) yt(0 : 218793738)
    IMAGE w(25) h(12) TILE w(73760) h(218793738)
    nr_components(3)
      component[0] signed(1) prec(8) hsep(1) vsep(1)
      component[1] signed(0) prec(9) hsep(2) vsep(2)
      component[2] signed(0) prec(3) hsep(2) vsep(2)
[51]marker(0xff52)

    read_cod

             max_len 12
          prog_order 128
           nr_layers 38552
multi_comp_transform 0
Scod 0
       entropy_coder 0
      use_sop_marker 0
      use_eph_marker 0
      num_resolutions 1
     code_block_width 0
    code_block_height 0
     code_block_style 0
       transformation 0 (9-7 irreversible)

    [0]precinct_w 15
    [0]precinct_h 15


    cod len(12)

[65]marker(0xffff)
test_marker: type(0xffff) prefix(0xff) suffix(0xff)
 I :MARKER 0xffff is unknown.
EXIT read_jp2c
    end - s ==> -27531
EXIT with end - s ==> 0 (DEC:0)
```
winfried

---

Comment by yuawn on 2021-05-04 14:36:50+00:00:
@szukw000, 
you need to build it with address sanitizer to detect the bug.

---

Comment by yuawn on 2021-05-04 14:39:59+00:00:
I also reproduced it on released version [2.3.1](https://github.com/uclouvain/openjpeg/releases/tag/v2.3.1) released on Apr 2, 2019.
This bug affects released versions 2.3.1 ~ 2.4.0.

---

Comment by CityOfLight77 on 2021-05-05 06:54:20+00:00:
@yuawn I try to build openjpeg with AFL but got error it can't find clang... already install it beforehand.
Mind to know how you build openjpeg with AFL?

---

Comment by yuawn on 2021-05-05 11:15:15+00:00:
@CityOfLight77 there is no need to build it with AFL.

Both of GCC and Clang supports ASAN, just build it as I said above:
```bash
CFLAGS='-g -fsanitize=address' cmake .. -DCMAKE_BUILD_TYPE=Release
make
```
I reproduced this bug with gcc and clang on the versions from 2.3.1 to current master.

---

Comment by szukw000 on 2021-05-06 04:19:59+00:00:
@yuawn ,
I added:
```
    CFLAGS='-g -fsanitize=address'
```

opj_decompress -i /tmp/1347-poc.j2k -o 1347-poc.j2k.png

```
[INFO] Start to read j2k main header (0).
[ERROR] Unknown progression order in COD marker
[WARNING] Unknown marker
[ERROR] Unknown progression order in COD marker
[WARNING] Unknown marker
[WARNING] Unknown marker
[WARNING] Unknown marker
[ERROR] Unknown progression order in COD marker
[WARNING] Unknown marker
[WARNING] Unknown marker
[WARNING] Unknown marker
[INFO] Main header has been correctly decoded.
[INFO] No decoded area parameters, set the decoded area to the whole image
[INFO] Psot value of the current tile-part is equal to zero, we assuming it is the last tile-part of the codestream.
[INFO] Header of tile 1 / 1 has been read.
[INFO] Tile 1/1 has been decoded.
[INFO] Image data has been updated with tile 1.

imagetopng: All components shall have the same subsampling, same bit depth, same sign.
        Aborting
[ERROR] Error generating png file. Outfile 1347-poc.j2k.png not generated
```

By the way: I use gcc (GCC) 10.3.0.

winfried


---

Comment by yuawn on 2021-05-06 12:49:27+00:00:
Hi @szukw000,
It seems like you didn't compile it with ASAN successfully, where did you add the compiler flags?

I can confirm that the following script can reproduce the bug successfully:
```bash
git clone https://github.com/uclouvain/openjpeg.git
cd openjpeg
git checkout v2.4.0

mkdir build
cd build

CFLAGS='-g -fsanitize=address' cmake .. -DCMAKE_BUILD_TYPE=Release
make

wget https://github.com/uclouvain/openjpeg/files/6402272/poc.j2k.gz
gunzip poc.j2k.gz

./bin/opj_decompress -i ./poc.j2k -o ./out.png
```
```bash
$ gcc --version
gcc (Ubuntu 10.2.0-5ubuntu1~20.04) 10.2.0

$ md5sum poc.j2k
c85153c022a7469d865a5a0b5e2781f8  poc.j2k
```

---

Comment by StayPirate on 2021-06-08 13:12:15+00:00:
@rouault any idea if f4cb033 will be merged or if an official ptach will be released instead?

---

Comment by rouault on 2021-06-08 13:21:14+00:00:
> @rouault any idea if [f4cb033](https://github.com/uclouvain/openjpeg/commit/f4cb033a340b55dbc576453c4b6a967fec5cbbda) will be merged or if an official ptach will be released instead?

@msabwat can you issue a pull request with your proposed fix ?

---

Comment by msabwat on 2021-06-08 22:30:25+00:00:
> > @rouault any idea if [f4cb033](https://github.com/uclouvain/openjpeg/commit/f4cb033a340b55dbc576453c4b6a967fec5cbbda) will be merged or if an official ptach will be released instead?
> 
> @msabwat can you issue a pull request with your proposed fix ?

Sure !

---

Comment by StayPirate on 2021-06-10 12:22:02+00:00:
This issue got assigned CVE-2021-3575. @msabwat would be worthy if you can add this CVE ID to your commit message.

---

Comment by ajakk on 2022-01-24 21:42:51+00:00:
> This issue got assigned CVE-2021-3575. @msabwat would be worthy if you can add this CVE ID to your commit message.

Did you request it? Still seems reserved, so should be safe to make public now, right?

---

Comment by nanonyme on 2022-04-15 17:36:58+00:00:
Any chance getting canonical fix merged? This is now public as severity 6.8 arbitrary code execution bug.

---

Comment by StayPirate on 2022-04-28 08:16:53+00:00:
any update here?

---

Comment by nanonyme on 2022-05-22 16:32:40+00:00:
@ZaquL I guess that would explain why prior attempts to fix resulted in minor corruption.

---

Comment by mnqazi on 2023-01-09 06:14:27+00:00:
is this finally patched or not?

---

Comment by SimonWoidig on 2023-11-16 11:29:02+00:00:
Any updates? This vulnerability is still unpatched after two years.

---

Comment by deekal2 on 2024-02-16 17:12:55+00:00:
Is this issue being actively looked into? This vulnerability is still unpatched after two years. 

The last release for this component was 2 years ago. Is this component being maintained?

Is there an alternative to OpenJPEG?

---

Comment by mdadams on 2024-02-18 08:17:47+00:00:
[JasPer](https://github.com/jasper-software/jasper)  would be one possible alternative to OpenJPEG.

---

Comment by rouault on 2024-02-18 16:09:05+00:00:
Fix in https://github.com/uclouvain/openjpeg/pull/1509

Attachments:
https://github.com/uclouvain/openjpeg/files/6402272/poc.j2k.gz

Commit References:
0bda7188b7b545232a341f1d978b1e4feda46fc2
f4cb033a340b55dbc576453c4b6a967fec5cbbda

================= Bug Report (2/2) ==================
## Source: Red Hat Bugzilla
## URL: https://bugzilla.redhat.com/show_bug.cgi?id=1957616
## Description:
Bugzilla ID: 1957616
Title: CVE-2021-3575 openjpeg: heap-buffer-overflow in color.c may lead to DoS or arbitrary code execution

Description
Marian Rehak 2021-05-06 07:30:41 UTC
Decompressing a crafted .j2k file may lead to heap-buffer-overflow in color.c:379:42 in sycc420_to_rgb.

Reference:

https://github.com/uclouvain/openjpeg/issues/1347


Comments:
Comment 1
Marian Rehak 2021-05-06 07:31:12 UTC
Created openjpeg tracking bugs for this issue:

Affects: fedora-all [bug 1957617]


Created openjpeg2 tracking bugs for this issue:

Affects: epel-7 [bug 1957619]
Affects: fedora-all [bug 1957618]

---

Comment 5
errata-xmlrpc 2021-11-09 17:56:47 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise Linux 8

Via RHSA-2021:4251 https://access.redhat.com/errata/RHSA-2021:4251

---

Comment 6
Product Security DevOps Team 2021-11-09 18:24:10 UTC
This bug is now closed. Further updates for individual products will be reflected on the CVE page(s):

https://access.redhat.com/security/cve/cve-2021-3575

Build script:
#!/bin/bash -eu
# Minimized build script with only core build commands
set -eu
mkdir -p build
cd build
cmake ..
make clean -s -j$(nproc)
make -j$(nproc) -s

Dockerfile:
FROM hwiwonlee/secb.base:latest
RUN apt-get update && apt-get install -y make cmake g++
RUN git clone https://github.com/uclouvain/openjpeg openjpeg
RUN git -C openjpeg checkout 37ac30ceff6640bbab502388c5e0fa0bff23f505
WORKDIR $SRC/openjpeg
COPY build.sh $SRC/

Additional files: