From patchwork Mon Jul 30 19:30:07 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [2/2] udf: Avoid run away loop when partition table length is corrupted From: Steve Conklin X-Patchwork-Id: 174079 Message-Id: <1343676607-31153-3-git-send-email-sconklin@canonical.com> To: kernel-team@lists.ubuntu.com Date: Mon, 30 Jul 2012 14:30:07 -0500 From: Jan Kara CVE-2012-3400 BugLink: http://bugs.launchpad.net/bugs/1024497 Backported with changes to error prints from upstream commit adee11b2085bee90bd8f4f52123ffb07882d6256 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 Signed-off-by: Steve Conklin --- fs/udf/super.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/fs/udf/super.c b/fs/udf/super.c index 4ea5ad8..0940837 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -1303,6 +1303,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); @@ -1310,6 +1311,14 @@ 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; + } i = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps)); if (i != 0) { @@ -1318,7 +1327,7 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block, } 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 *)