Skip to content

Commit c5f28c7

Browse files
ndosschebukka
authored andcommitted
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 .
1 parent 2bf2411 commit c5f28c7

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

ext/standard/image.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ static size_t php_read_stream_all_chunks(php_stream *stream, char *buffer, size_
434434
if (read_now < stream->chunk_size && read_total != length) {
435435
return 0;
436436
}
437+
buffer += read_now;
437438
} while (read_total < length);
438439

439440
return read_total;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
--TEST--
2+
GH-20584 (Information Leak of Memory)
3+
--CREDITS--
4+
Nikita Sveshnikov (Positive Technologies)
5+
--FILE--
6+
<?php
7+
// Minimal PoC: corruption/uninitialized memory leak when reading APP1 via php://filter
8+
$file = __DIR__ . '/gh20584.jpg';
9+
10+
// Make APP1 large enough so it is read in multiple chunks
11+
$chunk = 8192;
12+
$tail = 123;
13+
$payload = str_repeat('A', $chunk) . str_repeat('B', $chunk) . str_repeat('Z',
14+
$tail);
15+
$app1Len = 2 + strlen($payload);
16+
17+
// Minimal JPEG: SOI + APP1 + SOF0(1x1) + EOI
18+
$sof = "\xFF\xC0" . pack('n', 11) . "\x08" . pack('n',1) . pack('n',1) .
19+
"\x01\x11\x00";
20+
$jpeg = "\xFF\xD8" . "\xFF\xE1" . pack('n', $app1Len) . $payload . $sof .
21+
"\xFF\xD9";
22+
file_put_contents($file, $jpeg);
23+
24+
// Read through a filter to enforce multiple reads
25+
$src = 'php://filter/read=string.rot13|string.rot13/resource=' . $file;
26+
$info = null;
27+
@getimagesize($src, $info);
28+
$exp = $payload;
29+
$ret = $info['APP1'];
30+
31+
var_dump($ret === $exp);
32+
33+
?>
34+
--CLEAN--
35+
<?php
36+
@unlink(__DIR__ . '/gh20584.jpg');
37+
?>
38+
--EXPECT--
39+
bool(true)

0 commit comments

Comments
 (0)