Whamcloud - gitweb
Add more complete tests for symlinks: nul termination of long links and length
authorAndreas Dilger <adilger@clusterfs.com>
Sat, 18 May 2002 19:16:30 +0000 (13:16 -0600)
committerAndreas Dilger <adilger@clusterfs.com>
Sat, 18 May 2002 19:16:30 +0000 (13:16 -0600)
Improve the f_badsymlinks test case for these new tests.

e2fsck/pass1.c
e2fsck/pass2.c
e2fsck/problem.c
e2fsck/problem.h
tests/ChangeLog
tests/f_badsymlinks/expect.1
tests/f_badsymlinks/expect.2
tests/f_badsymlinks/image.gz
tests/f_badsymlinks/name
tests/f_filetype/expect.1

index d252bb7..1d7b3f8 100644 (file)
@@ -173,15 +173,14 @@ static int strnlen(const char * s, int count)
  */
 int e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode)
 {
+       int len;
        int i;
 
-       if ((inode->i_size_high || inode->i_size == 0) ||
-           (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL |
-                              EXT2_INDEX_FL)))
+       if (inode->i_size_high || inode->i_size == 0)
                return 0;
 
        if (inode->i_blocks) {
-               if ((inode->i_size > fs->blocksize) ||
+               if ((inode->i_size >= fs->blocksize) ||
                    (inode->i_blocks != fs->blocksize >> 9) ||
                    (inode->i_block[0] < fs->super->s_first_data_block) ||
                    (inode->i_block[0] >= fs->super->s_blocks_count))
@@ -190,14 +189,26 @@ int e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode)
                for (i = 1; i < EXT2_N_BLOCKS; i++)
                        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) - 1)
+               if (inode->i_size >= sizeof(inode->i_block))
                        return 0;
 
-               if (inode->i_size !=
-                   strnlen((char *)inode->i_block, sizeof(inode->i_block)))
+               len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
+               if (len == sizeof(inode->i_block))
                        return 0;
        }
+       if (len != inode->i_size)
+               return 0;
        return 1;
 }
 
@@ -205,15 +216,16 @@ 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)
 static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
 {
-       if (!(pctx->inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)))
+       if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
                return;
 
        if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
                return;
 
-       pctx->inode->i_flags &= ~((EXT2_IMMUTABLE_FL | EXT2_APPEND_FL));
+       pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
        e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
 }
 
@@ -1137,7 +1149,7 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
        pb.fragmented = 0;
        pb.compressed = 0;
        pb.previous_block = 0;
-       pb.is_dir = LINUX_S_ISDIR(pctx->inode->i_mode);
+       pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
        pb.inode = inode;
        pb.pctx = pctx;
        pb.ctx = ctx;
@@ -1218,6 +1230,9 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
                            fs->super->s_prealloc_dir_blocks)
                                bad_size = 2;
                }
+       } else if (!LINUX_S_ISREG(inode->i_mode)) {
+               if (inode->i_size_high)
+                       bad_size = 5;
        } else {
                size = inode->i_size | ((__u64) inode->i_size_high << 32);
                if ((size < pb.last_block * fs->blocksize))
@@ -1230,13 +1245,14 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
                pctx->num = (pb.last_block+1) * fs->blocksize;
                if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
                        inode->i_size = pctx->num;
-                       if (!pb.is_dir)
+                       if (LINUX_S_ISREG(inode->i_mode))
                                inode->i_size_high = pctx->num >> 32;
                        e2fsck_write_inode(ctx, ino, inode, "check_blocks");
                }
                pctx->num = 0;
        }
-       if (!pb.is_dir && (inode->i_size_high || inode->i_size & 0x80000000UL))
+       if (LINUX_S_ISREG(inode->i_mode) &&
+           (inode->i_size_high || inode->i_size & 0x80000000UL))
                ctx->large_files++;
        if (pb.num_blocks != inode->i_blocks) {
                pctx->num = pb.num_blocks;
@@ -1342,7 +1358,7 @@ static int process_block(ext2_filsys fs,
                   perhaps this really is just an illegal block. */
                return 0;
        }
-       
+
        if (blk == 0) {
                if (p->is_dir == 0) {
                        /*
index e424eb5..19a682a 100644 (file)
@@ -675,7 +675,7 @@ static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
        if (!ext2fs_inode_has_valid_blocks(&inode))
                return;
 
-       if (!LINUX_S_ISDIR(inode.i_mode) &&
+       if (LINUX_S_ISREG(inode.i_mode) &&
            (inode.i_size_high || inode.i_size & 0x80000000UL))
                ctx->large_files--;
 
index 7f6cc02..126d9d5 100644 (file)
@@ -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"
-            "or append-only flag set.  "),
+         N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable,\n"
+            "append-only, or dir index 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 */
@@ -643,8 +643,8 @@ static const struct e2fsck_problem problem_table[] = {
        /* Bad extended attribute value */
        { PR_1_EA_BAD_VALUE,
          N_("@a @b %b is corrupt (invalid value).  "),
-         PROMPT_CLEAR, 0},       
-                 
+         PROMPT_CLEAR, 0},
+
        /* Pass 1b errors */
 
        /* Pass 1B: Rescan for duplicate/bad blocks */
@@ -949,7 +949,7 @@ static const struct e2fsck_problem problem_table[] = {
          N_("@E has a zero-length name.\n"),
          PROMPT_CLEAR, 0 },
 
-       /* Invalid fast symlink size */
+       /* Invalid symlink size */
        { PR_2_SYMLINK_SIZE,
          N_("Symlink %Q (@i #%i) has an invalid size (%Is).\n"),
          PROMPT_CLEAR, 0 },
index 89bd5b4..666b893 100644 (file)
@@ -362,16 +362,16 @@ struct problem_context {
 
 /* Error allocating EA region allocation structure */
 #define PR_1_EA_ALLOC_REGION           0x01003F
-       
+
 /* Error EA allocation collision */
 #define PR_1_EA_ALLOC_COLLISION                0x010040
-       
+
 /* Bad extended attribute name */
 #define PR_1_EA_BAD_NAME               0x010041
 
 /* Bad extended attribute value */
-#define PR_1_EA_BAD_VALUE              0x0100423
-       
+#define PR_1_EA_BAD_VALUE              0x010042
+
 /*
  * Pass 1b errors
  */
@@ -562,7 +562,7 @@ struct problem_context {
 /* Directory filename can't be zero-length  */
 #define PR_2_NULL_NAME         0x020030
 
-/* Invalid fast symlink size */
+/* Invalid symlink size */
 #define PR_2_SYMLINK_SIZE      0x020031
 
 /* i_file_acl (extended attribute) is bad */
index deac0d4..717c2bf 100644 (file)
@@ -1,3 +1,11 @@
+2002-05-18  Andreas Dilger  <adilger@clusterfs.com>
+
+       * f_badsymlink: Add extra length checks for symlinks
+               - missing nul termination test (new)
+               - nul terminated but i_size is wrong
+               - i_size == maximum size (no space for nul, new)
+               - too many blocks for long symlink
+
 2002-03-08  Theodore Tso  <tytso@mit.edu>
 
        * Release of E2fsprogs 1.27
index 203d9ae..c9eb717 100644 (file)
@@ -1,53 +1,64 @@
 Pass 1: Checking inodes, blocks, and sizes
-Special (device/socket/fifo/symlink) file (inode 18) has immutable
-or append-only flag set.  Clear? yes
+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
 
 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
-or append-only flag set.  Clear? yes
+Special (device/socket/fifo/symlink) file (inode 20) has immutable,
+append-only, or dir index flag set.  Clear? yes
 
 Pass 2: Checking directory structure
 Symlink /empty_link (inode #17) has an invalid size (0).
 Clear? yes
 
-Symlink /long_fastlink (inode #13) has an invalid size (99).
+Symlink /long_fastlink (inode #13) has an invalid size (59).
+Clear? yes
+
+Symlink /long_link (inode #14) has an invalid size (1023).
 Clear? yes
 
-Symlink /long_link (inode #14) has an invalid size (1234567890).
+Symlink /high_fastlink (inode #15) has an invalid size (4294967299).
 Clear? yes
 
-Symlink /high_link (inode #16) has an invalid size (4294967358).
+Symlink /high_link (inode #16) has an invalid size (4294968320).
 Clear? yes
 
 Symlink /empty_fastlink (inode #12) has an invalid size (0).
 Clear? yes
 
-Symlink /bad_link (inode #19) has an invalid size (62).
+Symlink /bad_link_block (inode #19) has an invalid size (62).
+Clear? yes
+
+Symlink /extra_link_block (inode #21) has an invalid size (62).
+Clear? yes
+
+Symlink /bad_link_size (inode #22) has an invalid size (1024).
+Clear? yes
+
+Symlink /bad_fastlink_size (inode #23) has an invalid size (60).
 Clear? yes
 
 Pass 3: Checking directory connectivity
 Pass 4: Checking reference counts
 Pass 5: Checking group summary information
-Block bitmap differences:  -26
-Fix? yes
-
-Free blocks count wrong for group #0 (997, counted=1001).
+Free blocks count wrong for group #0 (995, counted=1001).
 Fix? yes
 
-Free blocks count wrong (997, counted=1001).
+Free blocks count wrong (995, counted=1001).
 Fix? yes
 
-Free inodes count wrong for group #0 (12, counted=18).
+Free inodes count wrong for group #0 (9, counted=19).
 Fix? yes
 
-Free inodes count wrong (12, counted=18).
+Free inodes count wrong (9, counted=19).
 Fix? yes
 
 
 test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 14/32 files (0.0% non-contiguous), 23/1024 blocks
+test_filesys: 13/32 files (7.7% non-contiguous), 23/1024 blocks
 Exit status is 1
index 6dbd393..1499551 100644 (file)
@@ -3,5 +3,5 @@ Pass 2: Checking directory structure
 Pass 3: Checking directory connectivity
 Pass 4: Checking reference counts
 Pass 5: Checking group summary information
-test_filesys: 14/32 files (0.0% non-contiguous), 23/1024 blocks
+test_filesys: 13/32 files (0.0% non-contiguous), 23/1024 blocks
 Exit status is 0
index 743163f..4ebacde 100644 (file)
Binary files a/tests/f_badsymlinks/image.gz and b/tests/f_badsymlinks/image.gz differ
index 51c8224..630858f 100644 (file)
@@ -1 +1 @@
-corrupted fast symlinks
+corrupted symlinks
index a94560e..276a7d1 100644 (file)
@@ -1,15 +1,15 @@
 Pass 1: Checking inodes, blocks, and sizes
-Special (device/socket/fifo/symlink) file (inode 14) has immutable
-or append-only flag set.  Clear? yes
+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 15) 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 16) 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 17) 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
 
 Pass 2: Checking directory structure
 Setting filetype for entry '.' in / (2) to 2.