mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
Merge branch 'PHP-8.2' into PHP-8.3
This commit is contained in:
commit
6d99ccc268
8 changed files with 243 additions and 32 deletions
17
NEWS
17
NEWS
|
@ -45,7 +45,14 @@ PHP NEWS
|
||||||
- Windows:
|
- Windows:
|
||||||
. Fixed minimal Windows version. (cmb)
|
. Fixed minimal Windows version. (cmb)
|
||||||
|
|
||||||
12 Sep 2024, PHP 8.3.12
|
26 Sep 2024, PHP 8.3.12
|
||||||
|
|
||||||
|
- CGI:
|
||||||
|
. Fixed bug GHSA-p99j-rfp4-xqvq (Bypass of CVE-2024-4577, Parameter Injection
|
||||||
|
Vulnerability). (CVE-2024-8926) (nielsdos)
|
||||||
|
. Fixed bug GHSA-94p6-54jq-9mwp (cgi.force_redirect configuration is
|
||||||
|
bypassable due to the environment variable collision). (CVE-2024-8927)
|
||||||
|
(nielsdos)
|
||||||
|
|
||||||
- Core:
|
- Core:
|
||||||
. Fixed bug GH-15408 (MSan false-positve on zend_max_execution_timer).
|
. Fixed bug GH-15408 (MSan false-positve on zend_max_execution_timer).
|
||||||
|
@ -73,6 +80,10 @@ PHP NEWS
|
||||||
. Fixed bug GH-15752 (Incorrect error message for finfo_file
|
. Fixed bug GH-15752 (Incorrect error message for finfo_file
|
||||||
with an empty filename argument). (DanielEScherzer)
|
with an empty filename argument). (DanielEScherzer)
|
||||||
|
|
||||||
|
- FPM:
|
||||||
|
. Fixed bug GHSA-865w-9rf3-2wh5 (Logs from childrens may be altered).
|
||||||
|
(CVE-2024-9026) (Jakub Zelenka)
|
||||||
|
|
||||||
- MySQLnd:
|
- MySQLnd:
|
||||||
. Fixed bug GH-15432 (Heap corruption when querying a vector). (cmb,
|
. Fixed bug GH-15432 (Heap corruption when querying a vector). (cmb,
|
||||||
Kamil Tekiela)
|
Kamil Tekiela)
|
||||||
|
@ -83,6 +94,10 @@ PHP NEWS
|
||||||
. Fixed bug GH-15658 (Segmentation fault in Zend/zend_vm_execute.h).
|
. Fixed bug GH-15658 (Segmentation fault in Zend/zend_vm_execute.h).
|
||||||
(nielsdos)
|
(nielsdos)
|
||||||
|
|
||||||
|
- SAPI:
|
||||||
|
. Fixed bug GHSA-9pqp-7h25-4f32 (Erroneous parsing of multipart form data).
|
||||||
|
(CVE-2024-8925) (Arnaud)
|
||||||
|
|
||||||
- Standard:
|
- Standard:
|
||||||
. Fixed bug GH-15552 (Signed integer overflow in ext/standard/scanf.c). (cmb)
|
. Fixed bug GH-15552 (Signed integer overflow in ext/standard/scanf.c). (cmb)
|
||||||
|
|
||||||
|
|
|
@ -729,6 +729,13 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */
|
||||||
boundary_len = boundary_end-boundary;
|
boundary_len = boundary_end-boundary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Boundaries larger than FILLUNIT-strlen("\r\n--") characters lead to
|
||||||
|
* erroneous parsing */
|
||||||
|
if (boundary_len > FILLUNIT-strlen("\r\n--")) {
|
||||||
|
sapi_module.sapi_error(E_WARNING, "Boundary too large in multipart/form-data POST data");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize the buffer */
|
/* Initialize the buffer */
|
||||||
if (!(mbuff = multipart_buffer_new(boundary, boundary_len))) {
|
if (!(mbuff = multipart_buffer_new(boundary, boundary_len))) {
|
||||||
sapi_module.sapi_error(E_WARNING, "Unable to initialize the input buffer");
|
sapi_module.sapi_error(E_WARNING, "Unable to initialize the input buffer");
|
||||||
|
|
|
@ -1746,7 +1746,6 @@ int main(int argc, char *argv[])
|
||||||
int status = 0;
|
int status = 0;
|
||||||
#endif
|
#endif
|
||||||
char *query_string;
|
char *query_string;
|
||||||
char *decoded_query_string;
|
|
||||||
int skip_getopt = 0;
|
int skip_getopt = 0;
|
||||||
|
|
||||||
#if defined(SIGPIPE) && defined(SIG_IGN)
|
#if defined(SIGPIPE) && defined(SIG_IGN)
|
||||||
|
@ -1801,10 +1800,15 @@ int main(int argc, char *argv[])
|
||||||
* the executable. Ideally we skip argument parsing when we're in cgi or fastcgi mode,
|
* the executable. Ideally we skip argument parsing when we're in cgi or fastcgi mode,
|
||||||
* but that breaks PHP scripts on Linux with a hashbang: `#!/php-cgi -d option=value`.
|
* but that breaks PHP scripts on Linux with a hashbang: `#!/php-cgi -d option=value`.
|
||||||
* Therefore, this code only prevents passing arguments if the query string starts with a '-'.
|
* Therefore, this code only prevents passing arguments if the query string starts with a '-'.
|
||||||
* Similarly, scripts spawned in subprocesses on Windows may have the same issue. */
|
* Similarly, scripts spawned in subprocesses on Windows may have the same issue.
|
||||||
|
* However, Windows has lots of conversion rules and command line parsing rules that
|
||||||
|
* are too difficult and dangerous to reliably emulate. */
|
||||||
if((query_string = getenv("QUERY_STRING")) != NULL && strchr(query_string, '=') == NULL) {
|
if((query_string = getenv("QUERY_STRING")) != NULL && strchr(query_string, '=') == NULL) {
|
||||||
|
#ifdef PHP_WIN32
|
||||||
|
skip_getopt = cgi || fastcgi;
|
||||||
|
#else
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
decoded_query_string = strdup(query_string);
|
char *decoded_query_string = strdup(query_string);
|
||||||
php_url_decode(decoded_query_string, strlen(decoded_query_string));
|
php_url_decode(decoded_query_string, strlen(decoded_query_string));
|
||||||
for (p = (unsigned char *)decoded_query_string; *p && *p <= ' '; p++) {
|
for (p = (unsigned char *)decoded_query_string; *p && *p <= ' '; p++) {
|
||||||
/* skip all leading spaces */
|
/* skip all leading spaces */
|
||||||
|
@ -1813,22 +1817,8 @@ int main(int argc, char *argv[])
|
||||||
skip_getopt = 1;
|
skip_getopt = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* On Windows we have to take into account the "best fit" mapping behaviour. */
|
|
||||||
#ifdef PHP_WIN32
|
|
||||||
if (*p >= 0x80) {
|
|
||||||
wchar_t wide_buf[1];
|
|
||||||
wide_buf[0] = *p;
|
|
||||||
char char_buf[4];
|
|
||||||
size_t wide_buf_len = sizeof(wide_buf) / sizeof(wide_buf[0]);
|
|
||||||
size_t char_buf_len = sizeof(char_buf) / sizeof(char_buf[0]);
|
|
||||||
if (WideCharToMultiByte(CP_ACP, 0, wide_buf, wide_buf_len, char_buf, char_buf_len, NULL, NULL) == 0
|
|
||||||
|| char_buf[0] == '-') {
|
|
||||||
skip_getopt = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
free(decoded_query_string);
|
free(decoded_query_string);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
php_ini_builder_init(&ini_builder);
|
php_ini_builder_init(&ini_builder);
|
||||||
|
@ -1895,18 +1885,17 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
/* check force_cgi after startup, so we have proper output */
|
/* check force_cgi after startup, so we have proper output */
|
||||||
if (cgi && CGIG(force_redirect)) {
|
if (cgi && CGIG(force_redirect)) {
|
||||||
/* Apache will generate REDIRECT_STATUS,
|
/* This is to allow a different environment variable to be configured
|
||||||
* Netscape and redirect.so will generate HTTP_REDIRECT_STATUS.
|
* in case the we cannot auto-detect which environment variable to use.
|
||||||
* redirect.so and installation instructions available from
|
* Checking this first to allow user overrides in case the environment
|
||||||
* http://www.koehntopp.de/php.
|
* variable can be set by an untrusted party. */
|
||||||
* -- kk@netuse.de
|
const char *redirect_status_env = CGIG(redirect_status_env);
|
||||||
*/
|
if (!redirect_status_env) {
|
||||||
if (!getenv("REDIRECT_STATUS") &&
|
/* Apache will generate REDIRECT_STATUS. */
|
||||||
!getenv ("HTTP_REDIRECT_STATUS") &&
|
redirect_status_env = "REDIRECT_STATUS";
|
||||||
/* this is to allow a different env var to be configured
|
}
|
||||||
* in case some server does something different than above */
|
|
||||||
(!CGIG(redirect_status_env) || !getenv(CGIG(redirect_status_env)))
|
if (!getenv(redirect_status_env)) {
|
||||||
) {
|
|
||||||
zend_try {
|
zend_try {
|
||||||
SG(sapi_headers).http_response_code = 400;
|
SG(sapi_headers).http_response_code = 400;
|
||||||
PUTS("<b>Security Alert!</b> The PHP CGI cannot be accessed directly.\n\n\
|
PUTS("<b>Security Alert!</b> The PHP CGI cannot be accessed directly.\n\n\
|
||||||
|
|
|
@ -228,7 +228,7 @@ stdio_read:
|
||||||
if ((sizeof(FPM_STDIO_CMD_FLUSH) - cmd_pos) <= in_buf &&
|
if ((sizeof(FPM_STDIO_CMD_FLUSH) - cmd_pos) <= in_buf &&
|
||||||
!memcmp(buf, &FPM_STDIO_CMD_FLUSH[cmd_pos], sizeof(FPM_STDIO_CMD_FLUSH) - cmd_pos)) {
|
!memcmp(buf, &FPM_STDIO_CMD_FLUSH[cmd_pos], sizeof(FPM_STDIO_CMD_FLUSH) - cmd_pos)) {
|
||||||
zlog_stream_finish(log_stream);
|
zlog_stream_finish(log_stream);
|
||||||
start = cmd_pos;
|
start = sizeof(FPM_STDIO_CMD_FLUSH) - cmd_pos;
|
||||||
} else {
|
} else {
|
||||||
zlog_stream_str(log_stream, &FPM_STDIO_CMD_FLUSH[0], cmd_pos);
|
zlog_stream_str(log_stream, &FPM_STDIO_CMD_FLUSH[0], cmd_pos);
|
||||||
}
|
}
|
||||||
|
|
47
sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-end.phpt
Normal file
47
sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-end.phpt
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
--TEST--
|
||||||
|
FPM: Buffered worker output plain log with msg with flush split position towards separator end
|
||||||
|
--SKIPIF--
|
||||||
|
<?php include "skipif.inc"; ?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once "tester.inc";
|
||||||
|
|
||||||
|
$cfg = <<<EOT
|
||||||
|
[global]
|
||||||
|
error_log = {{FILE:LOG}}
|
||||||
|
[unconfined]
|
||||||
|
listen = {{ADDR}}
|
||||||
|
pm = dynamic
|
||||||
|
pm.max_children = 5
|
||||||
|
pm.start_servers = 1
|
||||||
|
pm.min_spare_servers = 1
|
||||||
|
pm.max_spare_servers = 3
|
||||||
|
catch_workers_output = yes
|
||||||
|
decorate_workers_output = no
|
||||||
|
EOT;
|
||||||
|
|
||||||
|
$code = <<<EOT
|
||||||
|
<?php
|
||||||
|
file_put_contents('php://stderr', str_repeat('a', 1013) . "Quarkslab\0fscf\0Quarkslab");
|
||||||
|
EOT;
|
||||||
|
|
||||||
|
$tester = new FPM\Tester($cfg, $code);
|
||||||
|
$tester->start();
|
||||||
|
$tester->expectLogStartNotices();
|
||||||
|
$tester->request()->expectEmptyBody();
|
||||||
|
$tester->expectLogLine(str_repeat('a', 1013) . "Quarkslab", decorated: false);
|
||||||
|
$tester->expectLogLine("Quarkslab", decorated: false);
|
||||||
|
$tester->terminate();
|
||||||
|
$tester->expectLogTerminatingNotices();
|
||||||
|
$tester->close();
|
||||||
|
|
||||||
|
?>
|
||||||
|
Done
|
||||||
|
--EXPECT--
|
||||||
|
Done
|
||||||
|
--CLEAN--
|
||||||
|
<?php
|
||||||
|
require_once "tester.inc";
|
||||||
|
FPM\Tester::clean();
|
||||||
|
?>
|
47
sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-start.phpt
Normal file
47
sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-start.phpt
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
--TEST--
|
||||||
|
FPM: Buffered worker output plain log with msg with flush split position towards separator start
|
||||||
|
--SKIPIF--
|
||||||
|
<?php include "skipif.inc"; ?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once "tester.inc";
|
||||||
|
|
||||||
|
$cfg = <<<EOT
|
||||||
|
[global]
|
||||||
|
error_log = {{FILE:LOG}}
|
||||||
|
[unconfined]
|
||||||
|
listen = {{ADDR}}
|
||||||
|
pm = dynamic
|
||||||
|
pm.max_children = 5
|
||||||
|
pm.start_servers = 1
|
||||||
|
pm.min_spare_servers = 1
|
||||||
|
pm.max_spare_servers = 3
|
||||||
|
catch_workers_output = yes
|
||||||
|
decorate_workers_output = no
|
||||||
|
EOT;
|
||||||
|
|
||||||
|
$code = <<<EOT
|
||||||
|
<?php
|
||||||
|
file_put_contents('php://stderr', str_repeat('a', 1009) . "Quarkslab\0fscf\0Quarkslab");
|
||||||
|
EOT;
|
||||||
|
|
||||||
|
$tester = new FPM\Tester($cfg, $code);
|
||||||
|
$tester->start();
|
||||||
|
$tester->expectLogStartNotices();
|
||||||
|
$tester->request()->expectEmptyBody();
|
||||||
|
$tester->expectLogLine(str_repeat('a', 1009) . "Quarkslab", decorated: false);
|
||||||
|
$tester->expectLogLine("Quarkslab", decorated: false);
|
||||||
|
$tester->terminate();
|
||||||
|
$tester->expectLogTerminatingNotices();
|
||||||
|
$tester->close();
|
||||||
|
|
||||||
|
?>
|
||||||
|
Done
|
||||||
|
--EXPECT--
|
||||||
|
Done
|
||||||
|
--CLEAN--
|
||||||
|
<?php
|
||||||
|
require_once "tester.inc";
|
||||||
|
FPM\Tester::clean();
|
||||||
|
?>
|
3
tests/basic/GHSA-9pqp-7h25-4f32.inc
Normal file
3
tests/basic/GHSA-9pqp-7h25-4f32.inc
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<?php
|
||||||
|
print "Hello world\n";
|
||||||
|
var_dump($_POST);
|
103
tests/basic/GHSA-9pqp-7h25-4f32.phpt
Normal file
103
tests/basic/GHSA-9pqp-7h25-4f32.phpt
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
--TEST--
|
||||||
|
GHSA-9pqp-7h25-4f32
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if (!getenv('TEST_PHP_CGI_EXECUTABLE')) {
|
||||||
|
die("skip php-cgi not available");
|
||||||
|
}
|
||||||
|
if (substr(PHP_OS, 0, 3) == 'WIN') {
|
||||||
|
die("skip not for Windows in CI - probably resource issue");
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
const FILLUNIT = 5 * 1024;
|
||||||
|
|
||||||
|
function test($boundaryLen) {
|
||||||
|
printf("Boundary len: %d\n", $boundaryLen);
|
||||||
|
|
||||||
|
$cmd = [
|
||||||
|
getenv('TEST_PHP_CGI_EXECUTABLE'),
|
||||||
|
'-C',
|
||||||
|
'-n',
|
||||||
|
__DIR__ . '/GHSA-9pqp-7h25-4f32.inc',
|
||||||
|
];
|
||||||
|
|
||||||
|
$boundary = str_repeat('A', $boundaryLen);
|
||||||
|
$body = ""
|
||||||
|
. "--$boundary\r\n"
|
||||||
|
. "Content-Disposition: form-data; name=\"koko\"\r\n"
|
||||||
|
. "\r\n"
|
||||||
|
. "BBB\r\n--" . substr($boundary, 0, -1) . "CCC\r\n"
|
||||||
|
. "--$boundary--\r\n"
|
||||||
|
;
|
||||||
|
|
||||||
|
$env = array_merge($_ENV, [
|
||||||
|
'REDIRECT_STATUS' => '1',
|
||||||
|
'CONTENT_TYPE' => "multipart/form-data; boundary=$boundary",
|
||||||
|
'CONTENT_LENGTH' => strlen($body),
|
||||||
|
'REQUEST_METHOD' => 'POST',
|
||||||
|
'SCRIPT_FILENAME' => __DIR__ . '/GHSA-9pqp-7h25-4f32.inc',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$spec = [
|
||||||
|
0 => ['pipe', 'r'],
|
||||||
|
1 => STDOUT,
|
||||||
|
2 => STDOUT,
|
||||||
|
];
|
||||||
|
|
||||||
|
$pipes = [];
|
||||||
|
|
||||||
|
print "Starting...\n";
|
||||||
|
|
||||||
|
$handle = proc_open($cmd, $spec, $pipes, getcwd(), $env);
|
||||||
|
|
||||||
|
fwrite($pipes[0], $body);
|
||||||
|
|
||||||
|
$status = proc_close($handle);
|
||||||
|
|
||||||
|
print "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
for ($offset = -1; $offset <= 1; $offset++) {
|
||||||
|
test(FILLUNIT - strlen("\r\n--") + $offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
Boundary len: 5115
|
||||||
|
Starting...
|
||||||
|
X-Powered-By: %s
|
||||||
|
Content-type: text/html; charset=UTF-8
|
||||||
|
|
||||||
|
Hello world
|
||||||
|
array(1) {
|
||||||
|
["koko"]=>
|
||||||
|
string(5124) "BBB
|
||||||
|
--AAA%sCCC"
|
||||||
|
}
|
||||||
|
|
||||||
|
Boundary len: 5116
|
||||||
|
Starting...
|
||||||
|
X-Powered-By: %s
|
||||||
|
Content-type: text/html; charset=UTF-8
|
||||||
|
|
||||||
|
Hello world
|
||||||
|
array(1) {
|
||||||
|
["koko"]=>
|
||||||
|
string(5125) "BBB
|
||||||
|
--AAA%sCCC"
|
||||||
|
}
|
||||||
|
|
||||||
|
Boundary len: 5117
|
||||||
|
Starting...
|
||||||
|
X-Powered-By: %s
|
||||||
|
Content-type: text/html; charset=UTF-8
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<b>Warning</b>: Boundary too large in multipart/form-data POST data in <b>Unknown</b> on line <b>0</b><br />
|
||||||
|
Hello world
|
||||||
|
array(0) {
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue