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

================= Bug Report (1/2) ==================
## Source: GitHub Issue
## URL: https://github.com/uclouvain/openjpeg/issues/1283
## Description:
Issue: uclouvain/openjpeg#1283
Title: Heap-buffer-overflow in lib/openjp2/mqc.c:499
State: closed
Created by: zodf0055980
Created at: 2020-11-23 10:08:15+00:00

Issue Body:
I found a heap buffer overflow in the current master ([491299e](https://github.com/uclouvain/openjpeg/commit/491299eb073c80602ca8ee333303a31a581d3fa8)). 
I build openjpeg with ASAN, this is ASAN report.
POC picture :  ![sample](https://user-images.githubusercontent.com/25863161/99949026-5860c700-2db5-11eb-9219-2a9f500226ee.png)

```
~/openjpeg/build/bin/opj_compress -i ./sample.png -o ./out.j2k -M 3

[INFO] tile number 1 / 1
=================================================================
==29113==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000097 at pc 0x7f42917e7394 bp 0x7ffd162eff00 sp 0x7ffd162efef0
WRITE of size 1 at 0x602000000097 thread T0
    #0 0x7f42917e7393 in opj_mqc_byteout /home/yuan/afl-target/openjpeg/src/lib/openjp2/mqc.c:505
    #1 0x7f42917e7587 in opj_mqc_flush /home/yuan/afl-target/openjpeg/src/lib/openjp2/mqc.c:218
    #2 0x7f429185ad50 in opj_t1_encode_cblk /home/yuan/afl-target/openjpeg/src/lib/openjp2/t1.c:2478
    #3 0x7f429185ad50 in opj_t1_clbl_encode_processor /home/yuan/afl-target/openjpeg/src/lib/openjp2/t1.c:2241
    #4 0x7f4291702fcc in opj_thread_pool_submit_job /home/yuan/afl-target/openjpeg/src/lib/openjp2/thread.c:835
    #5 0x7f42918814a0 in opj_t1_encode_cblks /home/yuan/afl-target/openjpeg/src/lib/openjp2/t1.c:2319
    #6 0x7f42918af7c0 in opj_tcd_t1_encode /home/yuan/afl-target/openjpeg/src/lib/openjp2/tcd.c:2535
    #7 0x7f42918af7c0 in opj_tcd_encode_tile /home/yuan/afl-target/openjpeg/src/lib/openjp2/tcd.c:1439
    #8 0x7f429178af9b in opj_j2k_write_sod /home/yuan/afl-target/openjpeg/src/lib/openjp2/j2k.c:4813
    #9 0x7f429178af9b in opj_j2k_write_first_tile_part /home/yuan/afl-target/openjpeg/src/lib/openjp2/j2k.c:12626
    #10 0x7f429178af9b in opj_j2k_post_write_tile /home/yuan/afl-target/openjpeg/src/lib/openjp2/j2k.c:12382
    #11 0x7f42917c273b in opj_j2k_encode /home/yuan/afl-target/openjpeg/src/lib/openjp2/j2k.c:12131
    #12 0x5599a3d9d984 in main /home/yuan/afl-target/openjpeg/src/bin/jp2/opj_compress.c:2206
    #13 0x7f42908d8bf6 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6)
    #14 0x5599a3da2fd9 in _start (/home/yuan/afl-target/openjpeg/build/bin/opj_compress+0x1afd9)

0x602000000097 is located 0 bytes to the right of 7-byte region [0x602000000090,0x602000000097)
allocated by thread T0 here:
    #0 0x7f4291bc1b40 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb40)
    #1 0x7f42918b4ba4 in opj_tcd_code_block_enc_allocate_data /home/yuan/afl-target/openjpeg/src/lib/openjp2/tcd.c:1256
    #2 0x7f42918b4ba4 in opj_tcd_init_tile /home/yuan/afl-target/openjpeg/src/lib/openjp2/tcd.c:1170
    #3 0x7f42918b4ba4 in opj_tcd_init_encode_tile /home/yuan/afl-target/openjpeg/src/lib/openjp2/tcd.c:1201

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/yuan/afl-target/openjpeg/src/lib/openjp2/mqc.c:505 in opj_mqc_byteout
Shadow bytes around the buggy address:
  0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff8000: fa fa 00 00 fa fa 00 00 fa fa 00 00 fa fa 00 fa
=>0x0c047fff8010: fa fa[07]fa fa fa 07 fa fa fa 07 fa fa fa 07 fa
  0x0c047fff8020: fa fa 07 fa fa fa 07 fa fa fa 07 fa fa fa 07 fa
  0x0c047fff8030: fa fa 07 fa fa fa 07 fa fa fa 07 fa fa fa 07 fa
  0x0c047fff8040: fa fa 07 fa fa fa 07 fa fa fa 07 fa fa fa 07 fa
  0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8060: 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
  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
==29113==ABORTING
```

I also try to prove it without ASAN.
```
It malloc 7 bytes (0x602000000090) in opj_tcd_code_block_enc_allocate_data.
 
In opj_mqc_byteout function:
mpc->bp is 0x602000000096 first.
It try to do mqc->bp++,and set value in 0x602000000097
```



Comments:
Comment by zodf0055980 on 2020-11-23 14:01:28+00:00:
It has the same problem with `-M 44` after the fix.
```
➜  ~/openjpeg/build/bin/opj_compress -i ./ss.png -o ./out.j2k -M 44

[INFO] tile number 1 / 1
=================================================================
==13369==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000272f at pc 0x7f402686c0a0 bp 0x7fff404d6350 sp 0x7fff404d6340
WRITE of size 1 at 0x60300000272f thread T0
    #0 0x7f402686c09f in opj_mqc_byteout /home/yuan/openjpeg/src/lib/openjp2/mqc.c:505
    #1 0x7f402686c339 in opj_mqc_flush /home/yuan/openjpeg/src/lib/openjp2/mqc.c:218
    #2 0x7f40268e086f in opj_t1_encode_cblk /home/yuan/openjpeg/src/lib/openjp2/t1.c:2478
    #3 0x7f40268e086f in opj_t1_cblk_encode_processor /home/yuan/openjpeg/src/lib/openjp2/t1.c:2241
    #4 0x7f40267890ec in opj_thread_pool_submit_job /home/yuan/openjpeg/src/lib/openjp2/thread.c:835
    #5 0x7f40269074e4 in opj_t1_encode_cblks /home/yuan/openjpeg/src/lib/openjp2/t1.c:2319
    #6 0x7f402693598e in opj_tcd_t1_encode /home/yuan/openjpeg/src/lib/openjp2/tcd.c:2537
    #7 0x7f402693598e in opj_tcd_encode_tile /home/yuan/openjpeg/src/lib/openjp2/tcd.c:1441
    #8 0x7f4026810b98 in opj_j2k_write_sod /home/yuan/openjpeg/src/lib/openjp2/j2k.c:4813
    #9 0x7f4026810b98 in opj_j2k_write_first_tile_part /home/yuan/openjpeg/src/lib/openjp2/j2k.c:12626
    #10 0x7f4026810b98 in opj_j2k_post_write_tile /home/yuan/openjpeg/src/lib/openjp2/j2k.c:12382
    #11 0x7f4026848236 in opj_j2k_encode /home/yuan/openjpeg/src/lib/openjp2/j2k.c:12131
    #12 0x55cca6271705 in main /home/yuan/openjpeg/src/bin/jp2/opj_compress.c:2206
    #13 0x7f402595ebf6 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6)
    #14 0x55cca6276f19 in _start (/home/yuan/openjpeg/build/bin/opj_compress+0x1af19)

0x60300000272f is located 0 bytes to the right of 31-byte region [0x603000002710,0x60300000272f)
allocated by thread T0 here:
    #0 0x7f4026c46b40 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb40)
    #1 0x7f402693ab21 in opj_tcd_code_block_enc_allocate_data /home/yuan/openjpeg/src/lib/openjp2/tcd.c:1258
    #2 0x7f402693ab21 in opj_tcd_init_tile /home/yuan/openjpeg/src/lib/openjp2/tcd.c:1170
    #3 0x7f402693ab21 in opj_tcd_init_encode_tile /home/yuan/openjpeg/src/lib/openjp2/tcd.c:1201

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/yuan/openjpeg/src/lib/openjp2/mqc.c:505 in opj_mqc_byteout
Shadow bytes around the buggy address:
  0x0c067fff8490: 00 00 fa fa 00 00 00 fa fa fa 00 00 00 00 fa fa
  0x0c067fff84a0: 00 00 00 fa fa fa 00 00 00 00 fa fa 00 00 00 fa
  0x0c067fff84b0: fa fa 00 00 00 00 fa fa 00 00 00 fa fa fa 00 00
  0x0c067fff84c0: 00 00 fa fa 00 00 00 fa fa fa 00 00 00 00 fa fa
  0x0c067fff84d0: 00 00 00 fa fa fa 00 00 00 00 fa fa 00 00 00 fa
=>0x0c067fff84e0: fa fa 00 00 00[07]fa fa 00 00 00 00 fa fa 00 00
  0x0c067fff84f0: 00 fa fa fa 00 00 00 00 fa fa 00 00 00 fa fa fa
  0x0c067fff8500: 00 00 00 07 fa fa 00 00 00 00 fa fa 00 00 00 fa
  0x0c067fff8510: fa fa 00 00 00 00 fa fa 00 00 00 fa fa fa 00 00
  0x0c067fff8520: 00 07 fa fa 00 00 00 00 fa fa 00 00 00 fa fa fa
  0x0c067fff8530: 00 00 00 00 fa fa 00 00 00 fa fa fa 00 00 00 07
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
==13369==ABORTING
```

---

Comment by zodf0055980 on 2020-11-25 07:17:17+00:00:
Submit PR #1285 avoid heap buffer overflow in `-M 4 -IMF 2K`

---

Comment by zodf0055980 on 2020-11-29 00:50:15+00:00:
This issue was assigned CVE-2020-27814.

---

Comment by zodf0055980 on 2020-12-04 11:04:20+00:00:
find new POC : ![s0](https://user-images.githubusercontent.com/25863161/101156309-5fb08c00-3663-11eb-92be-61cd2b835e32.png)

```
~/openjpeg/build/bin/opj_compress -i ./s0.png -o ./a.jp2 -n 8 -s 7,7 -M 4 -I
```

Try to fix in #1303 

Commit References:
491299eb073c80602ca8ee333303a31a581d3fa8

================= Bug Report (2/2) ==================
## Source: Red Hat Bugzilla
## URL: https://bugzilla.redhat.com/show_bug.cgi?id=1901998
## Description:
Bugzilla ID: 1901998
Title: CVE-2020-27814 openjpeg: heap-buffer-overflow in lib/openjp2/mqc.c could result in DoS

Description
Michael Kaplan 2020-11-26 15:01:35 UTC
A heap-buffer overwrites error was discovered in lib/openjp2/mqc.c in
OpenJPEG 2.3.1. The vulnerability causes an out-of-bounds write, which may
lead to remote denial of service or possibly remote code execution.


Comments:
Comment 2
Michael Kaplan 2020-11-26 15:02:02 UTC
Created mingw-openjpeg2 tracking bugs for this issue:

Affects: fedora-all [bug 1902001]


Created openjpeg2 tracking bugs for this issue:

Affects: epel-all [bug 1901999]
Affects: fedora-all [bug 1902000]

---

Comment 4
Michael Kaplan 2020-11-27 13:36:33 UTC
Acknowledgments:

Name: zodf0055980 (SQLab NCTU Taiwan)

---

Comment 5
Michael Kaplan 2020-11-27 15:54:00 UTC
External References:

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

---

Comment 6
Huzaifa S. Sidhpurwala 2020-12-18 04:19:22 UTC
Upstream patches:

https://github.com/uclouvain/openjpeg/commit/15cf3d95814dc931ca0ecb132f81cb152e051bae
https://github.com/uclouvain/openjpeg/commit/eaa098b59b346cb88e4d10d505061f669d7134fc

---

Comment 8
Product Security DevOps Team 2021-11-09 17:52:28 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-2020-27814

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 a335b4d008359a32656026fa6780ef185b35cf0a
WORKDIR $SRC/openjpeg
COPY build.sh $SRC/

Additional files: