diff options
| -rw-r--r-- | MAINTAINERS | 2 | ||||
| -rw-r--r-- | fs/squashfs/block.c | 2 | ||||
| -rw-r--r-- | fs/squashfs/cache.c | 31 | ||||
| -rw-r--r-- | fs/squashfs/decompressor.c | 2 | ||||
| -rw-r--r-- | fs/squashfs/decompressor.h | 2 | ||||
| -rw-r--r-- | fs/squashfs/dir.c | 2 | ||||
| -rw-r--r-- | fs/squashfs/export.c | 42 | ||||
| -rw-r--r-- | fs/squashfs/file.c | 2 | ||||
| -rw-r--r-- | fs/squashfs/fragment.c | 37 | ||||
| -rw-r--r-- | fs/squashfs/id.c | 42 | ||||
| -rw-r--r-- | fs/squashfs/inode.c | 2 | ||||
| -rw-r--r-- | fs/squashfs/namei.c | 2 | ||||
| -rw-r--r-- | fs/squashfs/squashfs.h | 10 | ||||
| -rw-r--r-- | fs/squashfs/squashfs_fs.h | 2 | ||||
| -rw-r--r-- | fs/squashfs/squashfs_fs_i.h | 2 | ||||
| -rw-r--r-- | fs/squashfs/squashfs_fs_sb.h | 2 | ||||
| -rw-r--r-- | fs/squashfs/super.c | 112 | ||||
| -rw-r--r-- | fs/squashfs/symlink.c | 2 | ||||
| -rw-r--r-- | fs/squashfs/xattr.c | 2 | ||||
| -rw-r--r-- | fs/squashfs/xattr.h | 3 | ||||
| -rw-r--r-- | fs/squashfs/xattr_id.c | 47 | ||||
| -rw-r--r-- | fs/squashfs/xz_wrapper.c | 2 | ||||
| -rw-r--r-- | fs/squashfs/zlib_wrapper.c | 2 | 
23 files changed, 203 insertions, 151 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index d1a1465bec0..c4fc1daddcb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6001,7 +6001,7 @@ F:	Documentation/filesystems/spufs.txt  F:	arch/powerpc/platforms/cell/spufs/  SQUASHFS FILE SYSTEM -M:	Phillip Lougher <phillip@lougher.demon.co.uk> +M:	Phillip Lougher <phillip@squashfs.org.uk>  L:	squashfs-devel@lists.sourceforge.net (subscribers-only)  W:	http://squashfs.org.uk  S:	Maintained diff --git a/fs/squashfs/block.c b/fs/squashfs/block.c index 8ab48bc2fa7..ed0eb2a921f 100644 --- a/fs/squashfs/block.c +++ b/fs/squashfs/block.c @@ -2,7 +2,7 @@   * Squashfs - a compressed read only filesystem for Linux   *   * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 - * Phillip Lougher <phillip@lougher.demon.co.uk> + * Phillip Lougher <phillip@squashfs.org.uk>   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License diff --git a/fs/squashfs/cache.c b/fs/squashfs/cache.c index 4b5a3fbb1f1..f744be98cd5 100644 --- a/fs/squashfs/cache.c +++ b/fs/squashfs/cache.c @@ -2,7 +2,7 @@   * Squashfs - a compressed read only filesystem for Linux   *   * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 - * Phillip Lougher <phillip@lougher.demon.co.uk> + * Phillip Lougher <phillip@squashfs.org.uk>   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License @@ -393,19 +393,36 @@ struct squashfs_cache_entry *squashfs_get_datablock(struct super_block *sb,  /*   * Read a filesystem table (uncompressed sequence of bytes) from disk   */ -int squashfs_read_table(struct super_block *sb, void *buffer, u64 block, -	int length) +void *squashfs_read_table(struct super_block *sb, u64 block, int length)  {  	int pages = (length + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;  	int i, res; -	void **data = kcalloc(pages, sizeof(void *), GFP_KERNEL); -	if (data == NULL) -		return -ENOMEM; +	void *table, *buffer, **data; + +	table = buffer = kmalloc(length, GFP_KERNEL); +	if (table == NULL) +		return ERR_PTR(-ENOMEM); + +	data = kcalloc(pages, sizeof(void *), GFP_KERNEL); +	if (data == NULL) { +		res = -ENOMEM; +		goto failed; +	}  	for (i = 0; i < pages; i++, buffer += PAGE_CACHE_SIZE)  		data[i] = buffer; +  	res = squashfs_read_data(sb, data, block, length |  		SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length, pages); +  	kfree(data); -	return res; + +	if (res < 0) +		goto failed; + +	return table; + +failed: +	kfree(table); +	return ERR_PTR(res);  } diff --git a/fs/squashfs/decompressor.c b/fs/squashfs/decompressor.c index e921bd21373..9f1b0bb96f1 100644 --- a/fs/squashfs/decompressor.c +++ b/fs/squashfs/decompressor.c @@ -2,7 +2,7 @@   * Squashfs - a compressed read only filesystem for Linux   *   * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 - * Phillip Lougher <phillip@lougher.demon.co.uk> + * Phillip Lougher <phillip@squashfs.org.uk>   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License diff --git a/fs/squashfs/decompressor.h b/fs/squashfs/decompressor.h index 099745ad569..8ba70cff09a 100644 --- a/fs/squashfs/decompressor.h +++ b/fs/squashfs/decompressor.h @@ -4,7 +4,7 @@   * Squashfs - a compressed read only filesystem for Linux   *   * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 - * Phillip Lougher <phillip@lougher.demon.co.uk> + * Phillip Lougher <phillip@squashfs.org.uk>   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License diff --git a/fs/squashfs/dir.c b/fs/squashfs/dir.c index 3f79cd1d0c1..9dfe2ce0fb7 100644 --- a/fs/squashfs/dir.c +++ b/fs/squashfs/dir.c @@ -2,7 +2,7 @@   * Squashfs - a compressed read only filesystem for Linux   *   * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 - * Phillip Lougher <phillip@lougher.demon.co.uk> + * Phillip Lougher <phillip@squashfs.org.uk>   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License diff --git a/fs/squashfs/export.c b/fs/squashfs/export.c index 7f93d5a9ee0..730c56248c9 100644 --- a/fs/squashfs/export.c +++ b/fs/squashfs/export.c @@ -2,7 +2,7 @@   * Squashfs - a compressed read only filesystem for Linux   *   * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 - * Phillip Lougher <phillip@lougher.demon.co.uk> + * Phillip Lougher <phillip@squashfs.org.uk>   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License @@ -121,30 +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 *inode_lookup_table; -	int err; +	__le64 *table;  	TRACE("In read_inode_lookup_table, length %d\n", length); -	/* Allocate inode lookup table indexes */ -	inode_lookup_table = kmalloc(length, GFP_KERNEL); -	if (inode_lookup_table == NULL) { -		ERROR("Failed to allocate inode lookup table\n"); -		return ERR_PTR(-ENOMEM); -	} +	/* 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); -	err = squashfs_read_table(sb, inode_lookup_table, lookup_table_start, -			length); -	if (err < 0) { -		ERROR("unable to read inode lookup table\n"); -		kfree(inode_lookup_table); -		return ERR_PTR(err); +	/* +	 * 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 inode_lookup_table; +	return table;  } diff --git a/fs/squashfs/file.c b/fs/squashfs/file.c index a25c5060bdc..38bb1c64055 100644 --- a/fs/squashfs/file.c +++ b/fs/squashfs/file.c @@ -2,7 +2,7 @@   * Squashfs - a compressed read only filesystem for Linux   *   * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 - * Phillip Lougher <phillip@lougher.demon.co.uk> + * Phillip Lougher <phillip@squashfs.org.uk>   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License diff --git a/fs/squashfs/fragment.c b/fs/squashfs/fragment.c index 7eef571443c..1516a6490bf 100644 --- a/fs/squashfs/fragment.c +++ b/fs/squashfs/fragment.c @@ -2,7 +2,7 @@   * Squashfs - a compressed read only filesystem for Linux   *   * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 - * Phillip Lougher <phillip@lougher.demon.co.uk> + * Phillip Lougher <phillip@squashfs.org.uk>   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License @@ -71,26 +71,29 @@ int squashfs_frag_lookup(struct super_block *sb, unsigned int fragment,   * Read the uncompressed fragment lookup table indexes off disk into memory   */  __le64 *squashfs_read_fragment_index_table(struct super_block *sb, -	u64 fragment_table_start, unsigned int fragments) +	u64 fragment_table_start, u64 next_table, unsigned int fragments)  {  	unsigned int length = SQUASHFS_FRAGMENT_INDEX_BYTES(fragments); -	__le64 *fragment_index; -	int err; +	__le64 *table; -	/* Allocate fragment lookup table indexes */ -	fragment_index = kmalloc(length, GFP_KERNEL); -	if (fragment_index == NULL) { -		ERROR("Failed to allocate fragment index table\n"); -		return ERR_PTR(-ENOMEM); -	} +	/* +	 * Sanity check, length bytes should not extend into the next table - +	 * this check also traps instances where fragment_table_start is +	 * incorrectly larger than the next table start +	 */ +	if (fragment_table_start + length > next_table) +		return ERR_PTR(-EINVAL); + +	table = squashfs_read_table(sb, fragment_table_start, length); -	err = squashfs_read_table(sb, fragment_index, fragment_table_start, -			length); -	if (err < 0) { -		ERROR("unable to read fragment index table\n"); -		kfree(fragment_index); -		return ERR_PTR(err); +	/* +	 * table[0] points to the first fragment table metadata block, this +	 * should be less than fragment_table_start +	 */ +	if (!IS_ERR(table) && table[0] >= fragment_table_start) { +		kfree(table); +		return ERR_PTR(-EINVAL);  	} -	return fragment_index; +	return table;  } diff --git a/fs/squashfs/id.c b/fs/squashfs/id.c index d8f32452638..a70858e0fb4 100644 --- a/fs/squashfs/id.c +++ b/fs/squashfs/id.c @@ -2,7 +2,7 @@   * Squashfs - a compressed read only filesystem for Linux   *   * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 - * Phillip Lougher <phillip@lougher.demon.co.uk> + * Phillip Lougher <phillip@squashfs.org.uk>   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License @@ -66,27 +66,37 @@ int squashfs_get_id(struct super_block *sb, unsigned int index,   * Read uncompressed id lookup table indexes from disk into memory   */  __le64 *squashfs_read_id_index_table(struct super_block *sb, -			u64 id_table_start, unsigned short no_ids) +		u64 id_table_start, u64 next_table, unsigned short no_ids)  {  	unsigned int length = SQUASHFS_ID_BLOCK_BYTES(no_ids); -	__le64 *id_table; -	int err; +	__le64 *table;  	TRACE("In read_id_index_table, length %d\n", length); -	/* Allocate id lookup table indexes */ -	id_table = kmalloc(length, GFP_KERNEL); -	if (id_table == NULL) { -		ERROR("Failed to allocate id index table\n"); -		return ERR_PTR(-ENOMEM); -	} +	/* Sanity check values */ + +	/* there should always be at least one id */ +	if (no_ids == 0) +		return ERR_PTR(-EINVAL); + +	/* +	 * length bytes should not extend into the next table - this check +	 * also traps instances where id_table_start is incorrectly larger +	 * than the next table start +	 */ +	if (id_table_start + length > next_table) +		return ERR_PTR(-EINVAL); + +	table = squashfs_read_table(sb, id_table_start, length); -	err = squashfs_read_table(sb, id_table, id_table_start, length); -	if (err < 0) { -		ERROR("unable to read id index table\n"); -		kfree(id_table); -		return ERR_PTR(err); +	/* +	 * table[0] points to the first id lookup table metadata block, this +	 * should be less than id_table_start +	 */ +	if (!IS_ERR(table) && table[0] >= id_table_start) { +		kfree(table); +		return ERR_PTR(-EINVAL);  	} -	return id_table; +	return table;  } diff --git a/fs/squashfs/inode.c b/fs/squashfs/inode.c index 62e63ad2507..04bebcaa237 100644 --- a/fs/squashfs/inode.c +++ b/fs/squashfs/inode.c @@ -2,7 +2,7 @@   * Squashfs - a compressed read only filesystem for Linux   *   * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 - * Phillip Lougher <phillip@lougher.demon.co.uk> + * Phillip Lougher <phillip@squashfs.org.uk>   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License diff --git a/fs/squashfs/namei.c b/fs/squashfs/namei.c index 5d922a6701a..4bc63ac64bc 100644 --- a/fs/squashfs/namei.c +++ b/fs/squashfs/namei.c @@ -2,7 +2,7 @@   * Squashfs - a compressed read only filesystem for Linux   *   * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 - * Phillip Lougher <phillip@lougher.demon.co.uk> + * Phillip Lougher <phillip@squashfs.org.uk>   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License diff --git a/fs/squashfs/squashfs.h b/fs/squashfs/squashfs.h index 1f2e608b878..e3be6a71cfa 100644 --- a/fs/squashfs/squashfs.h +++ b/fs/squashfs/squashfs.h @@ -2,7 +2,7 @@   * Squashfs - a compressed read only filesystem for Linux   *   * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 - * Phillip Lougher <phillip@lougher.demon.co.uk> + * Phillip Lougher <phillip@squashfs.org.uk>   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License @@ -44,24 +44,24 @@ extern struct squashfs_cache_entry *squashfs_get_fragment(struct super_block *,  				u64, int);  extern struct squashfs_cache_entry *squashfs_get_datablock(struct super_block *,  				u64, int); -extern int squashfs_read_table(struct super_block *, void *, u64, int); +extern void *squashfs_read_table(struct super_block *, u64, int);  /* decompressor.c */  extern const struct squashfs_decompressor *squashfs_lookup_decompressor(int);  extern void *squashfs_decompressor_init(struct super_block *, unsigned short);  /* export.c */ -extern __le64 *squashfs_read_inode_lookup_table(struct super_block *, u64, +extern __le64 *squashfs_read_inode_lookup_table(struct super_block *, u64, u64,  				unsigned int);  /* fragment.c */  extern int squashfs_frag_lookup(struct super_block *, unsigned int, u64 *);  extern __le64 *squashfs_read_fragment_index_table(struct super_block *, -				u64, unsigned int); +				u64, u64, unsigned int);  /* id.c */  extern int squashfs_get_id(struct super_block *, unsigned int, unsigned int *); -extern __le64 *squashfs_read_id_index_table(struct super_block *, u64, +extern __le64 *squashfs_read_id_index_table(struct super_block *, u64, u64,  				unsigned short);  /* inode.c */ diff --git a/fs/squashfs/squashfs_fs.h b/fs/squashfs/squashfs_fs.h index 4582c568ef4..b4a4e539a08 100644 --- a/fs/squashfs/squashfs_fs.h +++ b/fs/squashfs/squashfs_fs.h @@ -4,7 +4,7 @@   * Squashfs   *   * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 - * Phillip Lougher <phillip@lougher.demon.co.uk> + * Phillip Lougher <phillip@squashfs.org.uk>   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License diff --git a/fs/squashfs/squashfs_fs_i.h b/fs/squashfs/squashfs_fs_i.h index 359baefc01f..73588e7700e 100644 --- a/fs/squashfs/squashfs_fs_i.h +++ b/fs/squashfs/squashfs_fs_i.h @@ -4,7 +4,7 @@   * Squashfs   *   * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 - * Phillip Lougher <phillip@lougher.demon.co.uk> + * Phillip Lougher <phillip@squashfs.org.uk>   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License diff --git a/fs/squashfs/squashfs_fs_sb.h b/fs/squashfs/squashfs_fs_sb.h index d9037a5215f..651f0b31d29 100644 --- a/fs/squashfs/squashfs_fs_sb.h +++ b/fs/squashfs/squashfs_fs_sb.h @@ -4,7 +4,7 @@   * Squashfs   *   * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 - * Phillip Lougher <phillip@lougher.demon.co.uk> + * Phillip Lougher <phillip@squashfs.org.uk>   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c index 5c8184c061a..6f26abee359 100644 --- a/fs/squashfs/super.c +++ b/fs/squashfs/super.c @@ -2,7 +2,7 @@   * Squashfs - a compressed read only filesystem for Linux   *   * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 - * Phillip Lougher <phillip@lougher.demon.co.uk> + * Phillip Lougher <phillip@squashfs.org.uk>   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License @@ -83,7 +83,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)  	long long root_inode;  	unsigned short flags;  	unsigned int fragments; -	u64 lookup_table_start, xattr_id_table_start; +	u64 lookup_table_start, xattr_id_table_start, next_table;  	int err;  	TRACE("Entered squashfs_fill_superblock\n"); @@ -95,12 +95,6 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)  	}  	msblk = sb->s_fs_info; -	sblk = kzalloc(sizeof(*sblk), GFP_KERNEL); -	if (sblk == NULL) { -		ERROR("Failed to allocate squashfs_super_block\n"); -		goto failure; -	} -  	msblk->devblksize = sb_min_blocksize(sb, BLOCK_SIZE);  	msblk->devblksize_log2 = ffz(~msblk->devblksize); @@ -114,10 +108,12 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)  	 * of bytes_used) we need to set it to an initial sensible dummy value  	 */  	msblk->bytes_used = sizeof(*sblk); -	err = squashfs_read_table(sb, sblk, SQUASHFS_START, sizeof(*sblk)); +	sblk = squashfs_read_table(sb, SQUASHFS_START, sizeof(*sblk)); -	if (err < 0) { +	if (IS_ERR(sblk)) {  		ERROR("unable to read squashfs_super_block\n"); +		err = PTR_ERR(sblk); +		sblk = NULL;  		goto failed_mount;  	} @@ -218,18 +214,61 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)  		goto failed_mount;  	} +	/* Handle xattrs */ +	sb->s_xattr = squashfs_xattr_handlers; +	xattr_id_table_start = le64_to_cpu(sblk->xattr_id_table_start); +	if (xattr_id_table_start == SQUASHFS_INVALID_BLK) { +		next_table = msblk->bytes_used; +		goto allocate_id_index_table; +	} + +	/* Allocate and read xattr id lookup table */ +	msblk->xattr_id_table = squashfs_read_xattr_id_table(sb, +		xattr_id_table_start, &msblk->xattr_table, &msblk->xattr_ids); +	if (IS_ERR(msblk->xattr_id_table)) { +		ERROR("unable to read xattr id index table\n"); +		err = PTR_ERR(msblk->xattr_id_table); +		msblk->xattr_id_table = NULL; +		if (err != -ENOTSUPP) +			goto failed_mount; +	} +	next_table = msblk->xattr_table; + +allocate_id_index_table:  	/* Allocate and read id index table */  	msblk->id_table = squashfs_read_id_index_table(sb, -		le64_to_cpu(sblk->id_table_start), le16_to_cpu(sblk->no_ids)); +		le64_to_cpu(sblk->id_table_start), next_table, +		le16_to_cpu(sblk->no_ids));  	if (IS_ERR(msblk->id_table)) { +		ERROR("unable to read id index table\n");  		err = PTR_ERR(msblk->id_table);  		msblk->id_table = NULL;  		goto failed_mount;  	} +	next_table = msblk->id_table[0]; + +	/* Handle inode lookup table */ +	lookup_table_start = le64_to_cpu(sblk->lookup_table_start); +	if (lookup_table_start == SQUASHFS_INVALID_BLK) +		goto handle_fragments; + +	/* Allocate and read inode lookup table */ +	msblk->inode_lookup_table = squashfs_read_inode_lookup_table(sb, +		lookup_table_start, next_table, msblk->inodes); +	if (IS_ERR(msblk->inode_lookup_table)) { +		ERROR("unable to read inode lookup table\n"); +		err = PTR_ERR(msblk->inode_lookup_table); +		msblk->inode_lookup_table = NULL; +		goto failed_mount; +	} +	next_table = msblk->inode_lookup_table[0]; +	sb->s_export_op = &squashfs_export_ops; + +handle_fragments:  	fragments = le32_to_cpu(sblk->fragments);  	if (fragments == 0) -		goto allocate_lookup_table; +		goto check_directory_table;  	msblk->fragment_cache = squashfs_cache_init("fragment",  		SQUASHFS_CACHED_FRAGMENTS, msblk->block_size); @@ -240,45 +279,29 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)  	/* Allocate and read fragment index table */  	msblk->fragment_index = squashfs_read_fragment_index_table(sb, -		le64_to_cpu(sblk->fragment_table_start), fragments); +		le64_to_cpu(sblk->fragment_table_start), next_table, fragments);  	if (IS_ERR(msblk->fragment_index)) { +		ERROR("unable to read fragment index table\n");  		err = PTR_ERR(msblk->fragment_index);  		msblk->fragment_index = NULL;  		goto failed_mount;  	} +	next_table = msblk->fragment_index[0]; -allocate_lookup_table: -	lookup_table_start = le64_to_cpu(sblk->lookup_table_start); -	if (lookup_table_start == SQUASHFS_INVALID_BLK) -		goto allocate_xattr_table; - -	/* Allocate and read inode lookup table */ -	msblk->inode_lookup_table = squashfs_read_inode_lookup_table(sb, -		lookup_table_start, msblk->inodes); -	if (IS_ERR(msblk->inode_lookup_table)) { -		err = PTR_ERR(msblk->inode_lookup_table); -		msblk->inode_lookup_table = NULL; +check_directory_table: +	/* Sanity check directory_table */ +	if (msblk->directory_table >= next_table) { +		err = -EINVAL;  		goto failed_mount;  	} -	sb->s_export_op = &squashfs_export_ops; - -allocate_xattr_table: -	sb->s_xattr = squashfs_xattr_handlers; -	xattr_id_table_start = le64_to_cpu(sblk->xattr_id_table_start); -	if (xattr_id_table_start == SQUASHFS_INVALID_BLK) -		goto allocate_root; - -	/* Allocate and read xattr id lookup table */ -	msblk->xattr_id_table = squashfs_read_xattr_id_table(sb, -		xattr_id_table_start, &msblk->xattr_table, &msblk->xattr_ids); -	if (IS_ERR(msblk->xattr_id_table)) { -		err = PTR_ERR(msblk->xattr_id_table); -		msblk->xattr_id_table = NULL; -		if (err != -ENOTSUPP) -			goto failed_mount; +	/* Sanity check inode_table */ +	if (msblk->inode_table >= msblk->directory_table) { +		err = -EINVAL; +		goto failed_mount;  	} -allocate_root: + +	/* allocate root */  	root = new_inode(sb);  	if (!root) {  		err = -ENOMEM; @@ -318,11 +341,6 @@ failed_mount:  	sb->s_fs_info = NULL;  	kfree(sblk);  	return err; - -failure: -	kfree(sb->s_fs_info); -	sb->s_fs_info = NULL; -	return -ENOMEM;  } @@ -475,5 +493,5 @@ static const struct super_operations squashfs_super_ops = {  module_init(init_squashfs_fs);  module_exit(exit_squashfs_fs);  MODULE_DESCRIPTION("squashfs 4.0, a compressed read-only filesystem"); -MODULE_AUTHOR("Phillip Lougher <phillip@lougher.demon.co.uk>"); +MODULE_AUTHOR("Phillip Lougher <phillip@squashfs.org.uk>");  MODULE_LICENSE("GPL"); diff --git a/fs/squashfs/symlink.c b/fs/squashfs/symlink.c index ec86434921e..1191817264c 100644 --- a/fs/squashfs/symlink.c +++ b/fs/squashfs/symlink.c @@ -2,7 +2,7 @@   * Squashfs - a compressed read only filesystem for Linux   *   * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 - * Phillip Lougher <phillip@lougher.demon.co.uk> + * Phillip Lougher <phillip@squashfs.org.uk>   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License diff --git a/fs/squashfs/xattr.c b/fs/squashfs/xattr.c index 3876c36699a..92fcde7b4d6 100644 --- a/fs/squashfs/xattr.c +++ b/fs/squashfs/xattr.c @@ -2,7 +2,7 @@   * Squashfs - a compressed read only filesystem for Linux   *   * Copyright (c) 2010 - * Phillip Lougher <phillip@lougher.demon.co.uk> + * Phillip Lougher <phillip@squashfs.org.uk>   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License diff --git a/fs/squashfs/xattr.h b/fs/squashfs/xattr.h index b634efce4bd..c83f5d9ec12 100644 --- a/fs/squashfs/xattr.h +++ b/fs/squashfs/xattr.h @@ -2,7 +2,7 @@   * Squashfs - a compressed read only filesystem for Linux   *   * Copyright (c) 2010 - * Phillip Lougher <phillip@lougher.demon.co.uk> + * Phillip Lougher <phillip@squashfs.org.uk>   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License @@ -31,6 +31,7 @@ static inline __le64 *squashfs_read_xattr_id_table(struct super_block *sb,  		u64 start, u64 *xattr_table_start, int *xattr_ids)  {  	ERROR("Xattrs in filesystem, these will be ignored\n"); +	*xattr_table_start = start;  	return ERR_PTR(-ENOTSUPP);  } diff --git a/fs/squashfs/xattr_id.c b/fs/squashfs/xattr_id.c index 05385dbe146..c89607d690c 100644 --- a/fs/squashfs/xattr_id.c +++ b/fs/squashfs/xattr_id.c @@ -2,7 +2,7 @@   * Squashfs - a compressed read only filesystem for Linux   *   * Copyright (c) 2010 - * Phillip Lougher <phillip@lougher.demon.co.uk> + * Phillip Lougher <phillip@squashfs.org.uk>   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License @@ -67,34 +67,29 @@ __le64 *squashfs_read_xattr_id_table(struct super_block *sb, u64 start,  		u64 *xattr_table_start, int *xattr_ids)  {  	unsigned int len; -	__le64 *xid_table; -	struct squashfs_xattr_id_table id_table; -	int err; +	struct squashfs_xattr_id_table *id_table; -	err = squashfs_read_table(sb, &id_table, start, sizeof(id_table)); -	if (err < 0) { -		ERROR("unable to read xattr id table\n"); -		return ERR_PTR(err); -	} -	*xattr_table_start = le64_to_cpu(id_table.xattr_table_start); -	*xattr_ids = le32_to_cpu(id_table.xattr_ids); -	len = SQUASHFS_XATTR_BLOCK_BYTES(*xattr_ids); +	id_table = squashfs_read_table(sb, start, sizeof(*id_table)); +	if (IS_ERR(id_table)) +		return (__le64 *) id_table; -	TRACE("In read_xattr_index_table, length %d\n", len); +	*xattr_table_start = le64_to_cpu(id_table->xattr_table_start); +	*xattr_ids = le32_to_cpu(id_table->xattr_ids); +	kfree(id_table); + +	/* Sanity check values */ -	/* Allocate xattr id lookup table indexes */ -	xid_table = kmalloc(len, GFP_KERNEL); -	if (xid_table == NULL) { -		ERROR("Failed to allocate xattr id index table\n"); -		return ERR_PTR(-ENOMEM); -	} +	/* there is always at least one xattr id */ +	if (*xattr_ids == 0) +		return ERR_PTR(-EINVAL); -	err = squashfs_read_table(sb, xid_table, start + sizeof(id_table), len); -	if (err < 0) { -		ERROR("unable to read xattr id index table\n"); -		kfree(xid_table); -		return ERR_PTR(err); -	} +	/* xattr_table should be less than start */ +	if (*xattr_table_start >= start) +		return ERR_PTR(-EINVAL); + +	len = SQUASHFS_XATTR_BLOCK_BYTES(*xattr_ids); + +	TRACE("In read_xattr_index_table, length %d\n", len); -	return xid_table; +	return squashfs_read_table(sb, start + sizeof(*id_table), len);  } diff --git a/fs/squashfs/xz_wrapper.c b/fs/squashfs/xz_wrapper.c index aa47a286d1f..1760b7d108f 100644 --- a/fs/squashfs/xz_wrapper.c +++ b/fs/squashfs/xz_wrapper.c @@ -2,7 +2,7 @@   * Squashfs - a compressed read only filesystem for Linux   *   * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 - * Phillip Lougher <phillip@lougher.demon.co.uk> + * Phillip Lougher <phillip@squashfs.org.uk>   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License diff --git a/fs/squashfs/zlib_wrapper.c b/fs/squashfs/zlib_wrapper.c index 517688b32ff..55d918fd2d8 100644 --- a/fs/squashfs/zlib_wrapper.c +++ b/fs/squashfs/zlib_wrapper.c @@ -2,7 +2,7 @@   * Squashfs - a compressed read only filesystem for Linux   *   * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 - * Phillip Lougher <phillip@lougher.demon.co.uk> + * Phillip Lougher <phillip@squashfs.org.uk>   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License  |