summaryrefslogtreecommitdiffstats
path: root/fs/exfat
diff options
context:
space:
mode:
authorYuezhang Mo <Yuezhang.Mo@sony.com>2024-10-17 03:25:06 +0200
committerNamjae Jeon <linkinjeon@kernel.org>2024-11-25 09:08:21 +0100
commit2e94e5bb94a3e641a25716a560bf474225fda83c (patch)
tree64be23a3cde0912aab6fdd267c208e9dc22d6cbb /fs/exfat
parentexfat: fix uninit-value in __exfat_get_dentry_set (diff)
downloadlinux-2e94e5bb94a3e641a25716a560bf474225fda83c.tar.xz
linux-2e94e5bb94a3e641a25716a560bf474225fda83c.zip
exfat: fix file being changed by unaligned direct write
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 <Yuezhang.Mo@sony.com> Co-developed-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Diffstat (limited to 'fs/exfat')
-rw-r--r--fs/exfat/file.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/fs/exfat/file.c b/fs/exfat/file.c
index a25d7eb789f4..fb38769c3e39 100644
--- a/fs/exfat/file.c
+++ b/fs/exfat/file.c
@@ -584,6 +584,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_extend_valid_size(file, pos);
if (ret < 0 && ret != -ENOSPC) {