+2005-07-04 Theodore Ts'o <tytso@mit.edu>
+
+ * pass2.c (e2fsck_process_bad_inode): Fixed bug which could cause
+ e2fsck to core dump if a disconnected inode contained an
+ extended attribute. This was actually caused by two bugs.
+ The first bug is that if the inode has been fully fixed
+ up, the code will attempt to remove the inode from the
+ inode_bad_map without checking to see if this bitmap is
+ present. Since it is cleared at the end of pass 2, if
+ e2fsck_process_bad_inode is called in pass 4 (as it is for
+ disconnected inodes), this would result in a core dump.
+ This bug was mostly hidden by a second bug, which caused
+ e2fsck_process_bad_inode() to consider all inodes without
+ an extended attribute to be not fixed. (Addresses Debian
+ Bug: #316736)
+
2006-06-30 Theodore Ts'o <tytso@mit.edu>
* Release of E2fsprogs 1.38
pctx.inode = &inode;
if (inode.i_file_acl &&
- !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
- fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
- inode.i_file_acl = 0;
+ !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
+ if (fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
+ inode.i_file_acl = 0;
#ifdef EXT2FS_ENABLE_SWAPFS
- /*
- * This is a special kludge to deal with long symlinks
- * on big endian systems. i_blocks had already been
- * decremented earlier in pass 1, but since i_file_acl
- * hadn't yet been cleared, ext2fs_read_inode()
- * assumed that the file was short symlink and would
- * not have byte swapped i_block[0]. Hence, we have
- * to byte-swap it here.
- */
- if (LINUX_S_ISLNK(inode.i_mode) &&
- (fs->flags & EXT2_FLAG_SWAP_BYTES) &&
- (inode.i_blocks == fs->blocksize >> 9))
- inode.i_block[0] = ext2fs_swab32(inode.i_block[0]);
+ /*
+ * This is a special kludge to deal with long
+ * symlinks on big endian systems. i_blocks
+ * had already been decremented earlier in
+ * pass 1, but since i_file_acl hadn't yet
+ * been cleared, ext2fs_read_inode() assumed
+ * that the file was short symlink and would
+ * not have byte swapped i_block[0]. Hence,
+ * we have to byte-swap it here.
+ */
+ if (LINUX_S_ISLNK(inode.i_mode) &&
+ (fs->flags & EXT2_FLAG_SWAP_BYTES) &&
+ (inode.i_blocks == fs->blocksize >> 9))
+ inode.i_block[0] = ext2fs_swab32(inode.i_block[0]);
#endif
- inode_modified++;
- } else
- not_fixed++;
+ inode_modified++;
+ } else
+ not_fixed++;
+ }
if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
!LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
if (inode_modified)
e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode");
- if (!not_fixed)
+ if (!not_fixed && ctx->inode_bad_map)
ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
return 0;
}
--- /dev/null
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+/lost+found not found. Create? yes
+
+Pass 4: Checking reference counts
+Inode 2 ref count is 4, should be 3. Fix? yes
+
+i_file_acl for inode 13 (...) is 4218798225, should be zero.
+Clear? yes
+
+Inode 13 (...) has invalid mode (0117003).
+Clear? yes
+
+i_file_acl for inode 14 (...) is 2892851642, should be zero.
+Clear? yes
+
+Inode 14 (...) has invalid mode (0154247).
+Clear? yes
+
+i_file_acl for inode 15 (...) is 1143674715, should be zero.
+Clear? yes
+
+Inode 15 (...) has invalid mode (074044).
+Clear? yes
+
+i_file_acl for inode 16 (...) is 2007517039, should be zero.
+Clear? yes
+
+i_faddr for inode 16 (...) is 1003914917, should be zero.
+Clear? yes
+
+i_frag for inode 16 (...) is 42, should be zero.
+Clear? yes
+
+i_fsize for inode 16 (...) is 245, should be zero.
+Clear? yes
+
+Unattached inode 16
+Connect to /lost+found? yes
+
+Inode 16 ref count is 5925, should be 1. Fix? yes
+
+Pass 5: Checking group summary information
+Block bitmap differences: -(9--19)
+Fix? yes
+
+Free blocks count wrong for group #0 (79, counted=91).
+Fix? yes
+
+Free blocks count wrong (79, counted=91).
+Fix? yes
+
+Inode bitmap differences: +16
+Fix? yes
+
+Free inodes count wrong for group #0 (7, counted=4).
+Fix? yes
+
+Directories count wrong for group #0 (3, counted=2).
+Fix? yes
+
+Free inodes count wrong (7, counted=4).
+Fix? yes
+
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
+test_filesys: 12/16 files (0.0% non-contiguous), 9/100 blocks
+Exit status is 1
--- /dev/null
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 12/16 files (0.0% non-contiguous), 9/100 blocks
+Exit status is 0
--- /dev/null
+Disconnected inode with bad fields