Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

opj_decompress heap overflow Denial of Service issue #1413

Closed
smlijun opened this issue Mar 3, 2022 · 2 comments
Closed

opj_decompress heap overflow Denial of Service issue #1413

smlijun opened this issue Mar 3, 2022 · 2 comments

Comments

@smlijun
Copy link

smlijun commented Mar 3, 2022

Expected behavior and actual behavior.

This vulnerability is a heap overflow bug issued by openjpeg opj_decompression.
This vulnerability can cause Denial of service.

Steps to reproduce the problem.

The environment setting is as follows.
OS : ubuntu20.04
Build option : cmake .. -DCMAKE_BUILD_TYPE=Release (I follow build option in openjpeg Official github)
Download the latest version of openjpeg from git and build it as follows.

mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make

execute opj_decompress as follows

./opj_decompress -i payload.j2k -o test.pgm

Double free will occur

payload url : https://www.notion.so/openjpeg-opj_decompress-double-free-bug-report-ddb096dc92274d6b8e305efc3f931ac8#53973c09200c45ed9c03d0e2a91da87d

screen shot : https://caramel-abacus-14e.notion.site/openjpeg-opj_decompress-double-free-bug-report-ddb096dc92274d6b8e305efc3f931ac8

call stack

[#0](https://hackerone.com/reports/0) GI_raise (sig=sig[@entry](https://hackerone.com/entry)=0x6) at ../sysdeps/unix/sysv/linux/raise.c:50
[#1](https://hackerone.com/reports/1) 0x00007ffff7c0d859 in GI_abort () at abort.c:79
[#2](https://hackerone.com/reports/2) 0x00007ffff7c783ee in libc_message (action=action[@entry](https://hackerone.com/entry)=do_abort,
fmt=fmt[@entry](https://hackerone.com/entry)=0x7ffff7da2285 "%s\n") at ../sysdeps/posix/libc_fatal.c:155
[#3](https://hackerone.com/reports/3) 0x00007ffff7c8047c in malloc_printerr (
str=str[@entry](https://hackerone.com/entry)=0x7ffff7da4670 "double free or corruption (out)") at malloc.c:5347
[#4](https://hackerone.com/reports/4) 0x00007ffff7c82120 in _int_free (av=0x7ffff7dd3b80 <main_arena>, p=0x55555558abe0,
have_lock=<optimized out>) at malloc.c:4314
[#5](https://hackerone.com/reports/5) 0x00007ffff7fafbb4 in opj_aligned_free (ptr=0x55555558abf0)
at /home/aftershock/Desktop/openjpeg-master/src/lib/openjp2/opj_malloc.c:228
[#6](https://hackerone.com/reports/6) 0x00007ffff7fa178a in opj_t1_allocate_buffers (t1=0x5555555862d0, w=0x40, h=0x40)
at /home/aftershock/Desktop/openjpeg-master/src/lib/openjp2/t1.c:1494
[#7](https://hackerone.com/reports/7) 0x00007ffff7fa2e4f in opj_t1_decode_cblk (t1=0x5555555862d0, cblk=0x555555583df0, orient=0x0,
roishift=0x0, cblksty=0x8, p_manager=0x555555574570, p_manager_mutex=0x555555586240,
check_pterm=0x0) at /home/aftershock/Desktop/openjpeg-master/src/lib/openjp2/t1.c:1983
[#8](https://hackerone.com/reports/8) 0x00007ffff7fa1eec in opj_t1_clbl_decode_processor (user_data=0x555555586630,
tls=0x555555576c70) at /home/aftershock/Desktop/openjpeg-master/src/lib/openjp2/t1.c:1704
[#9](https://hackerone.com/reports/9) 0x00007ffff7f43a34 in opj_thread_pool_submit_job (tp=0x555555576c10,
job_fn=0x7ffff7fa1a2f <opj_t1_clbl_decode_processor>, user_data=0x555555586630)
at /home/aftershock/Desktop/openjpeg-master/src/lib/openjp2/thread.c:835
[#10](https://hackerone.com/reports/10) 0x00007ffff7fa2d39 in opj_t1_decode_cblks (tcd=0x55555557af60, pret=0x7fffffff8acc,
tilec=0x55555557b430, tccp=0x55555557a440, p_manager=0x555555574570,
p_manager_mutex=0x555555586240, check_pterm=0x0)
at /home/aftershock/Desktop/openjpeg-master/src/lib/openjp2/t1.c:1943
[#11](https://hackerone.com/reports/11) 0x00007ffff7facbde in opj_tcd_t1_decode (p_tcd=0x55555557af60, p_manager=0x555555574570)
at /home/aftershock/Desktop/openjpeg-master/src/lib/openjp2/tcd.c:2000
[#12](https://hackerone.com/reports/12) 0x00007ffff7fac055 in opj_tcd_decode_tile (p_tcd=0x55555557af60, win_x0=0x0, win_y0=0x0,
win_x1=0x138, win_y1=0xd2, numcomps_to_decode=0x0, comps_indices=0x0,
p_src=0x55555557c600 "\307", <incomplete sequence \312>, p_max_length=0x6ad, p_tile_no=0x0,
p_cstr_index=0x555555576160, p_manager=0x555555574570)
at /home/aftershock/Desktop/openjpeg-master/src/lib/openjp2/tcd.c:1654
[#13](https://hackerone.com/reports/13) 0x00007ffff7f6c8f4 in opj_j2k_decode_tile (p_j2k=0x5555555745d0, p_tile_index=0x0, p_data=0x0,
p_data_size=0x0, p_stream=0x555555573480, p_manager=0x555555574570)
at /home/aftershock/Desktop/openjpeg-master/src/lib/openjp2/j2k.c:9841
[#14](https://hackerone.com/reports/14) 0x00007ffff7f71464 in opj_j2k_decode_tiles (p_j2k=0x5555555745d0, p_stream=0x555555573480,
p_manager=0x555555574570)
at /home/aftershock/Desktop/openjpeg-master/src/lib/openjp2/j2k.c:11683
[#15](https://hackerone.com/reports/15) 0x00007ffff7f6a8df in opj_j2k_exec (p_j2k=0x5555555745d0, p_procedure_list=0x555555576b90,
p_stream=0x555555573480, p_manager=0x555555574570)
at /home/aftershock/Desktop/openjpeg-master/src/lib/openjp2/j2k.c:8985
[#16](https://hackerone.com/reports/16) 0x00007ffff7f72047 in opj_j2k_decode (p_j2k=0x5555555745d0, p_stream=0x555555573480,
p_image=0x55555557b520, p_manager=0x555555574570)
at /home/aftershock/Desktop/openjpeg-master/src/lib/openjp2/j2k.c:11986
[#17](https://hackerone.com/reports/17) 0x00007ffff7f7e4d2 in opj_decode (p_codec=0x555555574510, p_stream=0x555555573480,
p_image=0x55555557b520)
at /home/aftershock/Desktop/openjpeg-master/src/lib/openjp2/openjpeg.c:494
[#18](https://hackerone.com/reports/18) 0x000055555555ad98 in main (argc=0x5, argv=0x7fffffffdff8)
at /home/aftershock/Desktop/openjpeg-master/src/bin/jp2/opj_decompress.c:1559
[#19](https://hackerone.com/reports/19) 0x00007ffff7c0f0b3 in libc_start_main (main=0x55555555a542 <main>, argc=0x5,
argv=0x7fffffffdff8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>,
stack_end=0x7fffffffdfe8) at ../csu/libc-start.c:308
[#20](https://hackerone.com/reports/20) 0x00005555555578ce in _start ()

openjpeg version

lastest version

@szukw000
Copy link
Contributor

szukw000 commented Mar 3, 2022

payload.j2k contains dubious markers:

[89]marker(0xff00)
test_marker: type(0xff00) prefix(0xff) suffix(0)
III:NEXT MARKER 0x3030 is unknown. STOP.

winfried

@zodf0055980
Copy link
Contributor

zodf0055980 commented May 31, 2022

Hi @rouault ,
I think this problem is malloc size error in ht_dec.c

t1->flags = (opj_flag_t*) opj_aligned_malloc(flagssize);

It should malloc flagssize * sizeof(opj_flag_t)

openjpeg/src/lib/openjp2/t1.c

Lines 1495 to 1496 in 5292728

t1->flags = (opj_flag_t*) opj_aligned_malloc(flagssize * sizeof(
opj_flag_t));

Before this patch, this is asan report.

➜  ./opj_decompress -i payload.j2k -o test.pgm

[INFO] Start to read j2k main header (0).
[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.
=================================================================
==111124==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61e000000ad0 at pc 0x7ffff75e4f3d bp 0x7fffffff80e0 sp 0x7fffffff7888
WRITE of size 4752 at 0x61e000000ad0 thread T0
    #0 0x7ffff75e4f3c in __interceptor_memset ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:762
    #1 0x7ffff7520729 in opj_t1_allocate_buffers /home/yuan/openjpeg/src/lib/openjp2/t1.c:1504
    #2 0x7ffff7523fe7 in opj_t1_decode_cblk /home/yuan/openjpeg/src/lib/openjp2/t1.c:1983
    #3 0x7ffff75219ef in opj_t1_clbl_decode_processor /home/yuan/openjpeg/src/lib/openjp2/t1.c:1704
    #4 0x7ffff741be1b in opj_thread_pool_submit_job /home/yuan/openjpeg/src/lib/openjp2/thread.c:835
    #5 0x7ffff7523c4c in opj_t1_decode_cblks /home/yuan/openjpeg/src/lib/openjp2/t1.c:1943
    #6 0x7ffff753f5c0 in opj_tcd_t1_decode /home/yuan/openjpeg/src/lib/openjp2/tcd.c:2000
    #7 0x7ffff753d327 in opj_tcd_decode_tile /home/yuan/openjpeg/src/lib/openjp2/tcd.c:1654
    #8 0x7ffff747d628 in opj_j2k_decode_tile /home/yuan/openjpeg/src/lib/openjp2/j2k.c:9862
    #9 0x7ffff748b264 in opj_j2k_decode_tiles /home/yuan/openjpeg/src/lib/openjp2/j2k.c:11707
    #10 0x7ffff74779a1 in opj_j2k_exec /home/yuan/openjpeg/src/lib/openjp2/j2k.c:9006
    #11 0x7ffff748d74f in opj_j2k_decode /home/yuan/openjpeg/src/lib/openjp2/j2k.c:12010
    #12 0x7ffff74aa477 in opj_decode /home/yuan/openjpeg/src/lib/openjp2/openjpeg.c:521
    #13 0x5555555672d6 in main /home/yuan/openjpeg/src/bin/jp2/opj_decompress.c:1582
    #14 0x7ffff705d0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x240b2)
    #15 0x55555555df0d in _start (/home/yuan/openjpeg/build/bin/opj_decompress+0x9f0d)

0x61e000000ad0 is located 0 bytes to the right of 2640-byte region [0x61e000000080,0x61e000000ad0)
allocated by thread T0 here:
    #0 0x7ffff768b6e5 in __interceptor_posix_memalign ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:217
    #1 0x7ffff7547ea5 in opj_aligned_alloc_n /home/yuan/openjpeg/src/lib/openjp2/opj_malloc.c:61
    #2 0x7ffff75480e1 in opj_aligned_malloc /home/yuan/openjpeg/src/lib/openjp2/opj_malloc.c:209
    #3 0x7ffff74402bf in opj_t1_allocate_buffers /home/yuan/openjpeg/src/lib/openjp2/ht_dec.c:1066
    #4 0x7ffff7440747 in opj_t1_ht_decode_cblk /home/yuan/openjpeg/src/lib/openjp2/ht_dec.c:1151
    #5 0x7ffff75217be in opj_t1_clbl_decode_processor /home/yuan/openjpeg/src/lib/openjp2/t1.c:1690
    #6 0x7ffff741be1b in opj_thread_pool_submit_job /home/yuan/openjpeg/src/lib/openjp2/thread.c:835
    #7 0x7ffff7523c4c in opj_t1_decode_cblks /home/yuan/openjpeg/src/lib/openjp2/t1.c:1943
    #8 0x7ffff753f5c0 in opj_tcd_t1_decode /home/yuan/openjpeg/src/lib/openjp2/tcd.c:2000
    #9 0x7ffff753d327 in opj_tcd_decode_tile /home/yuan/openjpeg/src/lib/openjp2/tcd.c:1654
    #10 0x7ffff747d628 in opj_j2k_decode_tile /home/yuan/openjpeg/src/lib/openjp2/j2k.c:9862
    #11 0x7ffff748b264 in opj_j2k_decode_tiles /home/yuan/openjpeg/src/lib/openjp2/j2k.c:11707
    #12 0x7ffff74779a1 in opj_j2k_exec /home/yuan/openjpeg/src/lib/openjp2/j2k.c:9006
    #13 0x7ffff748d74f in opj_j2k_decode /home/yuan/openjpeg/src/lib/openjp2/j2k.c:12010
    #14 0x7ffff74aa477 in opj_decode /home/yuan/openjpeg/src/lib/openjp2/openjpeg.c:521
    #15 0x5555555672d6 in main /home/yuan/openjpeg/src/bin/jp2/opj_decompress.c:1582
    #16 0x7ffff705d0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x240b2)

SUMMARY: AddressSanitizer: heap-buffer-overflow ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:762 in __interceptor_memset
Shadow bytes around the buggy address:
  0x0c3c7fff8100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c3c7fff8110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c3c7fff8120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c3c7fff8130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c3c7fff8140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c3c7fff8150: 00 00 00 00 00 00 00 00 00 00[fa]fa fa fa fa fa
  0x0c3c7fff8160: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c3c7fff8170: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c3c7fff8180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c3c7fff8190: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c3c7fff81a0: 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
  Shadow gap:              cc
==111124==ABORTING

After patch, ASAN not report any error.

➜  ./opj_decompress -i payload.j2k -o test.pgm

[INFO] Start to read j2k main header (0).
[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.

WARNING -> [PGM file] Only the first component
           is written to the file
[INFO] Generated Outfile test.pgm
decode time: 11 ms

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants