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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: stackexploit at gmail dot com
New email:
PHP Version: OS:

 

 [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: Thu Nov 21 11:01:29 2024 UTC