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 d8f32452638e..a70858e0fb44 100644 --- a/fs/squashfs/id.c +++ b/fs/squashfs/id.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Squashfs - a compressed read only filesystem for Linux | 2 | * Squashfs - a compressed read only filesystem for Linux |
3 | * | 3 | * |
4 | * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 | 4 | * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 |
5 | * Phillip Lougher <phillip@lougher.demon.co.uk> | 5 | * Phillip Lougher <phillip@squashfs.org.uk> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU General Public License | 8 | * 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, | |||
66 | * Read uncompressed id lookup table indexes from disk into memory | 66 | * Read uncompressed id lookup table indexes from disk into memory |
67 | */ | 67 | */ |
68 | __le64 *squashfs_read_id_index_table(struct super_block *sb, | 68 | __le64 *squashfs_read_id_index_table(struct super_block *sb, |
69 | u64 id_table_start, unsigned short no_ids) | 69 | u64 id_table_start, u64 next_table, unsigned short no_ids) |
70 | { | 70 | { |
71 | unsigned int length = SQUASHFS_ID_BLOCK_BYTES(no_ids); | 71 | unsigned int length = SQUASHFS_ID_BLOCK_BYTES(no_ids); |
72 | __le64 *id_table; | 72 | __le64 *table; |
73 | int err; | ||
74 | 73 | ||
75 | TRACE("In read_id_index_table, length %d\n", length); | 74 | TRACE("In read_id_index_table, length %d\n", length); |
76 | 75 | ||
77 | /* Allocate id lookup table indexes */ | 76 | /* Sanity check values */ |
78 | id_table = kmalloc(length, GFP_KERNEL); | 77 | |
79 | if (id_table == NULL) { | 78 | /* there should always be at least one id */ |
80 | ERROR("Failed to allocate id index table\n"); | 79 | if (no_ids == 0) |
81 | return ERR_PTR(-ENOMEM); | 80 | return ERR_PTR(-EINVAL); |
82 | } | 81 | |
82 | /* | ||
83 | * length bytes should not extend into the next table - this check | ||
84 | * also traps instances where id_table_start is incorrectly larger | ||
85 | * than the next table start | ||
86 | */ | ||
87 | if (id_table_start + length > next_table) | ||
88 | return ERR_PTR(-EINVAL); | ||
89 | |||
90 | table = squashfs_read_table(sb, id_table_start, length); | ||
83 | 91 | ||
84 | err = squashfs_read_table(sb, id_table, id_table_start, length); | 92 | /* |
85 | if (err < 0) { | 93 | * table[0] points to the first id lookup table metadata block, this |
86 | ERROR("unable to read id index table\n"); | 94 | * should be less than id_table_start |
87 | kfree(id_table); | 95 | */ |
88 | return ERR_PTR(err); | 96 | if (!IS_ERR(table) && table[0] >= id_table_start) { |
97 | kfree(table); | ||
98 | return ERR_PTR(-EINVAL); | ||
89 | } | 99 | } |
90 | 100 | ||
91 | return id_table; | 101 | return table; |
92 | } | 102 | } |