From e45f5f611b441d72a80cc750f7e786d222e4484d Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Fri, 22 May 2026 07:59:09 -0400 Subject: [PATCH] Fix GH-22121: double-free in gdImageSetStyle() after overflow early return gdImageSetStyle freed im->style before checking overflow2(). When the overflow check tripped and the function early-returned, im->style was left dangling. The next gdImageSetStyle, gdImageDestroy, or gdImageSetPixel gdStyled/gdStyledBrushed dispatch then freed or dereferenced it. Move the overflow check above the free to match upstream libgd (libgd/libgd src/gd.c::gdImageSetStyle), which has always had the check first. The original divergence was an oversight in 77ba2483d95 when the overflow check was ported from libgd 2.0.29. Fixes GH-22121 --- ext/gd/libgd/gd.c | 6 +++--- ext/gd/tests/gh22121.phpt | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 ext/gd/tests/gh22121.phpt diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c index 71a0e9ea63f2..9563354a99d8 100644 --- a/ext/gd/libgd/gd.c +++ b/ext/gd/libgd/gd.c @@ -2879,12 +2879,12 @@ void gdImageFilledPolygon (gdImagePtr im, gdPointPtr p, int n, int c) void gdImageSetStyle (gdImagePtr im, int *style, int noOfPixels) { - if (im->style) { - gdFree(im->style); - } if (overflow2(sizeof (int), noOfPixels)) { return; } + if (im->style) { + gdFree(im->style); + } im->style = (int *) gdMalloc(sizeof(int) * noOfPixels); memcpy(im->style, style, sizeof(int) * noOfPixels); im->styleLength = noOfPixels; diff --git a/ext/gd/tests/gh22121.phpt b/ext/gd/tests/gh22121.phpt new file mode 100644 index 000000000000..3a55fb5fa5a5 --- /dev/null +++ b/ext/gd/tests/gh22121.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-22121 (Double free in gdImageSetStyle() after overflow-triggered early return) +--EXTENSIONS-- +gd +--INI-- +memory_limit=-1 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagesetstyle(): Product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully + in %s on line %d +no double free