diff --git a/NEWS b/NEWS index b3ba4bce032..f411e6caf38 100644 --- a/NEWS +++ b/NEWS @@ -70,6 +70,10 @@ PHP NEWS . Fixed bug GH-16187 (Assertion failure in ext/reflection/php_reflection.c). (DanielEScherzer) +- SAPI: + . Fixed bug GH-15395 (php-fpm: zend_mm_heap corrupted with cgi-fcgi request). + (Jakub Zelenka, David Carlier) + - SimpleXML: . Fixed bug GH-15837 (Segmentation fault in ext/simplexml/simplexml.c). (nielsdos) diff --git a/main/SAPI.c b/main/SAPI.c index 2e697f97796..d960ba049a0 100644 --- a/main/SAPI.c +++ b/main/SAPI.c @@ -509,12 +509,15 @@ SAPI_API void sapi_deactivate_module(void) } if (SG(request_info).auth_user) { efree(SG(request_info).auth_user); + SG(request_info).auth_user = NULL; } if (SG(request_info).auth_password) { efree(SG(request_info).auth_password); + SG(request_info).auth_password = NULL; } if (SG(request_info).auth_digest) { efree(SG(request_info).auth_digest); + SG(request_info).auth_digest = NULL; } if (SG(request_info).content_type_dup) { efree(SG(request_info).content_type_dup); diff --git a/main/main.c b/main/main.c index eb6f17c1eed..591daaef3f5 100644 --- a/main/main.c +++ b/main/main.c @@ -2622,7 +2622,9 @@ PHPAPI int php_handle_auth_data(const char *auth) if (pass) { *pass++ = '\0'; SG(request_info).auth_user = estrndup(ZSTR_VAL(user), ZSTR_LEN(user)); - SG(request_info).auth_password = estrdup(pass); + if (strlen(pass) > 0) { + SG(request_info).auth_password = estrdup(pass); + } ret = 0; } zend_string_free(user); diff --git a/sapi/fpm/tests/gh15395-php-auth-shutdown.phpt b/sapi/fpm/tests/gh15395-php-auth-shutdown.phpt new file mode 100644 index 00000000000..b9875dd10ef --- /dev/null +++ b/sapi/fpm/tests/gh15395-php-auth-shutdown.phpt @@ -0,0 +1,61 @@ +--TEST-- +FPM: GH-15335 - PHP_AUTH shutdown use after free +--SKIPIF-- + +--FILE-- +createSourceFileAndScriptName(); +$tester->start(); +$tester->expectLogStartNotices(); +$tester + ->request( + headers: [ "HTTP_AUTHORIZATION" => "Basic Zm9vOg==", "REQUEST_METHOD" => "GET"], + uri: $scriptName, + address: '{{ADDR}}', + scriptFilename: __DIR__ . "/__unknown.php", + scriptName: "/", + ) + ->expectStatus('404 Not Found'); +$tester + ->request( + uri: $scriptName, + address: '{{ADDR}}', + params: [], + ); +$tester->expectNoLogPattern("/zend_mm_heap corrupted/"); +$tester->terminate(); +$tester->expectLogTerminatingNotices(); +$tester->close(); + +?> +Done +--EXPECT-- +Done +--CLEAN-- + diff --git a/sapi/fpm/tests/tester.inc b/sapi/fpm/tests/tester.inc index d4745ee56c9..e6c971c32e4 100644 --- a/sapi/fpm/tests/tester.inc +++ b/sapi/fpm/tests/tester.inc @@ -848,6 +848,7 @@ class Tester bool $expectError = false, int $readLimit = -1, int $writeDelay = 0, + array $params = null, ): Response { if ($this->hasError()) { return $this->createResponse(expectInvalid: true); @@ -857,7 +858,7 @@ class Tester $stdin = $this->parseStdin($stdin, $headers); } - $params = $this->getRequestParams($query, $headers, $uri, $scriptFilename, $scriptName, $stdin); + $params = $params ?? $this->getRequestParams($query, $headers, $uri, $scriptFilename, $scriptName, $stdin); $this->trace('Request params', $params); try {