aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf/super.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2012-06-27 14:20:22 -0400
committerJan Kara <jack@suse.cz>2012-06-28 13:30:58 -0400
commitadee11b2085bee90bd8f4f52123ffb07882d6256 (patch)
treec0219a7105329d633a9101235548a587bfcebee2 /fs/udf/super.c
parentcb14d340ef1737c24125dd663eff77734a482d47 (diff)
udf: Avoid run away loop when partition table length is corrupted
Check provided length of partition table so that (possibly maliciously) corrupted partition table cannot cause accessing data beyond current buffer. Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/udf/super.c')
-rw-r--r--fs/udf/super.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 9da6f4ee112c..ce911f50b39d 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -1225,6 +1225,7 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block,
1225 struct genericPartitionMap *gpm; 1225 struct genericPartitionMap *gpm;
1226 uint16_t ident; 1226 uint16_t ident;
1227 struct buffer_head *bh; 1227 struct buffer_head *bh;
1228 unsigned int table_len;
1228 int ret = 0; 1229 int ret = 0;
1229 1230
1230 bh = udf_read_tagged(sb, block, block, &ident); 1231 bh = udf_read_tagged(sb, block, block, &ident);
@@ -1232,13 +1233,20 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block,
1232 return 1; 1233 return 1;
1233 BUG_ON(ident != TAG_IDENT_LVD); 1234 BUG_ON(ident != TAG_IDENT_LVD);
1234 lvd = (struct logicalVolDesc *)bh->b_data; 1235 lvd = (struct logicalVolDesc *)bh->b_data;
1236 table_len = le32_to_cpu(lvd->mapTableLength);
1237 if (sizeof(*lvd) + table_len > sb->s_blocksize) {
1238 udf_err(sb, "error loading logical volume descriptor: "
1239 "Partition table too long (%u > %lu)\n", table_len,
1240 sb->s_blocksize - sizeof(*lvd));
1241 goto out_bh;
1242 }
1235 1243
1236 ret = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps)); 1244 ret = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps));
1237 if (ret) 1245 if (ret)
1238 goto out_bh; 1246 goto out_bh;
1239 1247
1240 for (i = 0, offset = 0; 1248 for (i = 0, offset = 0;
1241 i < sbi->s_partitions && offset < le32_to_cpu(lvd->mapTableLength); 1249 i < sbi->s_partitions && offset < table_len;
1242 i++, offset += gpm->partitionMapLength) { 1250 i++, offset += gpm->partitionMapLength) {
1243 struct udf_part_map *map = &sbi->s_partmaps[i]; 1251 struct udf_part_map *map = &sbi->s_partmaps[i];
1244 gpm = (struct genericPartitionMap *) 1252 gpm = (struct genericPartitionMap *)