Re: [PATCH v2] copy_file_range: limit size if in compat mode

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Aug 13, 2025 at 5:11 PM Miklos Szeredi <mszeredi@xxxxxxxxxx> wrote:
>
> If the process runs in 32-bit compat mode, copy_file_range results can be
> in the in-band error range.  In this case limit copy length to MAX_RW_COUNT
> to prevent a signed overflow.
>
> Reported-by: Florian Weimer <fweimer@xxxxxxxxxx>
> Closes: https://lore.kernel.org/all/lhuh5ynl8z5.fsf@xxxxxxxxxxxxxxxxxxxxxxxx/
> Signed-off-by: Miklos Szeredi <mszeredi@xxxxxxxxxx>

Reviewed-by: Amir Goldstein <amir73il@xxxxxxxxx>

> ---
> v2:
>  - simplified logic (Amir)
>
>  fs/read_write.c | 14 +++++++++-----
>  1 file changed, 9 insertions(+), 5 deletions(-)
>
> diff --git a/fs/read_write.c b/fs/read_write.c
> index c5b6265d984b..833bae068770 100644
> --- a/fs/read_write.c
> +++ b/fs/read_write.c
> @@ -1576,6 +1576,13 @@ ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in,
>         if (len == 0)
>                 return 0;
>
> +       /*
> +        * Make sure return value doesn't overflow in 32bit compat mode.  Also
> +        * limit the size for all cases except when calling ->copy_file_range().
> +        */
> +       if (splice || !file_out->f_op->copy_file_range || in_compat_syscall())
> +               len = min_t(size_t, MAX_RW_COUNT, len);
> +
>         file_start_write(file_out);
>
>         /*
> @@ -1589,9 +1596,7 @@ ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in,
>                                                       len, flags);
>         } else if (!splice && file_in->f_op->remap_file_range && samesb) {
>                 ret = file_in->f_op->remap_file_range(file_in, pos_in,
> -                               file_out, pos_out,
> -                               min_t(loff_t, MAX_RW_COUNT, len),
> -                               REMAP_FILE_CAN_SHORTEN);
> +                               file_out, pos_out, len, REMAP_FILE_CAN_SHORTEN);
>                 /* fallback to splice */
>                 if (ret <= 0)
>                         splice = true;
> @@ -1624,8 +1629,7 @@ ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in,
>          * to splicing from input file, while file_start_write() is held on
>          * the output file on a different sb.
>          */
> -       ret = do_splice_direct(file_in, &pos_in, file_out, &pos_out,
> -                              min_t(size_t, len, MAX_RW_COUNT), 0);
> +       ret = do_splice_direct(file_in, &pos_in, file_out, &pos_out, len, 0);
>  done:
>         if (ret > 0) {
>                 fsnotify_access(file_in);
> --
> 2.49.0
>





[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux