Skip to content

ext/zip: ZipArchive::close() use-after-free from a progress or cancel… - #23749

Closed
devnexen wants to merge 1 commit into
php:PHP-8.4from
devnexen:gh23747
Closed

devnexen wants to merge 1 commit into
php:PHP-8.4from
devnexen:gh23747

Conversation

@devnexen

Copy link
Copy Markdown
Member

… callback.

Fix #23747

ZipArchive::close() called from a progress or cancel callback ran a nested zip_close() that failed, then zip_discard() freed the archive while the outer zip_close() from close() or open() was still using it. Track the close in progress and throw an Error from close() and open() meanwhile.

… callback.

Fix php#23747

ZipArchive::close() called from a progress or cancel callback ran a
nested zip_close() that failed, then zip_discard() freed the archive
while the outer zip_close() from close() or open() was still using it.
Track the close in progress and throw an Error from close() and open()
meanwhile.
@devnexen
devnexen marked this pull request as ready for review September 18, 2026 04:30
@iliaal iliaal linked an issue Sep 18, 2026 that may be closed by this pull request
@devnexen devnexen closed this in 132403d Sep 18, 2026
damek24 pushed a commit to damek24/php-src that referenced this pull request Oct 8, 2026
A progress or cancel callback runs inside zip_close() after libzip has
fixed the list of entries it writes. Deleting or unchanging an entry from
the callback frees a dirent that zip_close() still uses. Other changes are
either silently dropped or make close() fail and lose the archive.

Reject archive mutations with the same "Already being closed" Error that
close() and open() already raise, using php_zipobj_closing(). This follows
phpGH-23749 and complements the destructor protection in phpGH-23779.

Cover progress callbacks, cancel callbacks, and the implicit close() in
open(), and verify that the archive contents are preserved.

Closes php#24025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ZipArchive::close() from inside a progress/cancel callback causes segv

2 participants