https://bugzilla.redhat.com/show_bug.cgi?id=843141
link: http://post-office.corp.redhat.com/archives/rhkernel-list/2012-October/msg02...
commit adee11b2085bee90bd8f4f52123ffb07882d6256 Author: Jan Kara jack@suse.cz Date: Wed Jun 27 20:20:22 2012 +0200
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
Signed-off-by: Nikola Pajkovsky npajkovs@redhat.com --- fs/udf/super.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-)
diff --git a/fs/udf/super.c b/fs/udf/super.c index 6f84480..f4a1800 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -1032,13 +1032,22 @@ udf_load_logicalvol(struct super_block *sb, struct buffer_head * bh, kernel_lb_a struct logicalVolDesc *lvd; int i, j, offset; uint8_t type; - + unsigned table_len; lvd = (struct logicalVolDesc *)bh->b_data;
+ table_len = le32_to_cpu(lvd->mapTableLength); + if (sizeof(*lvd) + table_len > sb->s_blocksize) { + udf_error(sb, __FUNCTION__, + "error loading logical volume descriptor: " + "Partition table too long (%u > %lu)\n", table_len, + sb->s_blocksize - sizeof(*lvd)); + return 1; + } + UDF_SB_ALLOC_PARTMAPS(sb, le32_to_cpu(lvd->numPartitionMaps));
for (i=0,offset=0; - i<UDF_SB_NUMPARTS(sb) && offset<le32_to_cpu(lvd->mapTableLength); + i<UDF_SB_NUMPARTS(sb) && offset<table_len; i++,offset+=((struct genericPartitionMap *)&(lvd->partitionMaps[offset]))->partitionMapLength) { type = ((struct genericPartitionMap *)&(lvd->partitionMaps[offset]))->partitionMapType; @@ -1258,8 +1267,12 @@ udf_process_sequence(struct super_block *sb, long block, long lastblock, kernel_
if (i == VDS_POS_PRIMARY_VOL_DESC) udf_load_pvoldesc(sb, bh); - else if (i == VDS_POS_LOGICAL_VOL_DESC) - udf_load_logicalvol(sb, bh, fileset); + else if (i == VDS_POS_LOGICAL_VOL_DESC) { + if (udf_load_logicalvol(sb, bh, fileset)) { + brelse(bh); + return 1; + } + } else if (i == VDS_POS_PARTITION_DESC) { struct buffer_head *bh2 = NULL; @@ -1338,13 +1351,12 @@ udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset)
brelse(bh);
- /* Process the main & reserve sequences */ + /* Process the main sequence */ /* responsible for finding the PartitionDesc(s) */ - if (!(udf_process_sequence(sb, main_s, main_e, fileset) && - udf_process_sequence(sb, reserve_s, reserve_e, fileset))) - { + if (udf_process_sequence(sb, main_s, main_e, fileset)) + return 1; + else break; - } } }
shit, wrong mailing list
Nikola Pajkovsky npajkovs@redhat.com writes:
https://bugzilla.redhat.com/show_bug.cgi?id=843141
link: http://post-office.corp.redhat.com/archives/rhkernel-list/2012-October/msg02...
commit adee11b2085bee90bd8f4f52123ffb07882d6256 Author: Jan Kara jack@suse.cz Date: Wed Jun 27 20:20:22 2012 +0200
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>
Signed-off-by: Nikola Pajkovsky npajkovs@redhat.com
fs/udf/super.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-)
diff --git a/fs/udf/super.c b/fs/udf/super.c index 6f84480..f4a1800 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -1032,13 +1032,22 @@ udf_load_logicalvol(struct super_block *sb, struct buffer_head * bh, kernel_lb_a struct logicalVolDesc *lvd; int i, j, offset; uint8_t type;
unsigned table_len; lvd = (struct logicalVolDesc *)bh->b_data;
table_len = le32_to_cpu(lvd->mapTableLength);
if (sizeof(*lvd) + table_len > sb->s_blocksize) {
udf_error(sb, __FUNCTION__,
"error loading logical volume descriptor: "
"Partition table too long (%u > %lu)\n", table_len,
sb->s_blocksize - sizeof(*lvd));
return 1;
}
UDF_SB_ALLOC_PARTMAPS(sb, le32_to_cpu(lvd->numPartitionMaps));
for (i=0,offset=0;
i<UDF_SB_NUMPARTS(sb) && offset<le32_to_cpu(lvd->mapTableLength);
i++,offset+=((struct genericPartitionMap *)&(lvd->partitionMaps[offset]))->partitionMapLength) { type = ((struct genericPartitionMap *)&(lvd->partitionMaps[offset]))->partitionMapType;i<UDF_SB_NUMPARTS(sb) && offset<table_len;
@@ -1258,8 +1267,12 @@ udf_process_sequence(struct super_block *sb, long block, long lastblock, kernel_
if (i == VDS_POS_PRIMARY_VOL_DESC) udf_load_pvoldesc(sb, bh);
else if (i == VDS_POS_LOGICAL_VOL_DESC)
udf_load_logicalvol(sb, bh, fileset);
else if (i == VDS_POS_LOGICAL_VOL_DESC) {
if (udf_load_logicalvol(sb, bh, fileset)) {
brelse(bh);
return 1;
}
} else if (i == VDS_POS_PARTITION_DESC) { struct buffer_head *bh2 = NULL;
@@ -1338,13 +1351,12 @@ udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset)
brelse(bh);
/* Process the main & reserve sequences */
/* Process the main sequence */ /* responsible for finding the PartitionDesc(s) */
if (!(udf_process_sequence(sb, main_s, main_e, fileset) &&
udf_process_sequence(sb, reserve_s, reserve_e, fileset)))
{
if (udf_process_sequence(sb, main_s, main_e, fileset))
return 1;
else break;
} }}
- nack, I don't want this in ABRT ;)
On 12/18/2012 08:59 AM, Nikola Pajkovsky wrote:
https://bugzilla.redhat.com/show_bug.cgi?id=843141
link: http://post-office.corp.redhat.com/archives/rhkernel-list/2012-October/msg02...
commit adee11b2085bee90bd8f4f52123ffb07882d6256 Author: Jan Kara jack@suse.cz Date: Wed Jun 27 20:20:22 2012 +0200
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>
Signed-off-by: Nikola Pajkovsky npajkovs@redhat.com
fs/udf/super.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-)
diff --git a/fs/udf/super.c b/fs/udf/super.c index 6f84480..f4a1800 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -1032,13 +1032,22 @@ udf_load_logicalvol(struct super_block *sb, struct buffer_head * bh, kernel_lb_a struct logicalVolDesc *lvd; int i, j, offset; uint8_t type;
unsigned table_len; lvd = (struct logicalVolDesc *)bh->b_data;
table_len = le32_to_cpu(lvd->mapTableLength);
if (sizeof(*lvd) + table_len > sb->s_blocksize) {
udf_error(sb, __FUNCTION__,
"error loading logical volume descriptor: "
"Partition table too long (%u > %lu)\n", table_len,
sb->s_blocksize - sizeof(*lvd));
return 1;
}
UDF_SB_ALLOC_PARTMAPS(sb, le32_to_cpu(lvd->numPartitionMaps));
for (i=0,offset=0;
i<UDF_SB_NUMPARTS(sb) && offset<le32_to_cpu(lvd->mapTableLength);
i++,offset+=((struct genericPartitionMap *)&(lvd->partitionMaps[offset]))->partitionMapLength) { type = ((struct genericPartitionMap *)&(lvd->partitionMaps[offset]))->partitionMapType;i<UDF_SB_NUMPARTS(sb) && offset<table_len;
@@ -1258,8 +1267,12 @@ udf_process_sequence(struct super_block *sb, long block, long lastblock, kernel_
if (i == VDS_POS_PRIMARY_VOL_DESC) udf_load_pvoldesc(sb, bh);
else if (i == VDS_POS_LOGICAL_VOL_DESC)
udf_load_logicalvol(sb, bh, fileset);
else if (i == VDS_POS_LOGICAL_VOL_DESC) {
if (udf_load_logicalvol(sb, bh, fileset)) {
brelse(bh);
return 1;
}
} else if (i == VDS_POS_PARTITION_DESC) { struct buffer_head *bh2 = NULL;
@@ -1338,13 +1351,12 @@ udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset)
brelse(bh);
/* Process the main & reserve sequences */
/* Process the main sequence */ /* responsible for finding the PartitionDesc(s) */
if (!(udf_process_sequence(sb, main_s, main_e, fileset) &&
udf_process_sequence(sb, reserve_s, reserve_e, fileset)))
{
if (udf_process_sequence(sb, main_s, main_e, fileset))
return 1;
else break;
} }}
crash-catcher@lists.fedorahosted.org