Skip to content

Fix extra-field cloning ownership leak - #562

Closed
carrerasdarren-cell wants to merge 1 commit into
nih-at:mainfrom
carrerasdarren-cell:agent/fix-extra-field-clone-leak
Closed

Fix extra-field cloning ownership leak#562
carrerasdarren-cell wants to merge 1 commit into
nih-at:mainfrom
carrerasdarren-cell:agent/fix-extra-field-clone-leak

Conversation

@carrerasdarren-cell

Copy link
Copy Markdown
Contributor

Summary

  • keep unchanged extra-field lists shared by generic directory-entry clones
  • deep-clone both lists only when the extra-field API prepares an entry for mutation
  • restore the copy-on-write ownership expected by directory-entry cleanup

Impact

Commit cbad2ba made _zip_dirent_clone() deep-copy every extra field, but
_zip_dirent_finalize() deliberately frees extra fields only when
ZIP_DIRENT_EXTRA_FIELD is marked changed. As a result, ordinary operations
such as renaming an entry leak the copied, archive-controlled extra fields when
the archive is discarded.

In a long-lived archive normalization or repackaging service, repeated hostile
archives can therefore grow process memory until exhaustion. The input does not
need to be malformed.

A local harness used a 1.0 MiB ZIP with 16 maximum-sized central extra fields,
then opened, renamed, and discarded all entries 100 times:

  • current main: 107.8 MiB peak footprint
  • no-extra-field control: 1.2 MiB peak footprint
  • this patch: 3.8 MiB peak footprint

Apple's leaks tool also traced the leaked allocations directly through
_zip_dirent_clone() and _zip_extra_fields_clone().

Validation

  • full ASan/UBSan regression suite: 189/189 passed
  • 100-cycle focused harness: clean under ASan/UBSan after the fix
  • git diff --check: clean

Keep unchanged extra fields shared by generic dirent clones, and deep-clone them only when the extra-field API prepares an entry for mutation. This prevents attacker-sized metadata from leaking when callers rename or otherwise edit archive entries.

Assisted-by: OpenAI Codex
dillof added a commit that referenced this pull request Aug 19, 2026
@dillof

dillof commented Aug 19, 2026

Copy link
Copy Markdown
Member

Good catch, thanks.

However, your fix was slightly wrong: The extra fields need to be cloned when they are first changed, even if the direntry was already cloned earlier. We've applied the correct fix.

@dillof dillof closed this Aug 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants