diff options
author | Amir Goldstein <amir73il@gmail.com> | 2023-11-22 15:27:05 +0300 |
---|---|---|
committer | Christian Brauner <brauner@kernel.org> | 2023-11-24 11:22:28 +0300 |
commit | dfad37051ade6ac0d404ef4913f3bd01954ee51c (patch) | |
tree | 4dc2f4ee1ad03043ea4025a20d99cbe09323acb6 /fs/remap_range.c | |
parent | d53471ba6f7ae97a4e223539029528108b705af1 (diff) | |
download | linux-dfad37051ade6ac0d404ef4913f3bd01954ee51c.tar.xz |
remap_range: move permission hooks out of do_clone_file_range()
In many of the vfs helpers, file permission hook is called before
taking sb_start_write(), making them "start-write-safe".
do_clone_file_range() is an exception to this rule.
do_clone_file_range() has two callers - vfs_clone_file_range() and
overlayfs. Move remap_verify_area() checks from do_clone_file_range()
out to vfs_clone_file_range() to make them "start-write-safe".
Overlayfs already has calls to rw_verify_area() with the same security
permission hooks as remap_verify_area() has.
The rest of the checks in remap_verify_area() are irrelevant for
overlayfs that calls do_clone_file_range() offset 0 and positive length.
This is needed for fanotify "pre content" events.
Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Link: https://lore.kernel.org/r/20231122122715.2561213-7-amir73il@gmail.com
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Diffstat (limited to 'fs/remap_range.c')
-rw-r--r-- | fs/remap_range.c | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/fs/remap_range.c b/fs/remap_range.c index 87ae4f0dc3aa..42f79cb2b1b1 100644 --- a/fs/remap_range.c +++ b/fs/remap_range.c @@ -385,14 +385,6 @@ loff_t do_clone_file_range(struct file *file_in, loff_t pos_in, if (!file_in->f_op->remap_file_range) return -EOPNOTSUPP; - ret = remap_verify_area(file_in, pos_in, len, false); - if (ret) - return ret; - - ret = remap_verify_area(file_out, pos_out, len, true); - if (ret) - return ret; - ret = file_in->f_op->remap_file_range(file_in, pos_in, file_out, pos_out, len, remap_flags); if (ret < 0) @@ -410,6 +402,14 @@ loff_t vfs_clone_file_range(struct file *file_in, loff_t pos_in, { loff_t ret; + ret = remap_verify_area(file_in, pos_in, len, false); + if (ret) + return ret; + + ret = remap_verify_area(file_out, pos_out, len, true); + if (ret) + return ret; + file_start_write(file_out); ret = do_clone_file_range(file_in, pos_in, file_out, pos_out, len, remap_flags); |