mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
Fix GH-15034: Integer overflow on stream_notification_callback byte_max parameter with files bigger than 2GB
We were using atoi, which is only for integers. When the size does not fit in an integer this breaks. Use ZEND_STRTOUL instead. Also make sure invalid data isn't accidentally parsed into a file size. Closes GH-15035.
This commit is contained in:
parent
8de7ccb29b
commit
cfcc2a3fda
2
NEWS
2
NEWS
@ -16,6 +16,8 @@ PHP NEWS
|
|||||||
|
|
||||||
- Streams:
|
- Streams:
|
||||||
. Fixed bug GH-15028 (Memory leak in ext/phar/stream.c). (nielsdos)
|
. Fixed bug GH-15028 (Memory leak in ext/phar/stream.c). (nielsdos)
|
||||||
|
. Fixed bug GH-15034 (Integer overflow on stream_notification_callback
|
||||||
|
byte_max parameter with files bigger than 2GB). (nielsdos)
|
||||||
|
|
||||||
- Tidy:
|
- Tidy:
|
||||||
. Fix memory leaks in ext/tidy basedir restriction code. (nielsdos)
|
. Fix memory leaks in ext/tidy basedir restriction code. (nielsdos)
|
||||||
|
@ -791,8 +791,19 @@ finish:
|
|||||||
} else if (!strncasecmp(http_header_line, "Content-Type:", sizeof("Content-Type:")-1)) {
|
} else if (!strncasecmp(http_header_line, "Content-Type:", sizeof("Content-Type:")-1)) {
|
||||||
php_stream_notify_info(context, PHP_STREAM_NOTIFY_MIME_TYPE_IS, http_header_value, 0);
|
php_stream_notify_info(context, PHP_STREAM_NOTIFY_MIME_TYPE_IS, http_header_value, 0);
|
||||||
} else if (!strncasecmp(http_header_line, "Content-Length:", sizeof("Content-Length:")-1)) {
|
} else if (!strncasecmp(http_header_line, "Content-Length:", sizeof("Content-Length:")-1)) {
|
||||||
file_size = atoi(http_header_value);
|
/* https://www.rfc-editor.org/rfc/rfc9110.html#name-content-length */
|
||||||
php_stream_notify_file_size(context, file_size, http_header_line, 0);
|
const char *ptr = http_header_value;
|
||||||
|
/* must contain only digits, no + or - symbols */
|
||||||
|
if (*ptr >= '0' && *ptr <= '9') {
|
||||||
|
char *endptr = NULL;
|
||||||
|
size_t parsed = ZEND_STRTOUL(ptr, &endptr, 10);
|
||||||
|
/* check whether there was no garbage in the header value and the conversion was successful */
|
||||||
|
if (endptr && !*endptr) {
|
||||||
|
/* truncate for 32-bit such that no negative file sizes occur */
|
||||||
|
file_size = MIN(parsed, ZEND_LONG_MAX);
|
||||||
|
php_stream_notify_file_size(context, file_size, http_header_line, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (
|
} else if (
|
||||||
!strncasecmp(http_header_line, "Transfer-Encoding:", sizeof("Transfer-Encoding:")-1)
|
!strncasecmp(http_header_line, "Transfer-Encoding:", sizeof("Transfer-Encoding:")-1)
|
||||||
&& !strncasecmp(http_header_value, "Chunked", sizeof("Chunked")-1)
|
&& !strncasecmp(http_header_value, "Chunked", sizeof("Chunked")-1)
|
||||||
|
44
ext/standard/tests/http/gh15034.phpt
Normal file
44
ext/standard/tests/http/gh15034.phpt
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
--TEST--
|
||||||
|
GH-15034 (Integer overflow on stream_notification_callback byte_max parameter with files bigger than 2GB)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
require 'server.inc';
|
||||||
|
http_server_skipif();
|
||||||
|
if (PHP_INT_SIZE != 8) die("skip 64-bit only");
|
||||||
|
?>
|
||||||
|
--INI--
|
||||||
|
allow_url_fopen=1
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
require 'server.inc';
|
||||||
|
|
||||||
|
$responses = [
|
||||||
|
"data://text/plain,HTTP/1.1 200 OK\r\n"
|
||||||
|
. "Content-Type: text/plain\r\n"
|
||||||
|
. "Content-Length: 3000000000\r\n\r\n"
|
||||||
|
. "foo\n",
|
||||||
|
];
|
||||||
|
['pid' => $pid, 'uri' => $uri] = http_server($responses);
|
||||||
|
|
||||||
|
$params = ['notification' => function(
|
||||||
|
int $notification_code,
|
||||||
|
int $severity,
|
||||||
|
?string $message,
|
||||||
|
int $message_code,
|
||||||
|
int $bytes_transferred,
|
||||||
|
int $bytes_max
|
||||||
|
) {
|
||||||
|
global $max;
|
||||||
|
$max = $bytes_max;
|
||||||
|
}];
|
||||||
|
$contextResource = stream_context_create([], $params);
|
||||||
|
|
||||||
|
$resource = fopen($uri, 'r', false, $contextResource);
|
||||||
|
fclose($resource);
|
||||||
|
|
||||||
|
http_server_kill($pid);
|
||||||
|
|
||||||
|
var_dump($max);
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
int(3000000000)
|
Loading…
Reference in New Issue
Block a user