Skip to content

Port libgd 7ff626c48a133eff1b6608bf28b1cfae30597408 to fix undefined behavior - #23953

Open
DanielEScherzer wants to merge 1 commit into
php:PHP-8.4from
DanielEScherzer:imagecreatefromstring-overflow
Open

DanielEScherzer wants to merge 1 commit into
php:PHP-8.4from
DanielEScherzer:imagecreatefromstring-overflow

Conversation

@DanielEScherzer

Copy link
Copy Markdown
Member

Apply the changes from libgd/libgd@7ff626c in order to fix undefined behavior in PHP's imagecreatefromstring() function when a compressed chunk claims to take INT_MAX space.

…behavior

Apply the changes from libgd/libgd@7ff626c in
order to fix undefined behavior in PHP's `imagecreatefromstring()` function
when a compressed chunk claims to take `INT_MAX` space.
@DanielEScherzer

Copy link
Copy Markdown
Member Author

This is only needed for PHP 8.4 and 8.5, 8.6 included the fix as part of #22532

Without this fix, UBSAN_OPTIONS=print_stacktrace=1 /usr/src/php84/sapi/cli/php /var/www/html/gd.php results in

/usr/src/php84/ext/gd/libgd/gd_gd2.c:302:10: runtime error: signed integer overflow: 2147483647 + 1 cannot be represented in type 'int'
    #0 0x564e272bf264 in php_gd_gdImageCreateFromGd2Ctx /usr/src/php84/ext/gd/libgd/gd_gd2.c:302:10
    #1 0x564e27255485 in _php_image_create_from_string /usr/src/php84/ext/gd/gd.c:1448:7
    #2 0x564e272545d1 in zif_imagecreatefromstring /usr/src/php84/ext/gd/gd.c:1502:9
    #3 0x564e28b0635d in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER /usr/src/php84/Zend/zend_vm_execute.h:1351:2
    #4 0x564e2875e20f in execute_ex /usr/src/php84/Zend/zend_vm_execute.h:58697:7
    #5 0x564e2875ef7e in zend_execute /usr/src/php84/Zend/zend_vm_execute.h:64349:2
    #6 0x564e290567e8 in zend_execute_script /usr/src/php84/Zend/zend.c:1937:3
    #7 0x564e2803824d in php_execute_script_ex /usr/src/php84/main/main.c:2577:13
    #8 0x564e28038978 in php_execute_script /usr/src/php84/main/main.c:2617:9
    #9 0x564e290602a9 in do_cli /usr/src/php84/sapi/cli/php_cli.c:935:5
    #10 0x564e2905dfc5 in main /usr/src/php84/sapi/cli/php_cli.c:1322:18
    #11 0x7fa129cab249 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #12 0x7fa129cab304 in __libc_start_main csu/../csu/libc-start.c:360:3
    #13 0x564e26803f30 in _start (/usr/src/php84/sapi/cli/php+0x1a03f30) (BuildId: 19ac90755960f95b5e2d9b45f49a35be7b83f33d)

SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/src/php84/ext/gd/libgd/gd_gd2.c:302:10 in 

CC @cmb69 as the original author in libgd

--FILE--
<?php

// Documentation available at https://libgd.github.io/manuals/2.3.3/files/gd_gd2-c.html

@devnexen devnexen Sep 28, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think you can simplify the test like this

--- a/ext/gd/tests/createfromstring-overflow.phpt
+++ b/ext/gd/tests/createfromstring-overflow.phpt
@@ -4,37 +4,9 @@ imagecreatefromstring overflow with compressed chunk of size INT_MAX
 gd
 --FILE--
 <?php
-
-// Documentation available at https://libgd.github.io/manuals/2.3.3/files/gd_gd2-c.html
-$fileHeaderParts = [
-     "signature" => "gd2\x00",
-     "version" => "\x00\x02",
-     "width" => "\x00\x01",
-     "height" => "\x00\x01",
-     "chunk_size" => "\x00\x40",
-     "format" => "\x00\x04", // compressed truecolor image data
-     "x_chunk_count" => "\x00\x01",
-     "y_chunk_count" => "\x00\x01",
-];
-$fileHeader = implode("", $fileHeaderParts);
-
-$chunkHeaderParts = [
-     "offset" => "\x00\x00\x00\x20",
-     "size" =>"\x7F\xFF\xFF\xFF", // INT_MAX
-];
-$chunkHeader = implode("", $chunkHeaderParts);
-
-$trueColorHeaderParts = [
-     "truecolor" => "\x01",
-     "transparent" => "\x00\x00\x00\x00",
-];
-$trueColorHeader = implode("", $trueColorHeaderParts);
-
-$source = $fileHeader . $chunkHeader . $trueColorHeader;
-$img = imagecreatefromstring($source);
-var_dump($img);
-
+$data = pack('a4n7N2CN', 'gd2', 2, 1, 1, 64, 4, 1, 1, 0, 0x7FFFFFFF, 1, 0);
+var_dump(imagecreatefromstring($data));

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that is possible, but it is entirely unclear to me what the pack string means and how these numbers do anything - is there a problem with having the clarity of array keys?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes true you would need to know the gd2 format. but definitely not a blocker, the most imporant is the fix :)

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