From aff3e4b91d256c22bad404f327fac5a5814142ea Mon Sep 17 00:00:00 2001 From: lazerg Date: Sat, 31 Oct 2026 22:23:51 +0500 Subject: [PATCH 1/2] Fix GH-25092: Double free in Phar::copy() on link and mounted entries --- ext/phar/phar_object.c | 8 +++++ ext/phar/tests/gh25092.phpt | 62 +++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 ext/phar/tests/gh25092.phpt diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index e2f36f1c7b24..3ca92c7bf342 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -3560,6 +3560,14 @@ PHP_METHOD(Phar, copy) newentry.filename_len = tmp_len; newentry.fp_refcount = 0; + if (newentry.link) { + newentry.link = estrdup(newentry.link); + } + + if (newentry.tmp) { + newentry.tmp = estrdup(newentry.tmp); + } + if (oldentry->fp_type != PHAR_FP) { if (FAILURE == phar_copy_entry_fp(oldentry, &newentry, &error)) { efree(newentry.filename); diff --git a/ext/phar/tests/gh25092.phpt b/ext/phar/tests/gh25092.phpt new file mode 100644 index 000000000000..604094d76362 --- /dev/null +++ b/ext/phar/tests/gh25092.phpt @@ -0,0 +1,62 @@ +--TEST-- +GH-25092 (Double free in Phar::copy() on link and mounted entries) +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +--FILE-- +copy('l', 'l2'); +unset($t); + +$t = new PharData($tar); +var_dump(isset($t['l']), isset($t['l2'])); +unset($t); + +$phar = __DIR__ . '/gh25092.phar'; +file_put_contents(__DIR__ . '/gh25092.txt', 'hello'); + +$p = new Phar($phar); +$p->addFromString('x.txt', 'x'); +$p->setStub(''); +unset($p); + +$p = new Phar($phar); +Phar::mount('phar://' . $phar . '/m.txt', __DIR__ . '/gh25092.txt'); +$p->copy('m.txt', 'c.txt'); +var_dump(isset($p['c.txt'])); +?> +--CLEAN-- + +--EXPECT-- +bool(true) +bool(true) +bool(true) From 1e44fc017d47f61190cc6bc05a98064ddc6f22f7 Mon Sep 17 00:00:00 2001 From: lazerg Date: Sun, 1 Nov 2026 06:28:42 +0500 Subject: [PATCH 2/2] Free duplicated link and tmp when phar_copy_entry_fp() fails --- ext/phar/phar_object.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 3ca92c7bf342..8b467a9abc8f 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -3571,6 +3571,12 @@ PHP_METHOD(Phar, copy) if (oldentry->fp_type != PHAR_FP) { if (FAILURE == phar_copy_entry_fp(oldentry, &newentry, &error)) { efree(newentry.filename); + if (newentry.link) { + efree(newentry.link); + } + if (newentry.tmp) { + efree(newentry.tmp); + } php_stream_close(newentry.fp); zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error); efree(error);