mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3: Fix GH-20584: Information Leak of Memory Fix GH-20583: Stack overflow in http_build_query via deep structures
This commit is contained in:
3
NEWS
3
NEWS
@@ -62,6 +62,9 @@ PHP NEWS
|
||||
|
||||
- Standard:
|
||||
. Fix memory leak in array_diff() with custom type checks. (ndossche)
|
||||
. Fixed bug GH-20583 (Stack overflow in http_build_query
|
||||
via deep structures). (ndossche)
|
||||
. Fixed bug GH-20584 (Information Leak of Memory). (ndossche)
|
||||
|
||||
- Tidy:
|
||||
. Fixed bug GH-20374 (PHP with tidy and custom-tags). (ndossche)
|
||||
|
||||
@@ -105,6 +105,15 @@ try_again:
|
||||
}
|
||||
}
|
||||
|
||||
static zend_always_inline bool php_url_check_stack_limit(void)
|
||||
{
|
||||
#ifdef ZEND_CHECK_STACK_LIMIT
|
||||
return zend_call_stack_overflowed(EG(stack_limit));
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* {{{ php_url_encode_hash */
|
||||
PHPAPI void php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
|
||||
const char *num_prefix, size_t num_prefix_len,
|
||||
@@ -123,6 +132,12 @@ PHPAPI void php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
|
||||
return;
|
||||
}
|
||||
|
||||
/* Very deeply structured data could trigger a stack overflow, even without recursion. */
|
||||
if (UNEXPECTED(php_url_check_stack_limit())) {
|
||||
zend_throw_error(NULL, "Maximum call stack size reached.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!arg_sep) {
|
||||
arg_sep = zend_ini_str("arg_separator.output", strlen("arg_separator.output"), false);
|
||||
if (ZSTR_LEN(arg_sep) == 0) {
|
||||
|
||||
@@ -403,6 +403,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;
|
||||
|
||||
27
ext/standard/tests/http/http_build_query/gh20583.phpt
Normal file
27
ext/standard/tests/http/http_build_query/gh20583.phpt
Normal file
@@ -0,0 +1,27 @@
|
||||
--TEST--
|
||||
GH-20583 (Stack overflow in http_build_query via deep structures)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (ini_get('zend.max_allowed_stack_size') === false) {
|
||||
die('skip No stack limit support');
|
||||
}
|
||||
if (getenv('SKIP_ASAN')) {
|
||||
die('skip ASAN needs different stack limit setting due to more stack space usage');
|
||||
}
|
||||
?>
|
||||
--INI--
|
||||
zend.max_allowed_stack_size=512K
|
||||
--FILE--
|
||||
<?php
|
||||
$a = null;
|
||||
for ($i = 0; $i < 5000; $i++) {
|
||||
$a = [$i => $a];
|
||||
}
|
||||
try {
|
||||
http_build_query($a, 'p');
|
||||
} catch (Throwable $e) {
|
||||
echo $e::class, ": ", $e->getMessage(), "\n";
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
Error: Maximum call stack size reached.
|
||||
39
ext/standard/tests/image/gh20584.phpt
Normal file
39
ext/standard/tests/image/gh20584.phpt
Normal file
@@ -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)
|
||||
Reference in New Issue
Block a user