Skip to content

Commit 569cf59

Browse files
committed
phar: Fix double-free in webPhar() without PATH_INFO
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 3ee2f44 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 the cleanup_skip_entry label where free_pathinfo triggers efree(path_info). This only affects PHP-8.6 as earlier branches do not free testit there. Allocate a dedicated copy for path_info so its lifetime outlives the efree(testit). Reported by RigelYoung. Closes GH-24166
1 parent 7aa003e commit 569cf59

2 files changed

Lines changed: 32 additions & 1 deletion

File tree

‎ext/phar/phar_object.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,7 @@ PHP_METHOD(Phar, webPhar)
665665
spprintf(&path_info, 0, "%s%s", testit, path_info);
666666
free_pathinfo = 1;
667667
} else {
668-
path_info = testit;
668+
path_info = estrdup(testit);
669669
free_pathinfo = 1;
670670
entry = estrndup("", 0);
671671
entry_len = 0;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
--TEST--
2+
Phar::webPhar() double free in CGI when SCRIPT_NAME is set but PATH_INFO is absent
3+
--CGI--
4+
--EXTENSIONS--
5+
phar
6+
--INI--
7+
phar.readonly=0
8+
phar.require_hash=0
9+
variables_order=EGPC
10+
register_argc_argv=0
11+
cgi.fix_pathinfo=0
12+
--ENV--
13+
REQUEST_METHOD=GET
14+
SCRIPT_NAME=/webphar_cgi_no_path_info.phar
15+
--FILE--
16+
<?php
17+
$fname = __DIR__ . '/' . basename(__FILE__, '.php') . '.phar';
18+
$phar = new Phar($fname);
19+
$phar->addFromString('index.php', '<?php echo "ok\n"; ?>');
20+
$phar->setStub('<?php
21+
Phar::webPhar();
22+
__HALT_COMPILER(); ?>');
23+
unset($phar);
24+
include $fname;
25+
?>
26+
--CLEAN--
27+
<?php @unlink(__DIR__ . '/' . basename(__FILE__, '.clean.php') . '.phar'); ?>
28+
--EXPECTHEADERS--
29+
Status: 301 Moved Permanently
30+
Location: /webphar_cgi_no_path_info.phar/index.php
31+
--EXPECT--

0 commit comments

Comments
 (0)