Skip to content

Commit

Permalink
ext4: fix xattr shifting when expanding inodes part 2
Browse files Browse the repository at this point in the history
When multiple xattrs need to be moved out of inode, we did not properly
recompute total size of xattr headers in the inode and the new header
position. Thus when moving the second and further xattr we asked
ext4_xattr_shift_entries() to move too much and from the wrong place,
resulting in possible xattr value corruption or general memory
corruption.

CC: stable@vger.kernel.org  # 4.4.x
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
  • Loading branch information
Jan Kara authored and Theodore Ts'o committed Aug 11, 2016
1 parent d014119 commit 418c12d
Showing 1 changed file with 3 additions and 2 deletions.
5 changes: 3 additions & 2 deletions fs/ext4/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1516,6 +1516,7 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
error = ext4_xattr_ibody_set(handle, inode, &i, is);
if (error)
goto cleanup;
total_ino -= entry_size;

entry = IFIRST(header);
if (entry_size + EXT4_XATTR_SIZE(size) >= isize_diff)
Expand All @@ -1526,11 +1527,11 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
ext4_xattr_shift_entries(entry, -shift_bytes,
(void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE +
EXT4_I(inode)->i_extra_isize + shift_bytes,
(void *)header, total_ino - entry_size,
inode->i_sb->s_blocksize);
(void *)header, total_ino, inode->i_sb->s_blocksize);

isize_diff -= shift_bytes;
EXT4_I(inode)->i_extra_isize += shift_bytes;
header = IHDR(inode, raw_inode);

i.name = b_entry_name;
i.value = buffer;
Expand Down

0 comments on commit 418c12d

Please sign in to comment.