Whamcloud - gitweb
e2fsck: enforce that extra_isize must be a multiple of four
authorTheodore Ts'o <tytso@mit.edu>
Sun, 4 Sep 2016 20:29:12 +0000 (16:29 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Sun, 4 Sep 2016 20:34:49 +0000 (16:34 -0400)
We need to prevent unaligned accesses, so treat any extra_isize which
is not a multiple of four as an bug.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
e2fsck/pass1.c
lib/ext2fs/ext2_err.et.in
lib/ext2fs/ext_attr.c
tests/f_write_ea_toobig_extra_isize/expect.1

index da0ddf4..ac4d554 100644 (file)
@@ -488,10 +488,14 @@ static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
         * implementations should never allow i_extra_isize to be 0
         */
        if (inode->i_extra_isize &&
-           (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
+           (inode->i_extra_isize < min || inode->i_extra_isize > max ||
+            inode->i_extra_isize & 3)) {
                if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
                        return;
-               inode->i_extra_isize = min;
+               if (inode->i_extra_isize < min || inode->i_extra_isize > max)
+                       inode->i_extra_isize = sb->s_want_extra_isize;
+               else
+                       inode->i_extra_isize = (inode->i_extra_isize + 3) & ~3;
                e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
                                        EXT2_INODE_SIZE(sb), "pass1");
                return;
index 2a109ca..ac96964 100644 (file)
@@ -539,4 +539,7 @@ ec  EXT2_ET_BAD_CRC,
 ec     EXT2_ET_CORRUPT_JOURNAL_SB,
        "The journal superblock is corrupt"
 
+ec     EXT2_ET_INODE_CORRUPTED,
+       "Inode is corrupted"
+
        end
index b121837..e8fd10c 100644 (file)
@@ -554,6 +554,10 @@ errcode_t ext2fs_xattrs_write(struct ext2_xattr_handle *handle)
                memset(p + EXT2_GOOD_OLD_INODE_SIZE, 0, extra);
                inode->i_extra_isize = extra;
        }
+       if (inode->i_extra_isize & 3) {
+               err = EXT2_ET_INODE_CORRUPTED;
+               goto out;
+       }
 
        /*
         * Force the inlinedata attr to the front and the empty entries
@@ -806,6 +810,10 @@ errcode_t ext2fs_xattrs_read(struct ext2_xattr_handle *handle)
                                                  inode->i_extra_isize +
                                                  sizeof(__u32))
                goto read_ea_block;
+       if (inode->i_extra_isize & 3) {
+               err = EXT2_ET_INODE_CORRUPTED;
+               goto out;
+       }
 
        /* Look for EA in the inode */
        memcpy(&ea_inode_magic, ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
index b7e7438..4aa86ac 100644 (file)
@@ -1,4 +1,7 @@
 Pass 1: Checking inodes, blocks, and sizes
+Inode 12 has a extra size (126) which is invalid
+Fix? yes
+
 Pass 2: Checking directory structure
 Directory inode 12, block #0, offset 4: directory corrupted
 Salvage? yes