[php-src] PHP-8.6: ext/phar: Fix double-free in webPhar() without PATH_INFO (#24166)

From: Date: Tue, 06 Oct 2026 17:54:21 +0000
Subject: [php-src] PHP-8.6: ext/phar: Fix double-free in webPhar() without PATH_INFO (#24166)
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-142022@lists.php.net to get a copy of this message
Author: Jakub Zelenka (bukka) Committer: Weilin Du (LamentXU123) Date: 2026-10-07T01:52:58+08:00 Commit: https://github.com/php/php-src/commit/d418a62648a51b942a0bd93e05a8d44794a5c861 Raw diff: https://github.com/php/php-src/commit/d418a62648a51b942a0bd93e05a8d44794a5c861.diff ext/phar: Fix double-free in webPhar() without PATH_INFO (#24166) In the CGI/FastCGI branch of webPhar(), when SCRIPT_NAME is present but PATH_INFO is absent, path_info was aliased to the testit buffer and free_pathinfo was set. Since commit 3ee2f442d20 added an unconditional efree(testit) after that branch, path_info became a dangling pointer. This causes a use-after-free when path_info is read later and a double-free at cleanup_skip_entry when free_pathinfo triggers efree(path_info). The regression was introduced in PHP 8.6. Earlier release branches do not free testit at this point. Allocate a dedicated copy for path_info so its lifetime outlives the efree(testit). Reported by RigelYoung. Closes #24166 Changed paths: A ext/phar/tests/webphar_cgi_no_path_info.phpt M NEWS M ext/phar/phar_object.c Diff: diff --git a/NEWS b/NEWS index 149d91b607a5..98d29e0ad782 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.6.0RC4 +- Phar: + . Fixed GH-24166 (Double-free in Phar::webPhar() in CGI without PATH_INFO). + (RigelYoung, Jakub Zelenka) 08 Oct 2026, PHP 8.6.0RC3 diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 1ba650c83e15..c45ae86a3fa5 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -665,7 +665,7 @@ PHP_METHOD(Phar, webPhar) spprintf(&path_info, 0, "%s%s", testit, path_info); free_pathinfo = 1; } else { - path_info = testit; + path_info = estrdup(testit); free_pathinfo = 1; entry = estrndup("", 0); entry_len = 0; diff --git a/ext/phar/tests/webphar_cgi_no_path_info.phpt b/ext/phar/tests/webphar_cgi_no_path_info.phpt new file mode 100644 index 000000000000..9991fe68e76f --- /dev/null +++ b/ext/phar/tests/webphar_cgi_no_path_info.phpt @@ -0,0 +1,31 @@ +--TEST-- +Phar::webPhar() double free in CGI when SCRIPT_NAME is set but PATH_INFO is absent +--CGI-- +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +phar.require_hash=0 +variables_order=EGPC +register_argc_argv=0 +cgi.fix_pathinfo=0 +--ENV-- +REQUEST_METHOD=GET +SCRIPT_NAME=/webphar_cgi_no_path_info.phar +--FILE-- +<?php +$fname = __DIR__ . '/' . basename(__FILE__, '.php') . '.phar'; +$phar = new Phar($fname); +$phar->addFromString('index.php', '<?php echo "ok\n"; ?>'); +$phar->setStub('<?php +Phar::webPhar(); +__HALT_COMPILER(); ?>'); +unset($phar); +include $fname; +?> +--CLEAN-- +<?php @unlink(__DIR__ . '/' . basename(__FILE__, '.clean.php') . '.phar'); ?> +--EXPECTHEADERS-- +Status: 301 Moved Permanently +Location: /webphar_cgi_no_path_info.phar/index.php +--EXPECT--

« previous php.cvs (#142022) next »