diff options
author | Paul Gortmaker <paul.gortmaker@windriver.com> | 2013-01-08 11:22:30 -0500 |
---|---|---|
committer | Paul Gortmaker <paul.gortmaker@windriver.com> | 2013-01-08 11:30:53 -0500 |
commit | 4229244bcf131b93e3e1d3a156d471a68990dc9d (patch) | |
tree | 97517bf8a604fd9c771af8987b9bb3df14edcb58 | |
parent | 9019b9a4caeae0d96018a115a473ba752701133e (diff) | |
download | longterm-queue-2.6.34-4229244bcf131b93e3e1d3a156d471a68990dc9d.tar.gz |
add udf partition table check patches
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
-rw-r--r-- | queue/series | 4 | ||||
-rw-r--r-- | queue/udf-Avoid-run-away-loop-when-partition-table-length-.patch | 56 | ||||
-rw-r--r-- | queue/udf-Fortify-loading-of-sparing-table.patch | 135 |
3 files changed, 195 insertions, 0 deletions
diff --git a/queue/series b/queue/series index b358273..4596ff6 100644 --- a/queue/series +++ b/queue/series @@ -60,3 +60,7 @@ export-__get_user_pages_fast-function.patch oprofile-x86-Fix-nmi-unsafe-callgraph-support.patch ext4-avoid-hangs-in-ext4_da_should_update_i_disksize.patch USB-cdc-acm-add-IDs-for-Motorola-H24-HSPA-USB-module.patch + +#misc +udf-Fortify-loading-of-sparing-table.patch +udf-Avoid-run-away-loop-when-partition-table-length-.patch diff --git a/queue/udf-Avoid-run-away-loop-when-partition-table-length-.patch b/queue/udf-Avoid-run-away-loop-when-partition-table-length-.patch new file mode 100644 index 0000000..eff07e5 --- /dev/null +++ b/queue/udf-Avoid-run-away-loop-when-partition-table-length-.patch @@ -0,0 +1,56 @@ +From 737a6534380d2b7ad37dcb812c58fd0c75b93582 Mon Sep 17 00:00:00 2001 +From: Jan Kara <jack@suse.cz> +Date: Wed, 27 Jun 2012 20:20:22 +0200 +Subject: [PATCH] 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> +[PG: in 2.6.34 udf_err() is called udf_error()] +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> +--- + fs/udf/super.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/fs/udf/super.c b/fs/udf/super.c +index 6a3e418..fae9f17 100644 +--- a/fs/udf/super.c ++++ b/fs/udf/super.c +@@ -1298,6 +1298,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); +@@ -1305,6 +1306,13 @@ 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, "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) { +@@ -1313,7 +1321,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 *) +-- +1.7.12.1 + diff --git a/queue/udf-Fortify-loading-of-sparing-table.patch b/queue/udf-Fortify-loading-of-sparing-table.patch new file mode 100644 index 0000000..97beb97 --- /dev/null +++ b/queue/udf-Fortify-loading-of-sparing-table.patch @@ -0,0 +1,135 @@ +From f85c2f697a26c068f4f9f2c442742f48845cfed2 Mon Sep 17 00:00:00 2001 +From: Jan Kara <jack@suse.cz> +Date: Wed, 27 Jun 2012 21:23:07 +0200 +Subject: [PATCH] udf: Fortify loading of sparing table + +commit 1df2ae31c724e57be9d7ac00d78db8a5dabdd050 upstream. + +Add sanity checks when loading sparing table from disk to avoid accessing +unallocated memory or writing to it. + +Signed-off-by: Jan Kara <jack@suse.cz> +[PG: in 2.6.34 udf_err() is called udf_error()] +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> +--- + fs/udf/super.c | 86 ++++++++++++++++++++++++++++++++++++---------------------- + 1 file changed, 53 insertions(+), 33 deletions(-) + +diff --git a/fs/udf/super.c b/fs/udf/super.c +index 1e4543c..6a3e418 100644 +--- a/fs/udf/super.c ++++ b/fs/udf/super.c +@@ -57,6 +57,7 @@ + #include <linux/seq_file.h> + #include <linux/bitmap.h> + #include <linux/crc-itu-t.h> ++#include <linux/log2.h> + #include <asm/byteorder.h> + + #include "udf_sb.h" +@@ -1239,11 +1240,59 @@ out_bh: + return ret; + } + ++static int udf_load_sparable_map(struct super_block *sb, ++ struct udf_part_map *map, ++ struct sparablePartitionMap *spm) ++{ ++ uint32_t loc; ++ uint16_t ident; ++ struct sparingTable *st; ++ struct udf_sparing_data *sdata = &map->s_type_specific.s_sparing; ++ int i; ++ struct buffer_head *bh; ++ ++ map->s_partition_type = UDF_SPARABLE_MAP15; ++ sdata->s_packet_len = le16_to_cpu(spm->packetLength); ++ if (!is_power_of_2(sdata->s_packet_len)) { ++ udf_error(sb, "error loading logical volume descriptor: " ++ "Invalid packet length %u\n", ++ (unsigned)sdata->s_packet_len); ++ return -EIO; ++ } ++ if (spm->numSparingTables > 4) { ++ udf_error(sb, "error loading logical volume descriptor: " ++ "Too many sparing tables (%d)\n", ++ (int)spm->numSparingTables); ++ return -EIO; ++ } ++ ++ for (i = 0; i < spm->numSparingTables; i++) { ++ loc = le32_to_cpu(spm->locSparingTable[i]); ++ bh = udf_read_tagged(sb, loc, loc, &ident); ++ if (!bh) ++ continue; ++ ++ st = (struct sparingTable *)bh->b_data; ++ if (ident != 0 || ++ strncmp(st->sparingIdent.ident, UDF_ID_SPARING, ++ strlen(UDF_ID_SPARING)) || ++ sizeof(*st) + le16_to_cpu(st->reallocationTableLen) > ++ sb->s_blocksize) { ++ brelse(bh); ++ continue; ++ } ++ ++ sdata->s_spar_map[i] = bh; ++ } ++ map->s_partition_func = udf_get_pblock_spar15; ++ return 0; ++} ++ + static int udf_load_logicalvol(struct super_block *sb, sector_t block, + struct kernel_lb_addr *fileset) + { + struct logicalVolDesc *lvd; +- int i, j, offset; ++ int i, offset; + uint8_t type; + struct udf_sb_info *sbi = UDF_SB(sb); + struct genericPartitionMap *gpm; +@@ -1299,38 +1348,9 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block, + } else if (!strncmp(upm2->partIdent.ident, + UDF_ID_SPARABLE, + strlen(UDF_ID_SPARABLE))) { +- uint32_t loc; +- struct sparingTable *st; +- struct sparablePartitionMap *spm = +- (struct sparablePartitionMap *)gpm; +- +- map->s_partition_type = UDF_SPARABLE_MAP15; +- map->s_type_specific.s_sparing.s_packet_len = +- le16_to_cpu(spm->packetLength); +- for (j = 0; j < spm->numSparingTables; j++) { +- struct buffer_head *bh2; +- +- loc = le32_to_cpu( +- spm->locSparingTable[j]); +- bh2 = udf_read_tagged(sb, loc, loc, +- &ident); +- map->s_type_specific.s_sparing. +- s_spar_map[j] = bh2; +- +- if (bh2 == NULL) +- continue; +- +- st = (struct sparingTable *)bh2->b_data; +- if (ident != 0 || strncmp( +- st->sparingIdent.ident, +- UDF_ID_SPARING, +- strlen(UDF_ID_SPARING))) { +- brelse(bh2); +- map->s_type_specific.s_sparing. +- s_spar_map[j] = NULL; +- } +- } +- map->s_partition_func = udf_get_pblock_spar15; ++ if (udf_load_sparable_map(sb, map, ++ (struct sparablePartitionMap *)gpm) < 0) ++ goto out_bh; + } else if (!strncmp(upm2->partIdent.ident, + UDF_ID_METADATA, + strlen(UDF_ID_METADATA))) { +-- +1.7.12.1 + |