Fix Heap-Use-After-Free in sapi_read_post_data Processing in CLI SAPI Interface GHSA-4w77-75f9-2c8w Fix Configuring a proxy in a stream context might allow for CRLF injection in URIs CVE-2024-11234 Fix Single byte overread with convert.quoted-printable-decode filter CVE-2024-11233 Fix Leak partial content of the heap through heap buffer over-read CVE-2024-8929 Fix libxml streams use wrong `content-type` header when requesting a redirected resource CVE-2025-1219 Fix Stream HTTP wrapper header check might omit basic auth header CVE-2025-1736 Fix Stream HTTP wrapper truncate redirect location to 1024 bytes CVE-2025-1861 Fix Streams HTTP wrapper does not fail for headers without colon CVE-2025-1734 Fix Header parser of `http` stream wrapper does not handle folded headers CVE-2025-1217 Fix pgsql extension does not check for errors during escaping CVE-2025-1735 Fix NULL Pointer Dereference in PHP SOAP Extension via Large XML Namespace Prefix CVE-2025-6491 Fix Null byte termination in hostnames CVE-2025-1220 Fix Null byte termination in dns_get_record() GHSA-www2-q4fc-65wf Fix Heap buffer overflow in array_merge() CVE-2025-14178 Fix Information Leak of Memory in getimagesize CVE-2025-14177 Resolves: RHEL-141181
108 lines
3.2 KiB
Diff
108 lines
3.2 KiB
Diff
From 6cf0fb3c48fda6a236359304e4db663ae77d858c Mon Sep 17 00:00:00 2001
|
|
From: Niels Dossche <7771979+ndossche@users.noreply.github.com>
|
|
Date: Tue, 25 Nov 2025 23:11:38 +0100
|
|
Subject: [PATCH 1/5] 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 .
|
|
|
|
(cherry picked from commit c5f28c7cf0a052f48e47877c7aa5c5bcc54f1cfc)
|
|
(cherry picked from commit ed665eb1903737d2b52b27368b155f6208604ed9)
|
|
---
|
|
ext/standard/image.c | 20 +++++++++++---
|
|
ext/standard/tests/image/gh20584.phpt | 39 +++++++++++++++++++++++++++
|
|
2 files changed, 56 insertions(+), 3 deletions(-)
|
|
create mode 100644 ext/standard/tests/image/gh20584.phpt
|
|
|
|
diff --git a/ext/standard/image.c b/ext/standard/image.c
|
|
index 4f2c5a505b4..800c5de8da3 100644
|
|
--- a/ext/standard/image.c
|
|
+++ b/ext/standard/image.c
|
|
@@ -434,8 +434,22 @@ static int php_skip_variable(php_stream * stream)
|
|
}
|
|
/* }}} */
|
|
|
|
-/* {{{ php_read_APP
|
|
- */
|
|
+static size_t php_read_stream_all_chunks(php_stream *stream, char *buffer, size_t length)
|
|
+{
|
|
+ size_t read_total = 0;
|
|
+ do {
|
|
+ ssize_t read_now = php_stream_read(stream, buffer, length - read_total);
|
|
+ read_total += read_now;
|
|
+ if (read_now < stream->chunk_size && read_total != length) {
|
|
+ return 0;
|
|
+ }
|
|
+ buffer += read_now;
|
|
+ } while (read_total < length);
|
|
+
|
|
+ return read_total;
|
|
+}
|
|
+
|
|
+/* {{{ php_read_APP */
|
|
static int php_read_APP(php_stream * stream, unsigned int marker, zval *info)
|
|
{
|
|
unsigned short length;
|
|
@@ -451,7 +465,7 @@ static int php_read_APP(php_stream * stream, unsigned int marker, zval *info)
|
|
|
|
buffer = emalloc((size_t)length);
|
|
|
|
- if (php_stream_read(stream, buffer, (size_t) length) != length) {
|
|
+ if (php_read_stream_all_chunks(stream, buffer, length) != length) {
|
|
efree(buffer);
|
|
return 0;
|
|
}
|
|
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)
|
|
--
|
|
2.52.0
|
|
|