Sec Bug->Bug #77311 [Opn->Nab]: Use After Free Read through image tile and brush
| From: | cmb@php.net | Date: | Tue, 18 Dec 2018 14:17:24 +0000 |
| Subject: | Sec Bug->Bug #77311 [Opn->Nab]: Use After Free Read through image tile and brush | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-218510@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=77311&edit=1
ID: 77311
Updated by: cmb@php.net
Reported by: sscannell at ripstech dot com
Summary: Use After Free Read through image tile and brush
-Status: Open
+Status: Not a bug
-Type: Security
+Type: Bug
Package: GD related
Operating System: *
PHP Version: 7.2.13
-Assigned To:
+Assigned To: cmb
Block user comment: N
Private report: Y
New Comment:
> By freeing the tile, creating a string of the same size as the
> just freed tile an attacker can read arbitrary memory memory.
Firstly, we must not assume that an attacker can execute arbitrary
PHP code â otherwise all bets are off.
Secondly, the PHP manual already documents this issue[1][2]:
| You need not take special action when you are finished with a
| tile, but if you destroy the tile image, you must not use the
| IMG_COLOR_TILED color until you have set a new tile image!
So according to our security classification[3], this is not a
security issue, since it requires the use of code or settings
known to be insecure.
I admit that this behavior of the GD extension is not nice, but
since the extension works with resources, there is no way to
cleanly solve this with refcounting only, since there may be
cyclic references between images, which would require a garbage
collector. Switching to objects would allow us to resolve this.
[1] <http://php.net/manual/en/function.imagesettile.php#refsect1-function.imagesettile-description>
[2] <http://php.net/manual/en/function.imagesetbrush.php#refsect1-function.imagesetbrush-notes>
[3] <https://wiki.php.net/security>
Previous Comments:
------------------------------------------------------------------------
[2018-12-17 15:10:24] sscannell at ripstech dot com
Description:
------------
Image resources in GD are represented by the gdImage struct. Images can be created via the PHP
userland functions imagecreate and imagecreatetruecolor and return such a resource.
via imagesettile (http://php.net/manual/de/function.imagesettile.php) one image resource can then be
set as a "tile" for another image. A pointer to the underlying gdImage Struct of the tile
is then set as the value of the tile field of the image resource that should have the tile:
void gdImageSetTile (gdImagePtr im, gdImagePtr tile)
{
int i;
im->tile = tile;
...
The issue is that only a pointer to the struct is passed, meaning all information about the refcount
is then lost. By freeing the tile, creating a string of the same size as the just freed tile an
attacker can read arbitrary memory memory.
The same happens for brushes:
void gdImageSetBrush (gdImagePtr im, gdImagePtr brush)
{
int i;
im->brush = brush;
...
Test script:
---------------
<?php
$img = imagecreate(0xff, 0xff);
$tile = imagecreate(0xff, 0xff);
imagesettile($img, $tile);
imagedestroy($tile);
$str = str_repeat("\x00", 7360 - 32);
imagesetpixel($img, 0, 0, -5);
Expected result:
----------------
No crash
Actual result:
--------------
Floating point exception (core dumped)
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=77311&edit=1