Skip to content

Commit

Permalink
Issue 553: Fix broken decryption for ZIP files.
Browse files Browse the repository at this point in the history
Sometimes, decompressing was failing due to miscalculation of buffer
offsets, and hence causing a silent buffer overflow.

When a previous chunk decompression left some bytes in the decryption
buffer, it was not taken into account in determining space left in the
decompression buffer.

So, it could happen, that the decryption buffer is completely full,
but some bytes are not used yet. In such case, even though the buffer
is full, the code tried to decrypt more bytes behind it's boundary.

This CL resolves this issue by properly calculating the amount of
space left in the decompression buffer.

(This is an edited version of Tomasz Mikolajewski's pull request.)
  • Loading branch information
kientzle committed Jun 16, 2016
1 parent 26b6d6d commit d85976e
Showing 1 changed file with 11 additions and 2 deletions.
13 changes: 11 additions & 2 deletions libarchive/archive_read_support_format_zip.c
Expand Up @@ -181,6 +181,14 @@ struct zip {
char init_decryption;

/* Decryption buffer. */
/*
* The decrypted data starts at decrypted_ptr and
* extends for decrypted_bytes_remaining. Decryption
* adds new data to the end of this block, data is returned
* to clients from the beginning. When the block hits the
* end of decrypted_buffer, it has to be shuffled back to
* the beginning of the buffer.
*/
unsigned char *decrypted_buffer;
unsigned char *decrypted_ptr;
size_t decrypted_buffer_size;
Expand Down Expand Up @@ -1293,8 +1301,9 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,

if (zip->tctx_valid || zip->cctx_valid) {
if (zip->decrypted_bytes_remaining < (size_t)bytes_avail) {
size_t buff_remaining = zip->decrypted_buffer_size
- (zip->decrypted_ptr - zip->decrypted_buffer);
size_t buff_remaining =
(zip->decrypted_buffer + zip->decrypted_buffer_size)
- (zip->decrypted_ptr + zip->decrypted_bytes_remaining);

if (buff_remaining > (size_t)bytes_avail)
buff_remaining = (size_t)bytes_avail;
Expand Down

0 comments on commit d85976e

Please sign in to comment.