php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #72298 pass2_no_dither out-of-bounds access
Submitted: 2016-05-31 00:28 UTC Modified: 2016-06-21 06:46 UTC
From: fernando at null-life dot com Assigned: stas (profile)
Status: Closed Package: GD related
PHP Version: 5.5.36 OS: *
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please !
Your email address:
MUST BE VALID
Solve the problem:
42 - 28 = ?
Subscribe to this entry?

 
 [2016-05-31 00:28 UTC] fernando at null-life dot com
Description:
------------
pass2_no_dither out-of-bounds access:

This was tested on PHP 7 with ASAN enabled and USE_ZEND_ALLOC=0.

*(inptr - 1) tries to access -1 element of input_buf.

https://github.com/php/php-src/blob/PHP-7.0/ext/gd/libgd/gd_topal.c#L1332

Line 1332:
if ((oim->transparent >= 0) && (oim->transparent == *(inptr - 1)))

Current libgd:
https://github.com/libgd/libgd/blob/master/src/gd_topal.c#L1115

Attached test case reaches vulnerable function using imagetruecolortopalette.



This issue appeared because of these two things:

1) Commit [1] to fix #28311 [2] introduced the (-1) on this line, but when this was added, libgd used to increase inptr on some previous lines:

b = gdTrueColorGetBlue(*inptr++); [3]

2) However, when merging a new libgd version [4] this change wasn't considered, and it became this:

/* 
2.0.24: inptr must not be incremented until after
transparency check, if any. Thanks to "Super Pikeman." 
*/
b = gdTrueColorGetBlue (*inptr);


[1] https://github.com/php/php-src/commit/40329bff38a8c65254a8937f7cc68e0c063ff657
[2] https://bugs.php.net/bug.php?id=28311
[3] https://github.com/php/php-src/blob/40329bff38a8c65254a8937f7cc68e0c063ff657/ext/gd/libgd/gd_topal.c#L1257
[4] https://github.com/php/php-src/commit/f647379a3d48c8659783146ebc8ba3c25e7c73e6#diff-e5c46ee7140a1ea33c97a0538d85f0cfL1257

Test script:
---------------
<?php

ini_set('memory_limit', -1);
$img = imagecreatetruecolor (1 , 1); 
imagecolortransparent($img, 0);
imagetruecolortopalette($img, false, 4);


Expected result:
----------------
No crash

Actual result:
--------------
USE_ZEND_ALLOC=0  /ramdisk/php-71/sapi/cli/php -n /home/user/crashes/imagetruecolortopalette/poc.php
=================================================================
==10667==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xf33057cc at pc 0x0865d849 bp 0xff8d1608 sp 0xff8d15f8
READ of size 4 at 0xf33057cc thread T0
    #0 0x865d848 in pass2_no_dither /home/user/php-7.1asan/ext/gd/libgd/gd_topal.c:1332
    #1 0x865d848 in gdImageTrueColorToPaletteBody /home/user/php-7.1asan/ext/gd/libgd/gd_topal.c:1950
    #2 0x85bf0c1 in zif_imagetruecolortopalette /home/user/php-7.1asan/ext/gd/gd.c:1521
    #3 0x9a4a629 in ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER /home/user/php-7.1asan/Zend/zend_vm_execute.h:615
    #4 0x9861b11 in execute_ex /home/user/php-7.1asan/Zend/zend_vm_execute.h:425
    #5 0x9c184d0 in zend_execute /home/user/php-7.1asan/Zend/zend_vm_execute.h:470
    #6 0x961f43c in zend_execute_scripts /home/user/php-7.1asan/Zend/zend.c:1427
    #7 0x93589fb in php_execute_script /home/user/php-7.1asan/main/main.c:2492
    #8 0x9c25135 in do_cli /home/user/php-7.1asan/sapi/cli/php_cli.c:982
    #9 0x80a84e3 in main /home/user/php-7.1asan/sapi/cli/php_cli.c:1352
    #10 0xf6c01636 in __libc_start_main (/lib/i386-linux-gnu/libc.so.6+0x18636)
    #11 0x80a8aca  (/ramdisk/php-71/sapi/cli/php+0x80a8aca)

0xf33057cc is located 4 bytes to the left of 4-byte region [0xf33057d0,0xf33057d4)
allocated by thread T0 here:
    #0 0xf7200d06 in malloc (/usr/lib/i386-linux-gnu/libasan.so.2+0x96d06)
    #1 0x94de179 in _emalloc /home/user/php-7.1asan/Zend/zend_alloc.c:2446



Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-06-19 04:09 UTC] stas@php.net
-Assigned To: +Assigned To: stas
 [2016-06-19 04:09 UTC] stas@php.net
fix in https://gist.github.com/8fb869157e1d505ea64a21a3a10cc06c
 and in security repo as e9ac8954be9f7d988189df44578d759ffdea3512 

Please verify.
 [2016-06-19 04:09 UTC] stas@php.net
-PHP Version: 7.0.7 +PHP Version: 5.5.36
 [2016-06-21 06:48 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=e9ac8954be9f7d988189df44578d759ffdea3512
Log: Fix bug #72298	pass2_no_dither out-of-bounds access
 [2016-06-21 06:48 UTC] stas@php.net
-Status: Assigned +Status: Closed
 [2016-06-21 07:03 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=e9ac8954be9f7d988189df44578d759ffdea3512
Log: Fix bug #72298	pass2_no_dither out-of-bounds access
 [2016-06-21 07:26 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=e9ac8954be9f7d988189df44578d759ffdea3512
Log: Fix bug #72298	pass2_no_dither out-of-bounds access
 [2016-06-21 07:27 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=e9ac8954be9f7d988189df44578d759ffdea3512
Log: Fix bug #72298	pass2_no_dither out-of-bounds access
 [2016-06-22 05:58 UTC] krakjoe@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=e9ac8954be9f7d988189df44578d759ffdea3512
Log: Fix bug #72298	pass2_no_dither out-of-bounds access
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sun Nov 19 01:31:42 2017 UTC