From 6c313fd4732adbb83d6f9c402300487b6a7e84bb Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Thu, 27 Jan 2005 14:28:41 -0500 Subject: [PATCH] Fix e2fsck to not delete symlinks that contain an extended attribute after the ext_attr feature flag has been cleared. (Addresses Red Hat Bugzilla #146284) --- e2fsck/ChangeLog | 9 ++++++ e2fsck/pass2.c | 54 ++++++++++++++++++++++------------- tests/ChangeLog | 4 +++ tests/f_clear_xattr/expect.1 | 38 ++++++++++++++++++++++++ tests/f_clear_xattr/expect.2 | 7 +++++ tests/f_clear_xattr/image.gz | Bin 0 -> 1082 bytes tests/f_clear_xattr/name | 1 + 7 files changed, 93 insertions(+), 20 deletions(-) create mode 100644 tests/f_clear_xattr/expect.1 create mode 100644 tests/f_clear_xattr/expect.2 create mode 100644 tests/f_clear_xattr/image.gz create mode 100644 tests/f_clear_xattr/name diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog index 4effd27a..1d99b1b4 100644 --- a/e2fsck/ChangeLog +++ b/e2fsck/ChangeLog @@ -1,3 +1,12 @@ +2005-01-27 Theodore Ts'o + + * pass2.c (e2fsck_process_bad_inode): Offer to clear i_file_acl + before checking to see if an invalid inode should be + removed, since otherwise the fast symlink detection code + can get confused. Also clear the inode's entry in + inode_bad_map if the inode has been completely fixed. + (Addresses Red Hat Bugzilla #146284) + 2005-01-25 Theodore Ts'o * unix.c (main, check_if_skip): Set the valid flag earlier, and if diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c index 774294c0..ef86d317 100644 --- a/e2fsck/pass2.c +++ b/e2fsck/pass2.c @@ -1178,6 +1178,7 @@ extern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir, ext2_filsys fs = ctx->fs; struct ext2_inode inode; int inode_modified = 0; + int not_fixed = 0; unsigned char *frag, *fsize; struct problem_context pctx; int problem = 0; @@ -1189,6 +1190,14 @@ extern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir, pctx.dir = dir; 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; + 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) && !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) && @@ -1217,14 +1226,17 @@ extern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir, if (ctx->flags & E2F_FLAG_SIGNAL_MASK) return 0; return 1; - } + } else + not_fixed++; problem = 0; } - if (inode.i_faddr && - fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) { - inode.i_faddr = 0; - inode_modified++; + if (inode.i_faddr) { + if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) { + inode.i_faddr = 0; + inode_modified++; + } else + not_fixed++; } switch (fs->super->s_creator_os) { @@ -1256,31 +1268,33 @@ extern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir, if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) { *fsize = 0; inode_modified++; - } + } else + not_fixed++; pctx.num = 0; } - 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; - inode_modified++; - } if (inode.i_file_acl && ((inode.i_file_acl < fs->super->s_first_data_block) || - (inode.i_file_acl >= fs->super->s_blocks_count)) && - fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) { - inode.i_file_acl = 0; - inode_modified++; + (inode.i_file_acl >= fs->super->s_blocks_count))) { + if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) { + inode.i_file_acl = 0; + inode_modified++; + } else + not_fixed++; } if (inode.i_dir_acl && - LINUX_S_ISDIR(inode.i_mode) && - fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) { - inode.i_dir_acl = 0; - inode_modified++; + LINUX_S_ISDIR(inode.i_mode)) { + if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) { + inode.i_dir_acl = 0; + inode_modified++; + } else + not_fixed++; } + if (inode_modified) e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode"); + if (!not_fixed) + ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino); return 0; } diff --git a/tests/ChangeLog b/tests/ChangeLog index c705a646..c4799761 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,7 @@ +2005-01-27 Theodore Ts'o + + * f_clear_xattr: New test case + 2005-01-25 Theodore Ts'o * f_summary_counts: New test case diff --git a/tests/f_clear_xattr/expect.1 b/tests/f_clear_xattr/expect.1 new file mode 100644 index 00000000..5cfbeafa --- /dev/null +++ b/tests/f_clear_xattr/expect.1 @@ -0,0 +1,38 @@ +Pass 1: Checking inodes, blocks, and sizes +Inode 14, i_blocks is 2, should be 0. Fix? yes + +Inode 12, i_blocks is 4, should be 2. Fix? yes + +Inode 13, i_blocks is 2, should be 0. Fix? yes + +Inode 15, i_blocks is 4, should be 2. Fix? yes + +Pass 2: Checking directory structure +i_file_acl for inode 12 (/dir) is 22, should be zero. +Clear? yes + +i_file_acl for inode 13 (/file) is 22, should be zero. +Clear? yes + +i_file_acl for inode 14 (/symlink) is 22, should be zero. +Clear? yes + +i_file_acl for inode 15 (/long-symlink) is 23, should be zero. +Clear? yes + +Pass 3: Checking directory connectivity +Pass 4: Checking reference counts +Pass 5: Checking group summary information +Block bitmap differences: -(22--23) +Fix? yes + +Free blocks count wrong for group #0 (76, counted=78). +Fix? yes + +Free blocks count wrong (76, counted=78). +Fix? yes + + +test_filesys: ***** FILE SYSTEM WAS MODIFIED ***** +test_filesys: 15/16 files (0.0% non-contiguous), 22/100 blocks +Exit status is 1 diff --git a/tests/f_clear_xattr/expect.2 b/tests/f_clear_xattr/expect.2 new file mode 100644 index 00000000..306d2678 --- /dev/null +++ b/tests/f_clear_xattr/expect.2 @@ -0,0 +1,7 @@ +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: 15/16 files (0.0% non-contiguous), 22/100 blocks +Exit status is 0 diff --git a/tests/f_clear_xattr/image.gz b/tests/f_clear_xattr/image.gz new file mode 100644 index 0000000000000000000000000000000000000000..99aca14bb206375a76d998aad901ff37b403d65d GIT binary patch literal 1082 zcmb`?{Zo<$0Kjp}oA0M~nGpWnX7Iy1BGK=8t0;~a8Y zR)&#cm5`5!wKLigNJHXJdgoqvjJg(c$KlzdljbL`ySy+(eDa1{*HoP5Ik2+r?c)}{ zvrx6>apuS!RdD~Mqw60<`TSgB(~`ZL-tF*hRk${Ua*pjaSDXlvW;!@2A2OOLYDtAU zbM$h_cq`r{p=+VW&gzB7Tj9q`ag)n`-Y;bjIbTP(7h`I_$PAT?HRksbNu(za%D}=t zDV{Tc`g~A$sb{*x04n&?-U@k;8hQ^9D5uXrDNb@i*6p$a(d$6qQ4q*0>2$N!gmn$} zs0zj`=8m{v65*u{(b(^&11Z!v8a??s?Q-i^RyH)J5$=I#yA;;6e?XeCfa(KIAVPBd)`1ih-7uY? zo^pb#;5j)iqIWZY{+vFjw!FM$v9u&J$|tFd&kRb!`kj6MtAu^_*z8|de6d-?he_I< znHy5!h7Q>N0qb87h`)LBmUVo1{i@`YvGUGt| zku37$UNwo{flj{)u%kiuXpoxCfEi3yik*V!0y9vsP!hB(0irem;sXwgBo)Ix8&q