Sec Bug->Bug #77311 [Opn->Nab]: Use After Free Read through image tile and brush

From: 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

« previous php.bugs (#218510) next »