The image present at http://kernelfun.blogspot.com/2006/11/mokb-09-11-2006-linux-26x-ext2checkpage.html contains a root directory which has a corrupt i_size, which is extremely large. This causes ext2_lookup ext2_inode_by_name ext2_find_entry to go off and try to check every page <= i_size (via ext2_check_page()), and of course each one fails, but there is a huge number to check. These failures cause a storm of printk's which could in theory result in a DoS, esp. if you have only one cpu to work with. A quick fix for this corruption case would be to simply check the directory size vs. block count; ext2 directories cannot be sparse so if this fails, we can abort the operation early: --- linux-2.6.18.orig/fs/ext2/namei.c +++ linux-2.6.18/fs/ext2/namei.c @@ -60,6 +60,12 @@ static struct dentry *ext2_lookup(struct if (dentry->d_name.len > EXT2_NAME_LEN) return ERR_PTR(-ENAMETOOLONG); + if (dir->i_size > dir->i_blocks << 9) { + printk("corrupted dir #%lu (sparse) len %llu blocks %llu\n", + dir->i_ino, dir->i_size, dir->i_blocks); + return ERR_PTR(-EIO); + } + ino = ext2_inode_by_name(dir, dentry); inode = NULL; if (ino) { This results in an error such as: EXT2-fs error (device loop0): ext2_readdir: bad page in #2 corrupted dir #2 (sparse) len 3238004736 blocks 4 when we try to look up files in the directory: [root@bear-04 ~]# cat mnt/* cat: mnt/*: Input/output error If the corruption were more intentional, and a very large i_size and i_blocks correlate, then additional checking might be needed to address this; perhaps something like keeping a count of the number of bad pages found, and aborting the operation if it exceeds a threshold... Alternately, I notice that ext2_readdir aborts on the first bad page it finds, while ext2_lookup tries to soldier on, page after page. Seems like maybe these should be consistent; if so just bailing on the first bad page we find would catch all cases. I'll bring this up on the ext4 list.
Created attachment 144206 [details] upstream patch sent to LKML today
This fix is now in 2.6.19.2, so when FC6 rebases to that or higher this bug will be resolved. Dave, if you want a patch for 2.6.18 FC6 kernels please let me know.
kernel-2.6.19-1.2895.fc6 from fc6 updates has this fixed now. Thanks, -Eric