From ac51a0a7139aa93bf1176b701c86fa3d2bdf6106 Mon Sep 17 00:00:00 2001 From: Phillip Lougher Date: Tue, 24 May 2011 04:15:21 +0100 Subject: Squashfs: add sanity checks to lookup table reading at mount time Fsfuzzer generates corrupted filesystems which throw a warn_on in kmalloc. One of these is due to a corrupted superblock inodes field. Fix this by checking that the number of bytes to be read (and allocated) does not extend into the next filesystem structure. Also add a couple of other sanity checks of the mount-time lookup table structures. Signed-off-by: Phillip Lougher --- fs/squashfs/export.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) (limited to 'fs/squashfs/export.c') diff --git a/fs/squashfs/export.c b/fs/squashfs/export.c index cc6dd90cee6a..e3108711a40a 100644 --- a/fs/squashfs/export.c +++ b/fs/squashfs/export.c @@ -121,13 +121,38 @@ static struct dentry *squashfs_get_parent(struct dentry *child) * Read uncompressed inode lookup table indexes off disk into memory */ __le64 *squashfs_read_inode_lookup_table(struct super_block *sb, - u64 lookup_table_start, unsigned int inodes) + u64 lookup_table_start, u64 next_table, unsigned int inodes) { unsigned int length = SQUASHFS_LOOKUP_BLOCK_BYTES(inodes); + __le64 *table; TRACE("In read_inode_lookup_table, length %d\n", length); - return squashfs_read_table(sb, lookup_table_start, length); + /* Sanity check values */ + + /* there should always be at least one inode */ + if (inodes == 0) + return ERR_PTR(-EINVAL); + + /* length bytes should not extend into the next table - this check + * also traps instances where lookup_table_start is incorrectly larger + * than the next table start + */ + if (lookup_table_start + length > next_table) + return ERR_PTR(-EINVAL); + + table = squashfs_read_table(sb, lookup_table_start, length); + + /* + * table[0] points to the first inode lookup table metadata block, + * this should be less than lookup_table_start + */ + if (!IS_ERR(table) && table[0] >= lookup_table_start) { + kfree(table); + return ERR_PTR(-EINVAL); + } + + return table; } -- cgit v1.2.3