aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2012-06-27 14:20:22 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-07-16 11:47:38 -0400
commit8411aa07c7aa22ef3fe269a05e45e672590e4f7f (patch)
tree6d573278c6db84c53c329813060a2cf0865141b4
parentf8db7530c08115356964240e4f9cc90fd112d251 (diff)
udf: Avoid run away loop when partition table length is corrupted
commit adee11b2085bee90bd8f4f52123ffb07882d6256 upstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-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 0bb6a6ded08..ee31a2ad087 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -1254,6 +1254,7 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block,
1254 struct genericPartitionMap *gpm; 1254 struct genericPartitionMap *gpm;
1255 uint16_t ident; 1255 uint16_t ident;
1256 struct buffer_head *bh; 1256 struct buffer_head *bh;
1257 unsigned int table_len;
1257 int ret = 0; 1258 int ret = 0;
1258 1259
1259 bh = udf_read_tagged(sb, block, block, &ident); 1260 bh = udf_read_tagged(sb, block, block, &ident);
@@ -1261,13 +1262,20 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block,
1261 return 1; 1262 return 1;
1262 BUG_ON(ident != TAG_IDENT_LVD); 1263 BUG_ON(ident != TAG_IDENT_LVD);
1263 lvd = (struct logicalVolDesc *)bh->b_data; 1264 lvd = (struct logicalVolDesc *)bh->b_data;
1265 table_len = le32_to_cpu(lvd->mapTableLength);
1266 if (sizeof(*lvd) + table_len > sb->s_blocksize) {
1267 udf_error(sb, __func__, "error loading logical volume descriptor: "
1268 "Partition table too long (%u > %lu)\n", table_len,
1269 sb->s_blocksize - sizeof(*lvd));
1270 goto out_bh;
1271 }
1264 1272
1265 ret = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps)); 1273 ret = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps));
1266 if (ret) 1274 if (ret)
1267 goto out_bh; 1275 goto out_bh;
1268 1276
1269 for (i = 0, offset = 0; 1277 for (i = 0, offset = 0;
1270 i < sbi->s_partitions && offset < le32_to_cpu(lvd->mapTableLength); 1278 i < sbi->s_partitions && offset < table_len;
1271 i++, offset += gpm->partitionMapLength) { 1279 i++, offset += gpm->partitionMapLength) {
1272 struct udf_part_map *map = &sbi->s_partmaps[i]; 1280 struct udf_part_map *map = &sbi->s_partmaps[i];
1273 gpm = (struct genericPartitionMap *) 1281 gpm = (struct genericPartitionMap *)