Skip to content

Commit 8fe7930

Browse files
committed
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. Closes GH-20592.
1 parent 292a7f7 commit 8fe7930

File tree

3 files changed

+41
-0
lines changed

3 files changed

+41
-0
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ PHP NEWS
6060
. Fix memory leak in array_diff() with custom type checks. (ndossche)
6161
. Fixed bug GH-20583 (Stack overflow in http_build_query
6262
via deep structures). (ndossche)
63+
. Fixed bug GH-20584 (Information Leak of Memory). (ndossche)
6364

6465
- Tidy:
6566
. Fixed bug GH-20374 (PHP with tidy and custom-tags). (ndossche)

ext/standard/image.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ static size_t php_read_stream_all_chunks(php_stream *stream, char *buffer, size_
403403
if (read_now < stream->chunk_size && read_total != length) {
404404
return 0;
405405
}
406+
buffer += read_now;
406407
} while (read_total < length);
407408

408409
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)