add patch remove-unneeded-test-in-ext4_alloc_file_blocks
[ext4-patch-queue.git] / fix-xattr-shifting-when-expanding-inodes-2
blob9c6b6775eea8d2583386710fd116a2611429116f
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
10 corruption.
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>
15 ---
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
21 --- a/fs/ext4/xattr.c
22 +++ b/fs/ext4/xattr.c
23 @@ -1516,6 +1516,7 @@ retry:
24                 error = ext4_xattr_ibody_set(handle, inode, &i, is);
25                 if (error)
26                         goto cleanup;
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;
44                 i.value = buffer;
45 -- 
46 2.6.6