From: Darrick J. Wong Date: Tue, 27 Jan 2015 15:59:19 +0000 (-0500) Subject: libext2fs: initialize i_extra_isize when writing EAs X-Git-Tag: v1.43-WIP-2015-05-18~91 X-Git-Url: https://git.whamcloud.com/gitweb?a=commitdiff_plain;h=366d299fe73f6e93b4182ed65d72d26705a378da;p=tools%2Fe2fsprogs.git libext2fs: initialize i_extra_isize when writing EAs If i_extra_isize is zero when we try to write extended attributes, we'll end up writing the EA magic into the i_extra_isize field, which causes a subsequent crash on big endian systems (when we try to write 0xEA02 bytes past the inode!). Therefore when the field is zero, set i_extra_isize to the desired extra_isize size, zero those bytes, and write the EAs after the end of the extended inode. v2: Don't bother if we have 128b inodes, and ensure that the value is 32b-aligned so that the EA magic starts on a 32b boundary. Signed-off-by: Darrick J. Wong Signed-off-by: Theodore Ts'o --- diff --git a/lib/ext2fs/ext_attr.c b/lib/ext2fs/ext_attr.c index 70bc3f9..c6fcf54 100644 --- a/lib/ext2fs/ext_attr.c +++ b/lib/ext2fs/ext_attr.c @@ -519,6 +519,18 @@ errcode_t ext2fs_xattrs_write(struct ext2_xattr_handle *handle) if (err) goto out; + /* If extra_isize isn't set, we need to set it now */ + if (inode->i_extra_isize == 0 && + EXT2_INODE_SIZE(handle->fs->super) > EXT2_GOOD_OLD_INODE_SIZE) { + char *p = (char *)inode; + size_t extra = handle->fs->super->s_want_extra_isize; + + if (extra == 0) + extra = sizeof(__u32); + memset(p + EXT2_GOOD_OLD_INODE_SIZE, 0, extra); + inode->i_extra_isize = extra; + } + move_inline_data_to_front(handle); x = handle->attrs; diff --git a/tests/f_write_ea_no_extra_isize/expect.1 b/tests/f_write_ea_no_extra_isize/expect.1 new file mode 100644 index 0000000..b7e7438 --- /dev/null +++ b/tests/f_write_ea_no_extra_isize/expect.1 @@ -0,0 +1,12 @@ +Pass 1: Checking inodes, blocks, and sizes +Pass 2: Checking directory structure +Directory inode 12, block #0, offset 4: directory corrupted +Salvage? yes + +Pass 3: Checking directory connectivity +Pass 4: Checking reference counts +Pass 5: Checking group summary information + +test_filesys: ***** FILE SYSTEM WAS MODIFIED ***** +test_filesys: 12/128 files (0.0% non-contiguous), 17/512 blocks +Exit status is 1 diff --git a/tests/f_write_ea_no_extra_isize/expect.2 b/tests/f_write_ea_no_extra_isize/expect.2 new file mode 100644 index 0000000..3b6073e --- /dev/null +++ b/tests/f_write_ea_no_extra_isize/expect.2 @@ -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: 12/128 files (0.0% non-contiguous), 17/512 blocks +Exit status is 0 diff --git a/tests/f_write_ea_no_extra_isize/image.gz b/tests/f_write_ea_no_extra_isize/image.gz new file mode 100644 index 0000000..928daff Binary files /dev/null and b/tests/f_write_ea_no_extra_isize/image.gz differ diff --git a/tests/f_write_ea_no_extra_isize/name b/tests/f_write_ea_no_extra_isize/name new file mode 100644 index 0000000..200e365 --- /dev/null +++ b/tests/f_write_ea_no_extra_isize/name @@ -0,0 +1 @@ +write EA when i_extra_size is zero