Author: lcapitulino
Date: Thu Feb 15 16:49:58 2007
New Revision: 121428

Added:
   
packages/updates/2006.0/kernel-2.6/current/PATCHES/patches/ZZCD_CVE-2006-6053_ext3_handle_dir_corruption.patch
Modified:
   packages/updates/2006.0/kernel-2.6/current/SPECS/kernel-2.6.spec

Log:
Fix for CVE-2006-6053

Added: 
packages/updates/2006.0/kernel-2.6/current/PATCHES/patches/ZZCD_CVE-2006-6053_ext3_handle_dir_corruption.patch
==============================================================================
--- (empty file)
+++ 
packages/updates/2006.0/kernel-2.6/current/PATCHES/patches/ZZCD_CVE-2006-6053_ext3_handle_dir_corruption.patch
      Thu Feb 15 16:49:58 2007
@@ -0,0 +1,80 @@
+commit 40b851348fe9bf49c26025b34261d25142269b60
+Author: Eric Sandeen <[EMAIL PROTECTED]>
+Date:   Wed Dec 6 20:36:26 2006 -0800
+
+    [PATCH] handle ext3 directory corruption better
+    
+    I've been using Steve Grubb's purely evil "fsfuzzer" tool, at
+    http://people.redhat.com/sgrubb/files/fsfuzzer-0.4.tar.gz
+    
+    Basically it makes a filesystem, splats some random bits over it, then
+    tries to mount it and do some simple filesystem actions.
+    
+    At best, the filesystem catches the corruption gracefully.  At worst,
+    things spin out of control.
+    
+    As you might guess, we found a couple places in ext3 where things spin out
+    of control :)
+    
+    First, we had a corrupted directory that was never checked for
+    consistency...  it was corrupt, and pointed to another bad "entry" of
+    length 0.  The for() loop looped forever, since the length of
+    ext3_next_entry(de) was 0, and we kept looking at the same pointer over and
+    over and over and over...  I modeled this check and subsequent action on
+    what is done for other directory types in ext3_readdir...
+    
+    (adding this check adds some computational expense; I am testing a followup
+    patch to reduce the number of times we check and re-check these directory
+    entries, in all cases.  Thanks for the idea, Andreas).
+    
+    Next we had a root directory inode which had a corrupted size, claimed to
+    be > 200M on a 4M filesystem.  There was only really 1 block in the
+    directory, but because the size was so large, readdir kept coming back for
+    more, spewing thousands of printk's along the way.
+    
+    Per Andreas' suggestion, if we're in this read error condition and we're
+    trying to read an offset which is greater than i_blocks worth of bytes,
+    stop trying, and break out of the loop.
+    
+    With these two changes fsfuzz test survives quite well on ext3.
+    
+    Signed-off-by: Eric Sandeen <[EMAIL PROTECTED]>
+    Cc: <[email protected]>
+    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
+    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
+
+---
+ fs/ext3/dir.c   |    3 +++
+ fs/ext3/namei.c |    9 +++++++++
+ 2 files changed, 12 insertions(+)
+
+--- linux-2.6.12.orig/fs/ext3/dir.c
++++ linux-2.6.12/fs/ext3/dir.c
+@@ -134,6 +134,9 @@ static int ext3_readdir(struct file * fi
+                       ext3_error (sb, "ext3_readdir",
+                               "directory #%lu contains a hole at offset %lu",
+                               inode->i_ino, (unsigned long)filp->f_pos);
++                      /* corrupt size?  Maybe no more blocks to read */
++                      if (filp->f_pos > inode->i_blocks << 9)
++                              break;
+                       filp->f_pos += sb->s_blocksize - offset;
+                       continue;
+               }
+--- linux-2.6.12.orig/fs/ext3/namei.c
++++ linux-2.6.12/fs/ext3/namei.c
+@@ -554,6 +554,15 @@ static int htree_dirblock_to_tree(struct
+                                          dir->i_sb->s_blocksize -
+                                          EXT3_DIR_REC_LEN(0));
+       for (; de < top; de = ext3_next_entry(de)) {
++              if (!ext3_check_dir_entry("htree_dirblock_to_tree", dir, de, bh,
++                                      (block<<EXT3_BLOCK_SIZE_BITS(dir->i_sb))
++                                              +((char *)de - bh->b_data))) {
++                      /* On error, skip the f_pos to the next block. */
++                      dir_file->f_pos = (dir_file->f_pos |
++                                      (dir->i_sb->s_blocksize - 1)) + 1;
++                      brelse (bh);
++                      return count;
++              }
+               ext3fs_dirhash(de->name, de->name_len, hinfo);
+               if ((hinfo->hash < start_hash) ||
+                   ((hinfo->hash == start_hash) &&

Modified: packages/updates/2006.0/kernel-2.6/current/SPECS/kernel-2.6.spec
==============================================================================
--- packages/updates/2006.0/kernel-2.6/current/SPECS/kernel-2.6.spec    
(original)
+++ packages/updates/2006.0/kernel-2.6/current/SPECS/kernel-2.6.spec    Thu Feb 
15 16:49:58 2007
@@ -1371,6 +1371,7 @@
     - NET: Make sure l_linger is unsigned to avoid negative timeouts
     - Security fixes:
       * ZZCC_CVE-2006-4538_ia64_corrupt_elf.patch                (#26747)
+      * ZZCD_CVE-2006-6053_ext3_handle_dir_corruption.patch      (#28303)
 
 * Thu Jan 18 2007 Samir Bellabes <[EMAIL PROTECTED]> 2.6.12-30mdk
   o Samir Bellabes <[EMAIL PROTECTED]>

Reply via email to