summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2012-06-27 20:20:22 +0200
committerMarkus Lehtonen <markus.lehtonen@linux.intel.com>2013-04-05 09:13:03 +0300
commitf242f8f7c68d4462d26a148c3da6929a5b5b894d (patch)
tree69af10b93ef4d1974d830592c6c9e067f0711f8a
parent3364bf1a77af87dd3da5ae82b7b928ad44ea8c10 (diff)
downloadkernel-mfld-blackbay-f242f8f7c68d4462d26a148c3da6929a5b5b894d.tar.gz
kernel-mfld-blackbay-f242f8f7c68d4462d26a148c3da6929a5b5b894d.tar.bz2
kernel-mfld-blackbay-f242f8f7c68d4462d26a148c3da6929a5b5b894d.zip
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 04e9e0fd105..3d05eeddae5 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 *)