diff options
author | Phillip Lougher <phillip@lougher.demon.co.uk> | 2009-03-05 00:31:12 +0000 |
---|---|---|
committer | Phillip Lougher <phillip@lougher.demon.co.uk> | 2009-03-05 00:31:12 +0000 |
commit | 118e1ef6fabfc023126e6075f6ac0fc729cb5285 (patch) | |
tree | 3c497ad9fcc5a459de9d75a688bb78c5220e8dd5 /fs/squashfs/block.c | |
parent | 2450cf51a1bdba7037e91b1bcc494b01c58aaf66 (diff) |
Squashfs: Fix oops when reading fsfuzzer corrupted filesystems
This fixes a code regression caused by the recent mainlining changes.
The recent code changes call zlib_inflate repeatedly, decompressing into
separate 4K buffers, this code didn't check for the possibility that
zlib_inflate might ask for too many buffers when decompressing corrupted
data.
Signed-off-by: Phillip Lougher <phillip@lougher.demon.co.uk>
Diffstat (limited to 'fs/squashfs/block.c')
-rw-r--r-- | fs/squashfs/block.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/fs/squashfs/block.c b/fs/squashfs/block.c index c837dfc2b3c..321728f48f2 100644 --- a/fs/squashfs/block.c +++ b/fs/squashfs/block.c @@ -80,7 +80,7 @@ static struct buffer_head *get_block_length(struct super_block *sb, * generated a larger block - this does occasionally happen with zlib). */ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index, - int length, u64 *next_index, int srclength) + int length, u64 *next_index, int srclength, int pages) { struct squashfs_sb_info *msblk = sb->s_fs_info; struct buffer_head **bh; @@ -185,6 +185,14 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index, } if (msblk->stream.avail_out == 0) { + if (page == pages) { + ERROR("zlib_inflate tried to " + "decompress too much data, " + "expected %d bytes. Zlib " + "data probably corrupt\n", + srclength); + goto release_mutex; + } msblk->stream.next_out = buffer[page++]; msblk->stream.avail_out = PAGE_CACHE_SIZE; } @@ -268,7 +276,8 @@ block_release: put_bh(bh[k]); read_failure: - ERROR("sb_bread failed reading block 0x%llx\n", cur_index); + ERROR("squashfs_read_data failed to read block 0x%llx\n", + (unsigned long long) index); kfree(bh); return -EIO; } |