diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index da0ddf48..ac4d5544 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -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; diff --git a/lib/ext2fs/ext2_err.et.in b/lib/ext2fs/ext2_err.et.in index 2a109ca3..ac96964d 100644 --- a/lib/ext2fs/ext2_err.et.in +++ b/lib/ext2fs/ext2_err.et.in @@ -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 diff --git a/lib/ext2fs/ext_attr.c b/lib/ext2fs/ext_attr.c index b121837d..e8fd10c2 100644 --- a/lib/ext2fs/ext_attr.c +++ b/lib/ext2fs/ext_attr.c @@ -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 + diff --git a/tests/f_write_ea_toobig_extra_isize/expect.1 b/tests/f_write_ea_toobig_extra_isize/expect.1 index b7e7438e..4aa86ac6 100644 --- a/tests/f_write_ea_toobig_extra_isize/expect.1 +++ b/tests/f_write_ea_toobig_extra_isize/expect.1 @@ -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