1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
http://bugs.gentoo.org/91751
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)
--- e2fsck/pass2.c
+++ e2fsck/pass2.c
@@ -1184,27 +1184,29 @@
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) &&
@@ -1302,7 +1304,7 @@
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;
}
|