aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2012-06-27 20:20:22 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-07-16 08:47:38 -0700
commit8411aa07c7aa22ef3fe269a05e45e672590e4f7f (patch)
tree6d573278c6db84c53c329813060a2cf0865141b4 /fs/udf
parentf8db7530c08115356964240e4f9cc90fd112d251 (diff)
downloadkernel_samsung_smdk4412-8411aa07c7aa22ef3fe269a05e45e672590e4f7f.zip
kernel_samsung_smdk4412-8411aa07c7aa22ef3fe269a05e45e672590e4f7f.tar.gz
kernel_samsung_smdk4412-8411aa07c7aa22ef3fe269a05e45e672590e4f7f.tar.bz2
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>
Diffstat (limited to 'fs/udf')
-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 0bb6a6d..ee31a2a 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,
struct genericPartitionMap *gpm;
uint16_t ident;
struct buffer_head *bh;
+ unsigned int table_len;
int ret = 0;
bh = udf_read_tagged(sb, block, block, &ident);
@@ -1261,13 +1262,20 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block,
return 1;
BUG_ON(ident != TAG_IDENT_LVD);
lvd = (struct logicalVolDesc *)bh->b_data;
+ table_len = le32_to_cpu(lvd->mapTableLength);
+ if (sizeof(*lvd) + table_len > sb->s_blocksize) {
+ udf_error(sb, __func__, "error loading logical volume descriptor: "
+ "Partition table too long (%u > %lu)\n", table_len,
+ sb->s_blocksize - sizeof(*lvd));
+ goto out_bh;
+ }
ret = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps));
if (ret)
goto out_bh;
for (i = 0, offset = 0;
- i < sbi->s_partitions && offset < le32_to_cpu(lvd->mapTableLength);
+ i < sbi->s_partitions && offset < table_len;
i++, offset += gpm->partitionMapLength) {
struct udf_part_map *map = &sbi->s_partmaps[i];
gpm = (struct genericPartitionMap *)