diff options
Diffstat (limited to 'fs/squashfs/id.c')
-rw-r--r-- | fs/squashfs/id.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/fs/squashfs/id.c b/fs/squashfs/id.c index 2fdac6703b48..499d08a1f34a 100644 --- a/fs/squashfs/id.c +++ b/fs/squashfs/id.c @@ -66,11 +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 *table; TRACE("In read_id_index_table, length %d\n", length); - return squashfs_read_table(sb, id_table_start, length); + /* 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); + + /* + * 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 table; } |