diff options
Diffstat (limited to 'fs/squashfs/id.c')
| -rw-r--r-- | fs/squashfs/id.c | 42 | 
1 files changed, 26 insertions, 16 deletions
| 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;  } | 
