diff options
author | Phillip Lougher <phillip@lougher.demon.co.uk> | 2011-05-23 23:05:22 -0400 |
---|---|---|
committer | Phillip Lougher <phillip@lougher.demon.co.uk> | 2011-05-25 13:21:32 -0400 |
commit | 37986f63c81bf23c856f65fc5e4830550e7f3d5b (patch) | |
tree | aafcc2078b469fb8fdb6e43255e136fcc7059dc9 /fs/squashfs/super.c | |
parent | 6f04864515365e135adc9f1cee4ac1251bb0ed35 (diff) |
Squashfs: add sanity checks to id reading at mount time
Fsfuzzer generates corrupted filesystems which throw a warn_on in
kmalloc. One of these is due to a corrupted superblock no_ids 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 id table
structures.
Signed-off-by: Phillip Lougher <phillip@lougher.demon.co.uk>
Diffstat (limited to 'fs/squashfs/super.c')
-rw-r--r-- | fs/squashfs/super.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c index 401cc8c7608f..8f5f2781a60e 100644 --- a/fs/squashfs/super.c +++ b/fs/squashfs/super.c | |||
@@ -83,7 +83,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent) | |||
83 | long long root_inode; | 83 | long long root_inode; |
84 | unsigned short flags; | 84 | unsigned short flags; |
85 | unsigned int fragments; | 85 | unsigned int fragments; |
86 | u64 lookup_table_start, xattr_id_table_start; | 86 | u64 lookup_table_start, xattr_id_table_start, next_table; |
87 | int err; | 87 | int err; |
88 | 88 | ||
89 | TRACE("Entered squashfs_fill_superblock\n"); | 89 | TRACE("Entered squashfs_fill_superblock\n"); |
@@ -217,8 +217,10 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent) | |||
217 | /* Handle xattrs */ | 217 | /* Handle xattrs */ |
218 | sb->s_xattr = squashfs_xattr_handlers; | 218 | sb->s_xattr = squashfs_xattr_handlers; |
219 | xattr_id_table_start = le64_to_cpu(sblk->xattr_id_table_start); | 219 | xattr_id_table_start = le64_to_cpu(sblk->xattr_id_table_start); |
220 | if (xattr_id_table_start == SQUASHFS_INVALID_BLK) | 220 | if (xattr_id_table_start == SQUASHFS_INVALID_BLK) { |
221 | next_table = msblk->bytes_used; | ||
221 | goto allocate_id_index_table; | 222 | goto allocate_id_index_table; |
223 | } | ||
222 | 224 | ||
223 | /* Allocate and read xattr id lookup table */ | 225 | /* Allocate and read xattr id lookup table */ |
224 | msblk->xattr_id_table = squashfs_read_xattr_id_table(sb, | 226 | msblk->xattr_id_table = squashfs_read_xattr_id_table(sb, |
@@ -230,11 +232,13 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent) | |||
230 | if (err != -ENOTSUPP) | 232 | if (err != -ENOTSUPP) |
231 | goto failed_mount; | 233 | goto failed_mount; |
232 | } | 234 | } |
235 | next_table = msblk->xattr_table; | ||
233 | 236 | ||
234 | allocate_id_index_table: | 237 | allocate_id_index_table: |
235 | /* Allocate and read id index table */ | 238 | /* Allocate and read id index table */ |
236 | msblk->id_table = squashfs_read_id_index_table(sb, | 239 | msblk->id_table = squashfs_read_id_index_table(sb, |
237 | le64_to_cpu(sblk->id_table_start), le16_to_cpu(sblk->no_ids)); | 240 | le64_to_cpu(sblk->id_table_start), next_table, |
241 | le16_to_cpu(sblk->no_ids)); | ||
238 | if (IS_ERR(msblk->id_table)) { | 242 | if (IS_ERR(msblk->id_table)) { |
239 | ERROR("unable to read id index table\n"); | 243 | ERROR("unable to read id index table\n"); |
240 | err = PTR_ERR(msblk->id_table); | 244 | err = PTR_ERR(msblk->id_table); |