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

[CVE-2016-9118] Heap Buffer Overflow in function pnmtoimage of convert.c #861

Closed
YangY-Xiao opened this issue Oct 30, 2016 · 3 comments
Closed
Labels

Comments

@YangY-Xiao
Copy link

YangY-Xiao commented Oct 30, 2016

Description

OpenJPEG Heap Buffer Overflow in function pnmtoimage of convert.c:1719

Testing Environment

Ubuntu(16.04) + OpenJPEG(2.1.2)

Exception Information

Address Sanitizer Output

==9282==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xb57007f4 at pc 0x08146481 bp 0xbffe8268 sp 0xbffe825c
WRITE of size 4 at 0xb57007f4 thread T0
#0 0x8146480 (/home/yang/openjpeg/openjpeg-2.1.2/build-clang/bin/opj_compress+0x8146480)
#1 0x81333b6 (/home/yang/openjpeg/openjpeg-2.1.2/build-clang/bin/opj_compress+0x81333b6)
#2 0xb7438636 (/lib/i386-linux-gnu/libc.so.6+0x18636)
#3 0x805f227 (/home/yang/openjpeg/openjpeg-2.1.2/build-clang/bin/opj_compress+0x805f227)

0xb57007f4 is located 0 bytes to the right of 4-byte region [0xb57007f0,0xb57007f4)
allocated by thread T0 here:
#0 0x81036f4 (/home/yang/openjpeg/openjpeg-2.1.2/build-clang/bin/opj_compress+0x81036f4)
#1 0xb7721e0c (/home/yang/openjpeg/openjpeg-2.1.2/build-clang/bin/libopenjp2.so.7+0x99e0c)
#2 0xb769e081 (/home/yang/openjpeg/openjpeg-2.1.2/build-clang/bin/libopenjp2.so.7+0x16081)
#3 0x8145543 (/home/yang/openjpeg/openjpeg-2.1.2/build-clang/bin/opj_compress+0x8145543)
#4 0x81333b6 (/home/yang/openjpeg/openjpeg-2.1.2/build-clang/bin/opj_compress+0x81333b6)
#5 0xb7438636 (/lib/i386-linux-gnu/libc.so.6+0x18636)

SUMMARY: AddressSanitizer: heap-buffer-overflow (/home/yang/openjpeg/openjpeg-2.1.2/build-clang/bin/opj_compress+0x8146480)
Shadow bytes around the buggy address:
0x36ae00a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36ae00b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36ae00c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36ae00d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36ae00e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x36ae00f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa[04]fa
0x36ae0100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36ae0110: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36ae0120: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36ae0130: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36ae0140: 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
Heap right redzone: fb
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
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
==9282==ABORTING

GDB Information

Program received signal SIGSEGV, Segmentation fault.
0x08051cb5 in pnmtoimage (filename=0xbf9b1e18 "crash/6.pgm", parameters=0xbf9b0718)
at /home/yang/openjpeg/openjpeg-2.1.2/src/bin/jp2/convert.c:1719
1719 image->comps[0].data[i] = (((uc>>bit) & 1)?0:255);
(rr) p i
$10 = 32646
(rr) p x
$11 = 32646
(rr) p y
$12 = 0
(rr) p image->comps[0].data
$13 = (OPJ_INT32 *) 0x86251e8
(rr) p h
$14 = 2147483647
(rr) p w
$15 = 2147483647
(rr) p image->comps[0].data[i]
Cannot access memory at address 0x8645000

Analysis

if(format == 4)
{
    int x, y, bit;
    unsigned char uc;
    i = 0;
    for(y = 0; y < h; ++y)
    {
        bit = -1; uc = 0;

        for(x = 0; x < w; ++x)
        {
            if(bit == -1)
            {
                bit = 7;
                uc = (unsigned char)getc(fp);
            }
            image->comps[0].data[i] = (((uc>>bit) & 1)?0:255);
            --bit; ++i;
        }
    }
}

Analysis

function pnmtoimage(convert.c:1553)
|
|-->function read_pnm_header(fp, &header_info)
| //FILE fp; struct pnm_header header_info
|
|-->function skip_int(s, &ph->width)
|--> return ph->width = 2147483647(0x7fffffff) from atoi("555555555544\n")
|-->function skip_int(s, &ph->height)
|--> same as ph->width = 2147483647(0x7fffffff) from atoi("555555555544\n")
|-->function opj_image_create
|-->comp->data = (OPJ_INT32
) opj_calloc(comp->w * comp->h, sizeof(OPJ_INT32));
|--> w = 0x7fffffff h = 0x7fffffff w*h = 1 (Integer Overflow)
|-->sizeof(comp->data) = 1
|-->image->comps[0].data[i] = (((uc>>bit) & 1)?0:255); (convert:1719)
|--> access violation (heap buffer overflow)

crash.pgm(ubuntu)
0000000 3450 350a 3535 3535 3535 3535 3435 0a34
0000010 3535 3535 3535 3535 3535 3434 3404 0a34
0000020 bf23

Poc

Contact me if you need Poc file at YangX92@hotmail.com

@1ucian0
Copy link

1ucian0 commented Dec 3, 2016

Please, refer to this issue as CVE-2016-9118

rouault added a commit that referenced this issue Jul 30, 2017
@rouault rouault closed this as completed Jul 30, 2017
@detonin detonin added the bug label Aug 3, 2017
@fgeek
Copy link

fgeek commented Aug 12, 2017

Does openjpeg have some kind of test suite? The PoC file should be included there in cases like these.

@rouault
Copy link
Collaborator

rouault commented Aug 13, 2017

Does openjpeg have some kind of test suite?

It does. Yes extending it is good practice, although sometimes a bit tricky to be relevant when using fuzzed files that might be rejected for other reasons by later fixes. So ideally files should exhibit one single defect and be conformant/usual for the rest.

@YangY-Xiao YangY-Xiao changed the title Heap Buffer Overflow in function pnmtoimage of convert.c [CVE-2016-9118] Heap Buffer Overflow in function pnmtoimage of convert.c Oct 24, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants