hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I9VTE3 CVE: NA
--------------------------------
Now xfs_itruncate_extents() unmap extsize aligned extents for forcealign, when unaligned truncating down a forceflign file which extsize is bigger than one block, xfs_truncate_page() only zeros out the tail EOF block, this could expose stale data.
If we truncate file that contains a large enough written extent:
|< ext >|< ext >| ...WWWWWWWWWWWWWWWWWWWWWzzzzzzzzzzzz ^ (new EOF) ^ old EOF
Since we only zeros out the tail of the EOF block, and xfs_itruncate_extents() unmap the whole ailgned extents, it becomes this state:
|< ext >| ...WWWzWWWWWWWWWWWWW ^ new EOF
Then if we do an extending write like this, the blocks in the previous tail extent becomes stale:
|< ext >| |< ext >| ...WWWzSSSSSSSSSSSSS......WWWWWWWWWWWzzzzzz ^ old EOF ^ append start ^ new EOF
Fix this by zeroing out the tail allocation uint for forcealign.
Signed-off-by: Long Li leo.lilong@huawei.com --- fs/xfs/xfs_iops.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 092fb02d1a13..0640fc666d83 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -769,7 +769,7 @@ xfs_setattr_size( int error; uint lock_flags = 0; bool did_zeroing = false; - unsigned int blocksize = i_blocksize(inode); + unsigned int blocksize = 0;
ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); ASSERT(xfs_isilocked(ip, XFS_MMAPLOCK_EXCL)); @@ -777,6 +777,11 @@ xfs_setattr_size( ASSERT((iattr->ia_valid & (ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET| ATTR_MTIME_SET|ATTR_TIMES_SET)) == 0);
+ if (xfs_inode_forcealign(ip) && ip->i_d.di_extsize > 1) + blocksize = ip->i_d.di_extsize; + else + blocksize = i_blocksize(inode); + oldsize = inode->i_size; newsize = iattr->ia_size;