1 ext4: fix xattr shifting when expanding inodes part 2
3 From: Jan Kara <jack@suse.cz>
5 When multiple xattrs need to be moved out of inode, we did not properly
6 recompute total size of xattr headers in the inode and the new header
7 position. Thus when moving the second and further xattr we asked
8 ext4_xattr_shift_entries() to move too much and from the wrong place,
9 resulting in possible xattr value corruption or general memory
12 CC: stable@vger.kernel.org # 4.4.x
13 Signed-off-by: Jan Kara <jack@suse.cz>
14 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
16 fs/ext4/xattr.c | 5 +++--
17 1 file changed, 3 insertions(+), 2 deletions(-)
19 diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
20 index cb1d7b4482de..b18b1ff7cc27 100644
23 @@ -1516,6 +1516,7 @@ retry:
24 error = ext4_xattr_ibody_set(handle, inode, &i, is);
27 + total_ino -= entry_size;
29 entry = IFIRST(header);
30 if (entry_size + EXT4_XATTR_SIZE(size) >= isize_diff)
31 @@ -1526,11 +1527,11 @@ retry:
32 ext4_xattr_shift_entries(entry, -shift_bytes,
33 (void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE +
34 EXT4_I(inode)->i_extra_isize + shift_bytes,
35 - (void *)header, total_ino - entry_size,
36 - inode->i_sb->s_blocksize);
37 + (void *)header, total_ino, inode->i_sb->s_blocksize);
39 isize_diff -= shift_bytes;
40 EXT4_I(inode)->i_extra_isize += shift_bytes;
41 + header = IHDR(inode, raw_inode);
43 i.name = b_entry_name;