]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
remap_range: move permission hooks out of do_clone_file_range()
authorAmir Goldstein <amir73il@gmail.com>
Wed, 22 Nov 2023 12:27:05 +0000 (14:27 +0200)
committerChristian Brauner <brauner@kernel.org>
Fri, 24 Nov 2023 08:22:28 +0000 (09:22 +0100)
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>
fs/remap_range.c

index 87ae4f0dc3aa01c6099ef2fa7a66b5d84bdb9703..42f79cb2b1b1f5b0235c3b8aa1c0e64f1a5668f1 100644 (file)
@@ -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);