Skip to content

ext/gd: keep the brush and tile images alive while the destination uses them - #24444

Open
lacatoire wants to merge 1 commit into
php:PHP-8.4from
lacatoire:fix/imagesetbrush-tile-keep-reference
Open

lacatoire wants to merge 1 commit into
php:PHP-8.4from
lacatoire:fix/imagesetbrush-tile-keep-reference

Conversation

@lacatoire

@lacatoire lacatoire commented Oct 19, 2026 •

Copy link
Copy Markdown
Member

imagesetbrush() and imagesettile() store a raw pointer to the brush or tile image in libgd, but the destination GdImage keeps no reference to it. Once the brush object is released, drawing with IMG_COLOR_BRUSHED or IMG_COLOR_TILED reads freed memory. Keep a reference to both images in the destination object and expose them to the GC.

To reproduce on PHP 8.5.4

<?php
$im = imagecreatetruecolor(20, 20);
$brush = imagecreatetruecolor(4, 4);
imagefill($brush, 0, 0, 0xff0000);
imagesetbrush($im, $brush);
unset($brush);
$junk = [];
for ($i = 0; $i < 50; $i++) { $j = imagecreatetruecolor(4, 4); imagefill($j, 0, 0, 0x00ff00); $junk[] = $j; }
imageline($im, 2, 10, 17, 10, IMG_COLOR_BRUSHED);
printf("%06x\n", imagecolorat($im, 5, 10));

Before: 00ff00, the pixels of another image

After: ff0000

@devnexen

Copy link
Copy Markdown
Member

since it s an UAF, it should target 8.4 I think.

@lacatoire
lacatoire force-pushed the fix/imagesetbrush-tile-keep-reference branch from 2671471 to cfa65df Compare October 20, 2026 07:15
@lacatoire
lacatoire changed the base branch from master to PHP-8.4 October 20, 2026 07:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants