]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
exfat: fix file being changed by unaligned direct write
authorYuezhang Mo <Yuezhang.Mo@sony.com>
Thu, 17 Oct 2024 01:25:06 +0000 (09:25 +0800)
committerNamjae Jeon <linkinjeon@kernel.org>
Mon, 25 Nov 2024 08:08:21 +0000 (17:08 +0900)
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>
fs/exfat/file.c

index a25d7eb789f4cbe96343aaa8e93589fa229175d6..fb38769c3e39d1456b95dae2aca6b4ea7bc3d22b 100644 (file)
@@ -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) {