]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
e2fsck: enforce that the extra isize fields in the superblock are sane
authorTheodore Ts'o <tytso@mit.edu>
Sun, 4 Sep 2016 21:31:07 +0000 (17:31 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Sun, 4 Sep 2016 21:41:20 +0000 (17:41 -0400)
Invalid extra isize fields can cause crashes in e2fsprogs and possibly
in the kernel for some architectures due to unaligned accesses.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
e2fsck/problem.c
e2fsck/problem.h
e2fsck/super.c
tests/f_sb_extra_isize/expect.1 [new file with mode: 0644]
tests/f_sb_extra_isize/expect.2 [new file with mode: 0644]
tests/f_sb_extra_isize/image.gz [new file with mode: 0644]
tests/f_sb_extra_isize/name [new file with mode: 0644]

index ff91abd93d8ee4b179c458a61ce618d3ea84fe33..34a671e582ccdc8735ea39ad9da4681b3583059f 100644 (file)
@@ -477,6 +477,16 @@ static struct e2fsck_problem problem_table[] = {
          N_("Error initializing quota context in support library: %m\n"),
          PROMPT_NULL, PR_FATAL },
 
+       /* Bad s_min_extra_isize in superblock */
+       { PR_0_BAD_MIN_EXTRA_ISIZE,
+         N_("Bad required extra isize in @S (%N).  "),
+         PROMPT_FIX, 0 },
+
+       /* Bad s_min_extra_isize in superblock */
+       { PR_0_BAD_WANT_EXTRA_ISIZE,
+         N_("Bad desired extra isize in @S (%N).  "),
+         PROMPT_FIX, 0 },
+
        /* Pass 1 errors */
 
        /* Pass 1: Checking inodes, blocks, and sizes */
index fad05c5624ca70cea1a9ead49713f11e5112bd5d..86cb61444b71255fa47ae8faf04afcefa776d43b 100644 (file)
@@ -274,6 +274,12 @@ struct problem_context {
 /* Error initializing quota context */
 #define PR_0_QUOTA_INIT_CTX                    0x00004C
 
+/* Bad s_min_extra_isize in superblock */
+#define PR_0_BAD_MIN_EXTRA_ISIZE               0x00004D
+
+/* Bad s_want_extra_isize in superblock */
+#define PR_0_BAD_WANT_EXTRA_ISIZE              0x00004E
+
 
 /*
  * Pass 1 errors
index dec70bd46b012fe03e6821df322349f184d856f4..d2fd92253c22f91f483ea2979983726adb1bcb22 100644 (file)
@@ -578,7 +578,35 @@ void check_super_block(e2fsck_t ctx)
                        ext2fs_mark_super_dirty(fs);
                }
        }
-
+       if (EXT2_INODE_SIZE(sb) > EXT2_GOOD_OLD_INODE_SIZE) {
+               unsigned min =
+                       sizeof(((struct ext2_inode_large *) 0)->i_extra_isize) +
+                       sizeof(((struct ext2_inode_large *) 0)->i_checksum_hi);
+               unsigned max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
+               pctx.num = sb->s_min_extra_isize;
+               if (sb->s_min_extra_isize &&
+                   (sb->s_min_extra_isize < min ||
+                    sb->s_min_extra_isize > max ||
+                    sb->s_min_extra_isize & 3) &&
+                   fix_problem(ctx, PR_0_BAD_MIN_EXTRA_ISIZE, &pctx)) {
+                       sb->s_min_extra_isize =
+                               (sizeof(struct ext2_inode_large) -
+                                EXT2_GOOD_OLD_INODE_SIZE);
+                       ext2fs_mark_super_dirty(fs);
+               }
+               pctx.num = sb->s_want_extra_isize;
+               if (sb->s_want_extra_isize &&
+                   (sb->s_want_extra_isize < min ||
+                    sb->s_want_extra_isize > max ||
+                    sb->s_want_extra_isize & 3) &&
+                   fix_problem(ctx, PR_0_BAD_WANT_EXTRA_ISIZE, &pctx)) {
+                       sb->s_want_extra_isize =
+                               (sizeof(struct ext2_inode_large) -
+                                EXT2_GOOD_OLD_INODE_SIZE);
+                       ext2fs_mark_super_dirty(fs);
+               }
+       }
+                   
        /* Are metadata_csum and uninit_bg both set? */
        if (ext2fs_has_feature_metadata_csum(fs->super) &&
            ext2fs_has_feature_gdt_csum(fs->super) &&
diff --git a/tests/f_sb_extra_isize/expect.1 b/tests/f_sb_extra_isize/expect.1
new file mode 100644 (file)
index 0000000..75e239b
--- /dev/null
@@ -0,0 +1,13 @@
+Bad required extra isize in superblock (1).  Fix? yes
+
+Bad desired extra isize in superblock (1024).  Fix? yes
+
+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: ***** FILE SYSTEM WAS MODIFIED *****
+test_filesys: 11/32 files (0.0% non-contiguous), 28/200 blocks
+Exit status is 1
diff --git a/tests/f_sb_extra_isize/expect.2 b/tests/f_sb_extra_isize/expect.2
new file mode 100644 (file)
index 0000000..c7e0e5f
--- /dev/null
@@ -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: 11/32 files (0.0% non-contiguous), 28/200 blocks
+Exit status is 0
diff --git a/tests/f_sb_extra_isize/image.gz b/tests/f_sb_extra_isize/image.gz
new file mode 100644 (file)
index 0000000..a7cb827
Binary files /dev/null and b/tests/f_sb_extra_isize/image.gz differ
diff --git a/tests/f_sb_extra_isize/name b/tests/f_sb_extra_isize/name
new file mode 100644 (file)
index 0000000..45bab4f
--- /dev/null
@@ -0,0 +1 @@
+check invalid extra_isize fields in superblock