Commit c5f28c7cf0a for php.net
commit c5f28c7cf0a052f48e47877c7aa5c5bcc54f1cfc
Author: Niels Dossche <7771979+ndossche@users.noreply.github.com>
Date: Tue Nov 25 23:11:38 2025 +0100
Fix GH-20584: Information Leak of Memory
The string added had uninitialized memory due to
php_read_stream_all_chunks() not moving the buffer position, resulting
in the same data always being overwritten instead of new data being
added to the end of the buffer.
This is backport as there is a security impact as described in
GHSA-3237-qqm7-mfv7 .
diff --git a/ext/standard/image.c b/ext/standard/image.c
index 5200295f3af..269117318c4 100644
--- a/ext/standard/image.c
+++ b/ext/standard/image.c
@@ -434,6 +434,7 @@ static size_t php_read_stream_all_chunks(php_stream *stream, char *buffer, size_
if (read_now < stream->chunk_size && read_total != length) {
return 0;
}
+ buffer += read_now;
} while (read_total < length);
return read_total;
diff --git a/ext/standard/tests/image/gh20584.phpt b/ext/standard/tests/image/gh20584.phpt
new file mode 100644
index 00000000000..d117f218202
--- /dev/null
+++ b/ext/standard/tests/image/gh20584.phpt
@@ -0,0 +1,39 @@
+--TEST--
+GH-20584 (Information Leak of Memory)
+--CREDITS--
+Nikita Sveshnikov (Positive Technologies)
+--FILE--
+<?php
+// Minimal PoC: corruption/uninitialized memory leak when reading APP1 via php://filter
+$file = __DIR__ . '/gh20584.jpg';
+
+// Make APP1 large enough so it is read in multiple chunks
+$chunk = 8192;
+$tail = 123;
+$payload = str_repeat('A', $chunk) . str_repeat('B', $chunk) . str_repeat('Z',
+$tail);
+$app1Len = 2 + strlen($payload);
+
+// Minimal JPEG: SOI + APP1 + SOF0(1x1) + EOI
+$sof = "\xFF\xC0" . pack('n', 11) . "\x08" . pack('n',1) . pack('n',1) .
+"\x01\x11\x00";
+$jpeg = "\xFF\xD8" . "\xFF\xE1" . pack('n', $app1Len) . $payload . $sof .
+"\xFF\xD9";
+file_put_contents($file, $jpeg);
+
+// Read through a filter to enforce multiple reads
+$src = 'php://filter/read=string.rot13|string.rot13/resource=' . $file;
+$info = null;
+@getimagesize($src, $info);
+$exp = $payload;
+$ret = $info['APP1'];
+
+var_dump($ret === $exp);
+
+?>
+--CLEAN--
+<?php
+@unlink(__DIR__ . '/gh20584.jpg');
+?>
+--EXPECT--
+bool(true)