Skip to content

minizip: fix heap-buffer-overflow in zipRemoveExtraInfoBlock - #1280

Open
nakata-app wants to merge 1 commit into
madler:developfrom
nakata-app:fix/ziRemoveExtraInfoBlock-oob-write
Open

minizip: fix heap-buffer-overflow in zipRemoveExtraInfoBlock#1280
nakata-app wants to merge 1 commit into
madler:developfrom
nakata-app:fix/ziRemoveExtraInfoBlock-oob-write

Conversation

@nakata-app

Copy link
Copy Markdown

Fixes #1276.

zipRemoveExtraInfoBlock() in contrib/minizip/zip.c read a 2-byte
block-size field directly from the input buffer and used it unchecked
as both a memcpy length and a pointer-advance amount, with no
validation against the buffer's actual remaining size (*dataLen).
An attacker-controlled extra-field blob can drive the read cursor and
the memcpy length past the end of the buffer.

This adds a bounds check before each block header is consumed:

  • bail out with ZIP_PARAMERROR if fewer than 4 bytes remain in the
    buffer for the header + size field
  • bail out with ZIP_PARAMERROR if the declared block size
    (dataSize + 4) exceeds what is actually left in the buffer

Testing

Reproducer from #1276, built with ASan/UBSan:

==ERROR: AddressSanitizer: heap-buffer-overflow
WRITE of size 32771 at ... in a 4-byte allocation
    #1 zipRemoveExtraInfoBlock zip.c:1980
  • Before the fix: aborts under ASan as shown above.
  • After the fix: reproducer runs clean, returns ZIP_PARAMERROR.
  • Regression check: a buffer with two well-formed 4-byte blocks
    (one matching the removal header, one not) still round-trips
    correctly — the surviving block is copied through unmodified and
    the new length is reported correctly. Normal block-removal
    behavior is unchanged.

zipRemoveExtraInfoBlock() read a 2-byte block-size field from the
input buffer and used it unchecked as a memcpy length and pointer
advance, with no validation against the buffer's remaining size.
An attacker-controlled extra-field blob can therefore drive both the
read cursor and the memcpy length past the end of the buffer.

Add a bounds check before consuming each block header: bail out with
ZIP_PARAMERROR if fewer than 4 bytes remain, or if the declared block
size (dataSize + 4) exceeds what is left in the buffer.

Verified with the reproducer from the report (ASan
heap/stack-buffer-overflow before the fix, clean run after) and a
regression case with two well-formed blocks confirming normal
block-removal behavior is unchanged.

Fixes madler#1276
@Neustradamus

Copy link
Copy Markdown

@gvollant: ^

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.

Unchecked block size in zipRemoveExtraInfoBlock (contrib/minizip/zip.c) causes heap-buffer-overflow write

2 participants