[kernel] r19390 - in dists/squeeze-security/linux-2.6/debian: . patches/bugfix/all patches/series

Dann Frazier dannf at alioth.debian.org
Sat Sep 22 15:24:52 UTC 2012


Author: dannf
Date: Sat Sep 22 15:24:51 2012
New Revision: 19390

Log:
udf: Fix buffer overflow when parsing sparing table (CVE-2012-3400)

Added:
   dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/udf-Avoid-run-away-loop-when-partition-table-length-is-corrupted.patch
   dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/udf-Fortify-loading-of-sparing-table.patch
Modified:
   dists/squeeze-security/linux-2.6/debian/changelog
   dists/squeeze-security/linux-2.6/debian/patches/series/45squeeze1

Modified: dists/squeeze-security/linux-2.6/debian/changelog
==============================================================================
--- dists/squeeze-security/linux-2.6/debian/changelog	Thu Sep 20 04:42:46 2012	(r19389)
+++ dists/squeeze-security/linux-2.6/debian/changelog	Sat Sep 22 15:24:51 2012	(r19390)
@@ -9,6 +9,7 @@
   * mm: fix vma_resv_map() NULL pointer (CVE-2012-2390)
   * cred: copy_process() should clear child->replacement_session_keyring
     (CVE-2012-2745)
+  * udf: Fix buffer overflow when parsing sparing table (CVE-2012-3400)
 
   [ Ben Hutchings ]
   * tcp: Don't change unlocked socket state in tcp_v4_err(). (Closes: #685087)

Added: dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/udf-Avoid-run-away-loop-when-partition-table-length-is-corrupted.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/udf-Avoid-run-away-loop-when-partition-table-length-is-corrupted.patch	Sat Sep 22 15:24:51 2012	(r19390)
@@ -0,0 +1,48 @@
+commit adee11b2085bee90bd8f4f52123ffb07882d6256
+Author: Jan Kara <jack at 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 at suse.cz>
+    [dannf: backported to Debian's 2.6.32]
+
+diff --git a/fs/udf/super.c b/fs/udf/super.c
+index fd4a262..b350a71 100644
+--- a/fs/udf/super.c
++++ b/fs/udf/super.c
+@@ -1300,6 +1300,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);
+@@ -1307,6 +1308,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) {
+@@ -1315,7 +1324,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 *)

Added: dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/udf-Fortify-loading-of-sparing-table.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/udf-Fortify-loading-of-sparing-table.patch	Sat Sep 22 15:24:51 2012	(r19390)
@@ -0,0 +1,129 @@
+commit 1df2ae31c724e57be9d7ac00d78db8a5dabdd050
+Author: Jan Kara <jack at suse.cz>
+Date:   Wed Jun 27 21:23:07 2012 +0200
+
+    udf: Fortify loading of sparing table
+    
+    Add sanity checks when loading sparing table from disk to avoid accessing
+    unallocated memory or writing to it.
+    
+    Signed-off-by: Jan Kara <jack at suse.cz>
+    [dannf: backported to Debian's 2.6.32]
+
+diff --git a/fs/udf/super.c b/fs/udf/super.c
+index 1e4543c..fd4a262 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,61 @@ 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, __func__,
++			  "error loading logical volume descriptor: "
++			  "Invalid packet length %u\n",
++			  (unsigned)sdata->s_packet_len);
++		return -EIO;
++	}
++	if (spm->numSparingTables > 4) {
++		udf_error(sb, __func__,
++			  "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 +1350,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))) {

Modified: dists/squeeze-security/linux-2.6/debian/patches/series/45squeeze1
==============================================================================
--- dists/squeeze-security/linux-2.6/debian/patches/series/45squeeze1	Thu Sep 20 04:42:46 2012	(r19389)
+++ dists/squeeze-security/linux-2.6/debian/patches/series/45squeeze1	Sat Sep 22 15:24:51 2012	(r19390)
@@ -7,4 +7,6 @@
 + bugfix/all/cred-copy_process-should-clear-child-replacement_session_keyring.patch
 + bugfix/all/tcp-Don-t-change-unlocked-socket-state-in-tcp_v4_err.patch
 + bugfix/all/locks-fix-checking-of-fcntl_setlease-argument.patch
-+ bugfix/all/sfc-Fix-maximum-number-of-TSO-segments-and-minimum-T.patch
\ No newline at end of file
++ bugfix/all/sfc-Fix-maximum-number-of-TSO-segments-and-minimum-T.patch
++ bugfix/all/udf-Fortify-loading-of-sparing-table.patch
++ bugfix/all/udf-Avoid-run-away-loop-when-partition-table-length-is-corrupted.patch



More information about the Kernel-svn-changes mailing list