Commit d418a62648a for php
commit d418a62648a51b942a0bd93e05a8d44794a5c861
Author: Jakub Zelenka <bukka@php.net>
Date: Tue Oct 6 16:42:29 2026 +0000
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
diff --git a/NEWS b/NEWS
index 149d91b607a..98d29e0ad78 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 1ba650c83e1..c45ae86a3fa 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 00000000000..9991fe68e76
--- /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--