[kernel] r12388 - in dists/etch-security/linux-2.6.24/debian: . patches/bugfix patches/series

Dann Frazier dannf at alioth.debian.org
Mon Nov 17 06:19:35 UTC 2008


Author: dannf
Date: Mon Nov 17 06:19:34 2008
New Revision: 12388

Log:
Avoid printk floods when reading corrupted ext[2,3] directories
(CVE-2008-3528)

Added:
   dists/etch-security/linux-2.6.24/debian/patches/bugfix/ext2-avoid-corrupted-directory-printk-floods.patch
   dists/etch-security/linux-2.6.24/debian/patches/bugfix/ext3-avoid-corrupted-directory-printk-floods.patch
Modified:
   dists/etch-security/linux-2.6.24/debian/changelog
   dists/etch-security/linux-2.6.24/debian/patches/series/6~etchnhalf.7

Modified: dists/etch-security/linux-2.6.24/debian/changelog
==============================================================================
--- dists/etch-security/linux-2.6.24/debian/changelog	(original)
+++ dists/etch-security/linux-2.6.24/debian/changelog	Mon Nov 17 06:19:34 2008
@@ -6,8 +6,10 @@
 
   [ dann frazier ]
   * Don't allow splicing to files opened with O_APPEND (CVE-2008-4554)
+  * Avoid printk floods when reading corrupted ext[2,3] directories
+    (CVE-2008-3528)
 
- -- dann frazier <dannf at debian.org>  Sun, 16 Nov 2008 23:14:59 -0700
+ -- dann frazier <dannf at debian.org>  Sun, 16 Nov 2008 23:17:57 -0700
 
 linux-2.6.24 (2.6.24-6~etchnhalf.6) stable-security; urgency=high
 

Added: dists/etch-security/linux-2.6.24/debian/patches/bugfix/ext2-avoid-corrupted-directory-printk-floods.patch
==============================================================================
--- (empty file)
+++ dists/etch-security/linux-2.6.24/debian/patches/bugfix/ext2-avoid-corrupted-directory-printk-floods.patch	Mon Nov 17 06:19:34 2008
@@ -0,0 +1,175 @@
+commit bd39597cbd42a784105a04010100e27267481c67
+Author: Eric Sandeen <sandeen at redhat.com>
+Date:   Wed Oct 15 22:04:02 2008 -0700
+
+    ext2: avoid printk floods in the face of directory corruption
+    
+    A very large directory with many read failures (either due to storage
+    problems, or due to invalid size & blocks from corruption) will generate a
+    printk storm as the filesystem continues to try to read all the blocks.
+    This flood of messages can tie up the box until it is complete - which may
+    be a very long time, especially for very large corrupted values.
+    
+    This is fixed by only reporting the corruption once each time we try to
+    read the directory.
+    
+    [akpm at linux-foundation.org: coding-style fixes]
+    Signed-off-by: Eric Sandeen <sandeen at redhat.com>
+    Signed-off-by: "Theodore Ts'o" <tytso at mit.edu>
+    Cc: Eugene Teo <eugeneteo at kernel.sg>
+    Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
+    Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+
+diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
+index a78c6b4..11a49ce 100644
+--- a/fs/ext2/dir.c
++++ b/fs/ext2/dir.c
+@@ -103,7 +103,7 @@ static int ext2_commit_chunk(struct page *page, loff_t pos, unsigned len)
+ 	return err;
+ }
+ 
+-static void ext2_check_page(struct page *page)
++static void ext2_check_page(struct page *page, int quiet)
+ {
+ 	struct inode *dir = page->mapping->host;
+ 	struct super_block *sb = dir->i_sb;
+@@ -146,10 +146,10 @@ out:
+ 	/* Too bad, we had an error */
+ 
+ Ebadsize:
+-	ext2_error(sb, "ext2_check_page",
+-		"size of directory #%lu is not a multiple of chunk size",
+-		dir->i_ino
+-	);
++	if (!quiet)
++		ext2_error(sb, __func__,
++			"size of directory #%lu is not a multiple "
++			"of chunk size", dir->i_ino);
+ 	goto fail;
+ Eshort:
+ 	error = "rec_len is smaller than minimal";
+@@ -166,32 +166,36 @@ Espan:
+ Einumber:
+ 	error = "inode out of bounds";
+ bad_entry:
+-	ext2_error (sb, "ext2_check_page", "bad entry in directory #%lu: %s - "
+-		"offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
+-		dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
+-		(unsigned long) le32_to_cpu(p->inode),
+-		rec_len, p->name_len);
++	if (!quiet)
++		ext2_error(sb, __func__, "bad entry in directory #%lu: : %s - "
++			"offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
++			dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
++			(unsigned long) le32_to_cpu(p->inode),
++			rec_len, p->name_len);
+ 	goto fail;
+ Eend:
+-	p = (ext2_dirent *)(kaddr + offs);
+-	ext2_error (sb, "ext2_check_page",
+-		"entry in directory #%lu spans the page boundary"
+-		"offset=%lu, inode=%lu",
+-		dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
+-		(unsigned long) le32_to_cpu(p->inode));
++	if (!quiet) {
++		p = (ext2_dirent *)(kaddr + offs);
++		ext2_error(sb, "ext2_check_page",
++			"entry in directory #%lu spans the page boundary"
++			"offset=%lu, inode=%lu",
++			dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
++			(unsigned long) le32_to_cpu(p->inode));
++	}
+ fail:
+ 	SetPageChecked(page);
+ 	SetPageError(page);
+ }
+ 
+-static struct page * ext2_get_page(struct inode *dir, unsigned long n)
++static struct page * ext2_get_page(struct inode *dir, unsigned long n,
++				   int quiet)
+ {
+ 	struct address_space *mapping = dir->i_mapping;
+ 	struct page *page = read_mapping_page(mapping, n, NULL);
+ 	if (!IS_ERR(page)) {
+ 		kmap(page);
+ 		if (!PageChecked(page))
+-			ext2_check_page(page);
++			ext2_check_page(page, quiet);
+ 		if (PageError(page))
+ 			goto fail;
+ 	}
+@@ -292,7 +296,7 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
+ 	for ( ; n < npages; n++, offset = 0) {
+ 		char *kaddr, *limit;
+ 		ext2_dirent *de;
+-		struct page *page = ext2_get_page(inode, n);
++		struct page *page = ext2_get_page(inode, n, 0);
+ 
+ 		if (IS_ERR(page)) {
+ 			ext2_error(sb, __func__,
+@@ -361,6 +365,7 @@ struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
+ 	struct page *page = NULL;
+ 	struct ext2_inode_info *ei = EXT2_I(dir);
+ 	ext2_dirent * de;
++	int dir_has_error = 0;
+ 
+ 	if (npages == 0)
+ 		goto out;
+@@ -374,7 +379,7 @@ struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
+ 	n = start;
+ 	do {
+ 		char *kaddr;
+-		page = ext2_get_page(dir, n);
++		page = ext2_get_page(dir, n, dir_has_error);
+ 		if (!IS_ERR(page)) {
+ 			kaddr = page_address(page);
+ 			de = (ext2_dirent *) kaddr;
+@@ -391,7 +396,9 @@ struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
+ 				de = ext2_next_entry(de);
+ 			}
+ 			ext2_put_page(page);
+-		}
++		} else
++			dir_has_error = 1;
++
+ 		if (++n >= npages)
+ 			n = 0;
+ 		/* next page is past the blocks we've got */
+@@ -414,7 +421,7 @@ found:
+ 
+ struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p)
+ {
+-	struct page *page = ext2_get_page(dir, 0);
++	struct page *page = ext2_get_page(dir, 0, 0);
+ 	ext2_dirent *de = NULL;
+ 
+ 	if (!IS_ERR(page)) {
+@@ -487,7 +494,7 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode)
+ 	for (n = 0; n <= npages; n++) {
+ 		char *dir_end;
+ 
+-		page = ext2_get_page(dir, n);
++		page = ext2_get_page(dir, n, 0);
+ 		err = PTR_ERR(page);
+ 		if (IS_ERR(page))
+ 			goto out;
+@@ -655,14 +662,17 @@ int ext2_empty_dir (struct inode * inode)
+ {
+ 	struct page *page = NULL;
+ 	unsigned long i, npages = dir_pages(inode);
++	int dir_has_error = 0;
+ 
+ 	for (i = 0; i < npages; i++) {
+ 		char *kaddr;
+ 		ext2_dirent * de;
+-		page = ext2_get_page(inode, i);
++		page = ext2_get_page(inode, i, dir_has_error);
+ 
+-		if (IS_ERR(page))
++		if (IS_ERR(page)) {
++			dir_has_error = 1;
+ 			continue;
++		}
+ 
+ 		kaddr = page_address(page);
+ 		de = (ext2_dirent *)kaddr;

Added: dists/etch-security/linux-2.6.24/debian/patches/bugfix/ext3-avoid-corrupted-directory-printk-floods.patch
==============================================================================
--- (empty file)
+++ dists/etch-security/linux-2.6.24/debian/patches/bugfix/ext3-avoid-corrupted-directory-printk-floods.patch	Mon Nov 17 06:19:34 2008
@@ -0,0 +1,49 @@
+commit cdbf6dba28e8e6268c8420857696309470009fd9
+Author: Eric Sandeen <sandeen at redhat.com>
+Date:   Sat Oct 18 20:28:00 2008 -0700
+
+    ext3: avoid printk floods in the face of directory corruption
+    
+    A very large directory with many read failures (either due to storage
+    problems, or due to invalid size & blocks from corruption) will generate a
+    printk storm as the filesystem continues to try to read all the blocks.
+    This flood of messages can tie up the box until it is complete - which may
+    be a very long time, especially for very large corrupted values.
+    
+    This is fixed by only reporting the corruption once each time we try to
+    read the directory.
+    
+    Signed-off-by: Eric Sandeen <sandeen at redhat.com>
+    Signed-off-by: "Theodore Ts'o" <tytso at mit.edu>
+    Cc: Eugene Teo <eugeneteo at kernel.sg>
+    Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
+    Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+
+diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c
+index 28b681e..4c82531 100644
+--- a/fs/ext3/dir.c
++++ b/fs/ext3/dir.c
+@@ -102,6 +102,7 @@ static int ext3_readdir(struct file * filp,
+ 	int err;
+ 	struct inode *inode = filp->f_path.dentry->d_inode;
+ 	int ret = 0;
++	int dir_has_error = 0;
+ 
+ 	sb = inode->i_sb;
+ 
+@@ -148,9 +149,12 @@ static int ext3_readdir(struct file * filp,
+ 		 * of recovering data when there's a bad sector
+ 		 */
+ 		if (!bh) {
+-			ext3_error (sb, "ext3_readdir",
+-				"directory #%lu contains a hole at offset %lu",
+-				inode->i_ino, (unsigned long)filp->f_pos);
++			if (!dir_has_error) {
++				ext3_error(sb, __func__, "directory #%lu "
++					"contains a hole at offset %lld",
++					inode->i_ino, filp->f_pos);
++				dir_has_error = 1;
++			}
+ 			/* corrupt size?  Maybe no more blocks to read */
+ 			if (filp->f_pos > inode->i_blocks << 9)
+ 				break;

Modified: dists/etch-security/linux-2.6.24/debian/patches/series/6~etchnhalf.7
==============================================================================
--- dists/etch-security/linux-2.6.24/debian/patches/series/6~etchnhalf.7	(original)
+++ dists/etch-security/linux-2.6.24/debian/patches/series/6~etchnhalf.7	Mon Nov 17 06:19:34 2008
@@ -2,3 +2,5 @@
 + bugfix/unix-domain-counting-gc.patch
 + bugfix/unix-domain-recursive-descent-abi-ignore.patch
 + bugfix/all/dont-allow-splice-to-files-opened-with-O_APPEND.patch
++ bugfix/ext2-avoid-corrupted-directory-printk-floods.patch
++ bugfix/ext3-avoid-corrupted-directory-printk-floods.patch



More information about the Kernel-svn-changes mailing list