From 039f4a704992d42e2d587231beb7c8a2fc752f37 Mon Sep 17 00:00:00 2001 From: Yuezhang Mo Date: Tue, 11 Mar 2025 08:51:19 +0900 Subject: [PATCH] exfat: fix file being changed by unaligned direct write BugLink: https://bugs.launchpad.net/bugs/2101915 [ Upstream commit 2e94e5bb94a3e641a25716a560bf474225fda83c ] Unaligned direct writes are invalid and should return an error without making any changes, rather than extending ->valid_size and then returning an error. Therefore, alignment checking is required before extending ->valid_size. Fixes: 11a347fb6cef ("exfat: change to get file size from DataLength") Signed-off-by: Yuezhang Mo Co-developed-by: Namjae Jeon Signed-off-by: Namjae Jeon Signed-off-by: Sasha Levin Signed-off-by: Koichiro Den Signed-off-by: Stefan Bader --- fs/exfat/file.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/fs/exfat/file.c b/fs/exfat/file.c index 9adfc38ca7da..ed7e1257399c 100644 --- a/fs/exfat/file.c +++ b/fs/exfat/file.c @@ -574,6 +574,16 @@ static ssize_t exfat_file_write_iter(struct kiocb *iocb, struct iov_iter *iter) if (ret < 0) goto unlock; + if (iocb->ki_flags & IOCB_DIRECT) { + unsigned long align = pos | iov_iter_alignment(iter); + + if (!IS_ALIGNED(align, i_blocksize(inode)) && + !IS_ALIGNED(align, bdev_logical_block_size(inode->i_sb->s_bdev))) { + ret = -EINVAL; + goto unlock; + } + } + if (pos > valid_size) { ret = exfat_file_zeroed_range(file, valid_size, pos); if (ret < 0 && ret != -ENOSPC) {