diff --git a/ext/phar/stream.c b/ext/phar/stream.c index 19ba48f87500..660b9399e4fd 100644 --- a/ext/phar/stream.c +++ b/ext/phar/stream.c @@ -846,6 +846,11 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\" from extracted phar archive, source has been deleted", url_from, url_to); return 0; } + if (zend_string_equals(resource_from->path, resource_to->path)) { + php_url_free(resource_from); + php_url_free(resource_to); + return 1; + } /* transfer all data over to the new entry */ memcpy((void *) &new, (void *) entry, sizeof(phar_entry_info)); /* mark the old one for deletion */ diff --git a/ext/phar/tests/gh25091.phpt b/ext/phar/tests/gh25091.phpt new file mode 100644 index 000000000000..3df6c7940eba --- /dev/null +++ b/ext/phar/tests/gh25091.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-25091: Use-after-free in rename() when source and destination are the same entry +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +--FILE-- + +--CLEAN-- + +--EXPECT-- +bool(true) +string(8) "contents"