[php-src] master: Merge branch 'PHP-8.4' into PHP-8.5
Weilin Du <[email protected]>
| Newsgroups | gmane.comp.php.cvs.general |
|---|---|
| Message-ID | <[email protected]> |
Author: Weilin Du (LamentXU123)
Date: 2026-08-27T00:12:16+08:00
Commit: https://github.com/php/php-src/commit/c91cc1a25dfb7dd8c10e1524fdb877b172198a1c
Raw diff: https://github.com/php/php-src/commit/c91cc1a25dfb7dd8c10e1524fdb877b172198a1c.diff
Merge branch 'PHP-8.4' into PHP-8.5
* origin/PHP-8.4:
Fix GH-23418: UAF when accessing mounted Phar subdirectories (#23442)
Changed paths:
A ext/phar/tests/gh23418.phpt
M NEWS
M ext/phar/util.c
Diff:
diff --git a/NEWS b/NEWS
index 9054fd40bfd2..3b865718f09d 100644
--- a/NEWS
+++ b/NEWS
@@ -46,6 +46,10 @@ PHP NEWS
. Fixed a leak when a persistent connection failed a liveness check
with no other live PDO handle. (iliaal)
+- Phar:
+ . Fixed bug GH-23418 (Use-after-free when looking up mounted directories).
+ (Weilin Du)
+
- Readline:
. Fixed the interactive shell not waiting for the pager process to exit.
(Weilin Du)
diff --git a/ext/phar/tests/gh23418.phpt b/ext/phar/tests/gh23418.phpt
new file mode 100644
index 000000000000..d7ebebcb9ecb
--- /dev/null
+++ b/ext/phar/tests/gh23418.phpt
@@ -0,0 +1,32 @@
+--TEST--
+GH-23418: Access a subdirectory of a mounted directory with a trailing slash
+--EXTENSIONS--
+phar
+--INI--
+phar.readonly=0
+--FILE--
+<?php
+$phar = __DIR__ . '/gh23418.phar';
+$mount = __DIR__ . '/gh23418';
+
+@mkdir($mount . '/s2', 0777, true);
+
+$p = new Phar($phar);
+$p->addFromString('x.txt', 'x');
+$p->setStub('<?php __HALT_COMPILER(); ?>');
+unset($p);
+
+$p = new Phar($phar);
+Phar::mount('phar://' . $phar . '/m', $mount);
+$info = $p['m/s2/'];
+
+echo get_class($info), ', isDir=', $info->isDir() ? 'true' : 'false', PHP_EOL;
+?>
+--CLEAN--
+<?php
+@unlink(__DIR__ . '/gh23418.phar');
+@rmdir(__DIR__ . '/gh23418/s2');
+@rmdir(__DIR__ . '/gh23418');
+?>
+--EXPECT--
+PharFileInfo, isDir=true
diff --git a/ext/phar/util.c b/ext/phar/util.c
index 7e245fe7585d..58f23a51994b 100644
--- a/ext/phar/util.c
+++ b/ext/phar/util.c
@@ -1362,7 +1362,7 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, si
if (ZSTR_LEN(str_key) >= path_len || strncmp(ZSTR_VAL(str_key), path, ZSTR_LEN(str_key))) {
continue;
} else {
- char *test;
+ char *test, *mount_path;
size_t test_len;
php_stream_statbuf ssb;
@@ -1405,22 +1405,25 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, si
}
/* mount the file just in time */
- if (SUCCESS != phar_mount_entry(phar, test, test_len, path, path_len)) {
- efree(test);
+ mount_path = estrndup(path, path_len);
+ if (SUCCESS != phar_mount_entry(phar, test, test_len, mount_path, path_len)) {
if (error) {
spprintf(error, 4096, "phar error: path \"%s\" exists as file \"%s\" and could not be mounted", path, test);
}
+ efree(mount_path);
+ efree(test);
return NULL;
}
-
- efree(test);
+ efree(mount_path);
if (NULL == (entry = zend_hash_str_find_ptr(&phar->manifest, path, path_len))) {
if (error) {
spprintf(error, 4096, "phar error: path \"%s\" exists as file \"%s\" and could not be retrieved after being mounted", path, test);
}
+ efree(test);
return NULL;
}
+ efree(test);
return entry;
}
} ZEND_HASH_FOREACH_END();