diff --git a/ChangeLog b/ChangeLog index 17d0e243e..8dfaf47d4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-12-18 Vladimir Serbinenko + + Make grub_zlib_decompress handle incomplete chunks. + + Fixes squash4. + 2013-12-18 Vladimir Serbinenko * grub-core/Makefile.am: Don't attempt to export grub_bios_interrupt diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index b15a9d65d..89666b6fd 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -1104,7 +1104,12 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, - (grub_uint8_t *) data->extent), extoff, buf, csize) != (grub_ssize_t) csize) - return -1; + { + if (!grub_errno) + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, + "premature end of compressed"); + return -1; + } } else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_LZO) { @@ -1158,7 +1163,12 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, grub_free (tmp); if (ret != (grub_ssize_t) csize) - return -1; + { + if (!grub_errno) + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, + "premature end of compressed"); + return -1; + } break; } diff --git a/grub-core/fs/hfspluscomp.c b/grub-core/fs/hfspluscomp.c index 461b4678f..d76f3f137 100644 --- a/grub-core/fs/hfspluscomp.c +++ b/grub-core/fs/hfspluscomp.c @@ -156,8 +156,12 @@ hfsplus_read_compressed_real (struct grub_hfsplus_file *node, if (ts > node->size - (pos & ~(HFSPLUS_COMPRESS_BLOCK_SIZE))) ts = node->size - (pos & ~(HFSPLUS_COMPRESS_BLOCK_SIZE)); if (grub_zlib_decompress (tmp_buf, sz, 0, - node->cbuf, ts) < 0) + node->cbuf, ts) != (grub_ssize_t) ts) { + if (!grub_errno) + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, + "premature end of compressed"); + grub_free (tmp_buf); return -1; } @@ -288,8 +292,14 @@ hfsplus_open_compressed_real (struct grub_hfsplus_file *node) if (grub_zlib_decompress ((char *) (cmp_head + 1), grub_cpu_to_be64 (attr_head->size) - sizeof (*cmp_head), 0, - node->cbuf, node->size) < 0) - return grub_errno; + node->cbuf, node->size) + != (grub_ssize_t) node->size) + { + if (!grub_errno) + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, + "premature end of compressed"); + return grub_errno; + } node->compressed = 1; return 0; } diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 4d0bde4ce..cfb25c030 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -293,9 +293,13 @@ static grub_err_t zlib_decompress (void *s, void *d, grub_size_t slen, grub_size_t dlen) { - if (grub_zlib_decompress (s, slen, 0, d, dlen) < 0) - return grub_errno; - return GRUB_ERR_NONE; + if (grub_zlib_decompress (s, slen, 0, d, dlen) == (grub_ssize_t) dlen) + return GRUB_ERR_NONE; + + if (!grub_errno) + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, + "premature end of compressed"); + return grub_errno; } static grub_err_t diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c index aec798f59..129209e37 100644 --- a/grub-core/io/gzio.c +++ b/grub-core/io/gzio.c @@ -1303,12 +1303,6 @@ grub_zlib_decompress (char *inbuf, grub_size_t insize, grub_off_t off, ret = grub_gzio_read_real (gzio, off, outbuf, outsize); grub_free (gzio); - if (!grub_errno && ret != (grub_ssize_t) outsize) - { - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "premature end of compressed"); - ret = -1; - } - /* FIXME: Check Adler. */ return ret; }