mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-01-11 17:10:13 +00:00
copy_file_range: limit size if in compat mode
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@redhat.com> Closes: https://lore.kernel.org/all/lhuh5ynl8z5.fsf@oldenburg.str.redhat.com/ Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> Link: https://lore.kernel.org/20250813151107.99856-1-mszeredi@redhat.com Reviewed-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
parent
15769d9478
commit
f8f59a2c05
@ -1576,6 +1576,13 @@ ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in,
|
|||||||
if (len == 0)
|
if (len == 0)
|
||||||
return 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);
|
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);
|
len, flags);
|
||||||
} else if (!splice && file_in->f_op->remap_file_range && samesb) {
|
} else if (!splice && file_in->f_op->remap_file_range && samesb) {
|
||||||
ret = file_in->f_op->remap_file_range(file_in, pos_in,
|
ret = file_in->f_op->remap_file_range(file_in, pos_in,
|
||||||
file_out, pos_out,
|
file_out, pos_out, len, REMAP_FILE_CAN_SHORTEN);
|
||||||
min_t(loff_t, MAX_RW_COUNT, len),
|
|
||||||
REMAP_FILE_CAN_SHORTEN);
|
|
||||||
/* fallback to splice */
|
/* fallback to splice */
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
splice = true;
|
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
|
* to splicing from input file, while file_start_write() is held on
|
||||||
* the output file on a different sb.
|
* the output file on a different sb.
|
||||||
*/
|
*/
|
||||||
ret = do_splice_direct(file_in, &pos_in, file_out, &pos_out,
|
ret = do_splice_direct(file_in, &pos_in, file_out, &pos_out, len, 0);
|
||||||
min_t(size_t, len, MAX_RW_COUNT), 0);
|
|
||||||
done:
|
done:
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
fsnotify_access(file_in);
|
fsnotify_access(file_in);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user