From: Theodore Ts'o Date: Tue, 21 May 2002 13:14:17 +0000 (-0400) Subject: Fix up Andreas' changeset. Avoid use of dynamic automatic arrays, X-Git-Tag: E2FSPROGS-1.28-WIP-0626~16 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=bcf9c5d4016975c3c2afdb4a4b358569bd3c8681;p=tools%2Fe2fsprogs.git Fix up Andreas' changeset. Avoid use of dynamic automatic arrays, and check for EXT2_INDEX_FL for special devices, and consider them to be invalid if they are set. --- diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog index f8795d9..5c1df96 100644 --- a/e2fsck/ChangeLog +++ b/e2fsck/ChangeLog @@ -1,3 +1,52 @@ +2002-05-20 Theodore Ts'o + + * e2fsck.h, pass1.c (e2fsck_pass1_check_symlink), pass2.c + (e2fsck_process_bad_inode): Add an extra + argument so a scratch buffer can be passed into the + function. + + * pass1.c (e2fsck_pass1_check_device_inode, + e2fsck_pass1_check_symlink): If the EXT2_INDEX_FL flag is + set, then the device/FIFO is invalid. + (check_immutable): Don't check for EXT2_INDEX_FL; we take + care of that elsewhere now. + (e2fsck_pass1): Check to see if the symlink is valid + before we offer to clear any immutable bits. This matches + the order in which we check other special files. + + * pass2.c (e2fsck_pass2): Allocate a bigger scratch buffer so we + can pass part of it to e2fsck_process_bad_inode. + + * pass4.c (e2fsck_pass4): If we need to call + e2fsck_process_bad_inode(), allocate the necessary scratch + buffer. + + * problem.h, problem.c: Change PR_2_SYMLINK_SIZE to be + PR_2_INVALID_SYMLINK, and change the text + accordingly. Revert the text change for PR_1_SET_IMMUTABLE + since we no longer check for EXT2_INDEX_FL in + check_immutable(). + +2002-05-18 Andreas Dilger + + * pass1.c (e2fsck_pass1_check_symlink): Remove checks of + immutable/append-only checks, since this is handled by + check_immutable. For non-fast symlinks, read in the + data block and check the length to make sure it + matches with the inode size. + (check_immutable): Generalize to also check for the + EXT2_INDEX_FL flag. + (check_blocks): For non-regular files, signal a bad inode + size if i_size_high is non-zero. + + * pass2.c: Only count large files if they are regular files + (not just if they aren't directories). + + * problem.c, problem.h: Change comment for PR_2_SYMLINK_SIZE + to indicate that it can be triggered by any symlink, + not fast symlink. Change text for PR_1_SET_IMMUTABLE + to indicate that it the EXT2_INDEX_FL was set. + 2002-05-17 Theodore Ts'o * pass1.c (e2fsck_pass1): When calculating max_sizes, omit capping diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h index e1e92ba..88490aa 100644 --- a/e2fsck/e2fsck.h +++ b/e2fsck/e2fsck.h @@ -323,10 +323,12 @@ extern void e2fsck_move_ext3_journal(e2fsck_t ctx); /* pass1.c */ extern void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool); extern int e2fsck_pass1_check_device_inode(struct ext2_inode *inode); -extern int e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode); +extern int e2fsck_pass1_check_symlink(ext2_filsys fs, + struct ext2_inode *inode, char *buf); /* pass2.c */ -extern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir, ext2_ino_t ino); +extern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir, + ext2_ino_t ino, char *buf); /* pass3.c */ extern int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t inode); diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index 1d7b3f8..5828b13 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -129,10 +129,12 @@ int e2fsck_pass1_check_device_inode(struct ext2_inode *inode) int i; /* - * If i_blocks is non-zero, then this is a bogus device/fifo/socket + * If i_blocks is non-zero, or the index flag is set, then + * this is a bogus device/fifo/socket */ - if (inode->i_blocks) + if (inode->i_blocks || (inode->i_flags & EXT2_INDEX_FL)) return 0; + /* * We should be able to do the test below all the time, but * because the kernel doesn't forcibly clear the device @@ -171,12 +173,14 @@ static int strnlen(const char * s, int count) * Check to make sure a symlink inode is real. Returns 1 if the symlink * checks out, 0 if not. */ -int e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode) +int e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode, + char *buf) { int len; int i; - if (inode->i_size_high || inode->i_size == 0) + if ((inode->i_size_high || inode->i_size == 0) || + (inode->i_flags & EXT2_INDEX_FL)) return 0; if (inode->i_blocks) { @@ -190,15 +194,12 @@ int e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode) if (inode->i_block[i]) return 0; - {char buf[fs->blocksize]; - if (io_channel_read_blk(fs->io, inode->i_block[0], 1, buf)) return 0; len = strnlen(buf, fs->blocksize); if (len == fs->blocksize) return 0; - } } else { if (inode->i_size >= sizeof(inode->i_block)) return 0; @@ -216,7 +217,7 @@ int e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode) * If the immutable (or append-only) flag is set on the inode, offer * to clear it. */ -#define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL | EXT2_INDEX_FL) +#define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL) static void check_immutable(e2fsck_t ctx, struct problem_context *pctx) { if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS)) @@ -615,11 +616,10 @@ void e2fsck_pass1(e2fsck_t ctx) check_immutable(ctx, &pctx); check_size(ctx, &pctx); ctx->fs_blockdev_count++; - } else if (LINUX_S_ISLNK (inode.i_mode)) { + } else if (LINUX_S_ISLNK (inode.i_mode) && + e2fsck_pass1_check_symlink(fs, &inode, block_buf)) { check_immutable(ctx, &pctx); ctx->fs_symlinks_count++; - if (!e2fsck_pass1_check_symlink(fs, &inode)) - mark_inode_bad(ctx, ino); if (!inode.i_blocks) { ctx->fs_fast_symlinks_count++; goto next; @@ -1139,7 +1139,7 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx, int bad_size = 0; __u64 size; - if (!ext2fs_inode_has_valid_blocks(pctx->inode)) + if (!ext2fs_inode_has_valid_blocks(inode)) return; pb.ino = ino; diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c index 19a682a..34c253d 100644 --- a/e2fsck/pass2.c +++ b/e2fsck/pass2.c @@ -107,7 +107,7 @@ void e2fsck_pass2(e2fsck_t ctx) ctx->flags |= E2F_FLAG_ABORT; return; } - buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize, + buf = (char *) e2fsck_allocate_memory(ctx, 2*fs->blocksize, "directory scan buffer"); /* @@ -547,7 +547,8 @@ static int check_dir_block(ext2_filsys fs, ext2fs_test_inode_bitmap(ctx->inode_bad_map, dirent->inode)) { if (e2fsck_process_bad_inode(ctx, ino, - dirent->inode)) { + dirent->inode, + buf + fs->blocksize)) { dirent->inode = 0; dir_modified++; goto next; @@ -696,7 +697,7 @@ static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf) } extern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir, - ext2_ino_t ino) + ext2_ino_t ino, char *buf) { ext2_filsys fs = ctx->fs; struct ext2_inode inode; @@ -730,8 +731,8 @@ extern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir, && !e2fsck_pass1_check_device_inode(&inode)) problem = PR_2_BAD_SOCKET; else if (LINUX_S_ISLNK(inode.i_mode) - && !e2fsck_pass1_check_symlink(fs, &inode)) { - problem = PR_2_SYMLINK_SIZE; + && !e2fsck_pass1_check_symlink(fs, &inode, buf)) { + problem = PR_2_INVALID_SYMLINK; } if (problem) { diff --git a/e2fsck/pass4.c b/e2fsck/pass4.c index 40bc20b..895b77a 100644 --- a/e2fsck/pass4.c +++ b/e2fsck/pass4.c @@ -86,6 +86,7 @@ void e2fsck_pass4(e2fsck_t ctx) #endif struct problem_context pctx; __u16 link_count, link_counted; + char *buf = 0; int group, maxgroup; #ifdef RESOURCE_TRACK @@ -126,7 +127,10 @@ void e2fsck_pass4(e2fsck_t ctx) ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count); ext2fs_icount_fetch(ctx->inode_count, i, &link_counted); if (link_counted == 0) { - if (e2fsck_process_bad_inode(ctx, 0, i)) + if (!buf) + buf = e2fsck_allocate_memory(ctx, + fs->blocksize, "bad_inode buffer"); + if (e2fsck_process_bad_inode(ctx, 0, i, buf)) continue; if (disconnect_inode(ctx, i)) continue; @@ -157,6 +161,8 @@ void e2fsck_pass4(e2fsck_t ctx) ctx->inode_bb_map = 0; ext2fs_free_inode_bitmap(ctx->inode_imagic_map); ctx->inode_imagic_map = 0; + if (buf) + ext2fs_free_mem((void **) &buf); #ifdef RESOURCE_TRACK if (ctx->options & E2F_OPT_TIME2) { e2fsck_clear_progbar(ctx); diff --git a/e2fsck/problem.c b/e2fsck/problem.c index 126d9d5..aaaa270 100644 --- a/e2fsck/problem.c +++ b/e2fsck/problem.c @@ -550,8 +550,8 @@ static const struct e2fsck_problem problem_table[] = { /* Immutable flag set on a device or socket inode */ { PR_1_SET_IMMUTABLE, - N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable,\n" - "append-only, or dir index flag set. "), + N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n" + "or append-only flag set. "), PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK }, /* Compression flag set on an inode when filesystem doesn't support it */ @@ -949,9 +949,9 @@ static const struct e2fsck_problem problem_table[] = { N_("@E has a zero-length name.\n"), PROMPT_CLEAR, 0 }, - /* Invalid symlink size */ - { PR_2_SYMLINK_SIZE, - N_("Symlink %Q (@i #%i) has an invalid size (%Is).\n"), + /* Invalid symlink */ + { PR_2_INVALID_SYMLINK, + N_("Symlink %Q (@i #%i) is invalid.\n"), PROMPT_CLEAR, 0 }, /* i_file_acl (extended attribute block) is bad */ diff --git a/e2fsck/problem.h b/e2fsck/problem.h index 666b893..f5eae27 100644 --- a/e2fsck/problem.h +++ b/e2fsck/problem.h @@ -562,8 +562,8 @@ struct problem_context { /* Directory filename can't be zero-length */ #define PR_2_NULL_NAME 0x020030 -/* Invalid symlink size */ -#define PR_2_SYMLINK_SIZE 0x020031 +/* Invalid symlink */ +#define PR_2_INVALID_SYMLINK 0x020031 /* i_file_acl (extended attribute) is bad */ #define PR_2_FILE_ACL_BAD 0x020032 diff --git a/tests/ChangeLog b/tests/ChangeLog index 717c2bf..2706592 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,12 @@ +2002-05-21 Theodore Ts'o + + * f_badsymlinks, f_filetype: Revert expected text since we're no + longer checking for EXT2_INDEX_FL along with the other + immutable flags. + + * f_badsymlinks, f_badinode: The symlink invalid size problem text + has been generalized to "invalid symlink". + 2002-05-18 Andreas Dilger * f_badsymlink: Add extra length checks for symlinks diff --git a/tests/f_badinode/expect.1 b/tests/f_badinode/expect.1 index 3ce38c9..6207042 100644 --- a/tests/f_badinode/expect.1 +++ b/tests/f_badinode/expect.1 @@ -17,7 +17,7 @@ Clear? yes Inode 15 (/char_dev) is an illegal character device. Clear? yes -Symlink /test-symlink (inode #16) has an invalid size (100). +Symlink /test-symlink (inode #16) is invalid. Clear? yes Pass 3: Checking directory connectivity diff --git a/tests/f_badsymlinks/expect.1 b/tests/f_badsymlinks/expect.1 index c9eb717..df187e6 100644 --- a/tests/f_badsymlinks/expect.1 +++ b/tests/f_badsymlinks/expect.1 @@ -1,46 +1,46 @@ Pass 1: Checking inodes, blocks, and sizes Inode 16, i_size is 4294967358, should be 1024. Fix? yes -Special (device/socket/fifo/symlink) file (inode 18) has immutable, -append-only, or dir index flag set. Clear? yes +Special (device/socket/fifo/symlink) file (inode 18) has immutable +or append-only flag set. Clear? yes Inode 19 has illegal block(s). Clear? yes Illegal block #0 (1234567890) in inode 19. CLEARED. Inode 19, i_blocks is 2, should be 0. Fix? yes -Special (device/socket/fifo/symlink) file (inode 20) has immutable, -append-only, or dir index flag set. Clear? yes +Special (device/socket/fifo/symlink) file (inode 20) has immutable +or append-only flag set. Clear? yes Pass 2: Checking directory structure -Symlink /empty_link (inode #17) has an invalid size (0). +Symlink /empty_link (inode #17) is invalid. Clear? yes -Symlink /long_fastlink (inode #13) has an invalid size (59). +Symlink /long_fastlink (inode #13) is invalid. Clear? yes -Symlink /long_link (inode #14) has an invalid size (1023). +Symlink /long_link (inode #14) is invalid. Clear? yes -Symlink /high_fastlink (inode #15) has an invalid size (4294967299). +Symlink /high_fastlink (inode #15) is invalid. Clear? yes -Symlink /high_link (inode #16) has an invalid size (4294968320). +Symlink /high_link (inode #16) is invalid. Clear? yes -Symlink /empty_fastlink (inode #12) has an invalid size (0). +Symlink /empty_fastlink (inode #12) is invalid. Clear? yes -Symlink /bad_link_block (inode #19) has an invalid size (62). +Symlink /bad_link_block (inode #19) is invalid. Clear? yes -Symlink /extra_link_block (inode #21) has an invalid size (62). +Symlink /extra_link_block (inode #21) is invalid. Clear? yes -Symlink /bad_link_size (inode #22) has an invalid size (1024). +Symlink /bad_link_size (inode #22) is invalid. Clear? yes -Symlink /bad_fastlink_size (inode #23) has an invalid size (60). +Symlink /bad_fastlink_size (inode #23) is invalid. Clear? yes Pass 3: Checking directory connectivity diff --git a/tests/f_filetype/expect.1 b/tests/f_filetype/expect.1 index 276a7d1..a94560e 100644 --- a/tests/f_filetype/expect.1 +++ b/tests/f_filetype/expect.1 @@ -1,15 +1,15 @@ Pass 1: Checking inodes, blocks, and sizes -Special (device/socket/fifo/symlink) file (inode 14) has immutable, -append-only, or dir index flag set. Clear? yes +Special (device/socket/fifo/symlink) file (inode 14) has immutable +or append-only flag set. Clear? yes -Special (device/socket/fifo/symlink) file (inode 15) has immutable, -append-only, or dir index flag set. Clear? yes +Special (device/socket/fifo/symlink) file (inode 15) has immutable +or append-only flag set. Clear? yes -Special (device/socket/fifo/symlink) file (inode 16) has immutable, -append-only, or dir index flag set. Clear? yes +Special (device/socket/fifo/symlink) file (inode 16) has immutable +or append-only flag set. Clear? yes -Special (device/socket/fifo/symlink) file (inode 17) has immutable, -append-only, or dir index flag set. Clear? yes +Special (device/socket/fifo/symlink) file (inode 17) has immutable +or append-only flag set. Clear? yes Pass 2: Checking directory structure Setting filetype for entry '.' in / (2) to 2.