All of lore.kernel.org
 help / color / mirror / Atom feed
From: Amir Goldstein <amir73il@gmail.com>
To: Christian Brauner <brauner@kernel.org>
Cc: Jeff Layton <jlayton@kernel.org>,
	Josef Bacik <josef@toxicpanda.com>,
	Christoph Hellwig <hch@lst.de>, Jan Kara <jack@suse.cz>,
	David Howells <dhowells@redhat.com>, Jens Axboe <axboe@kernel.dk>,
	Miklos Szeredi <miklos@szeredi.hu>,
	Al Viro <viro@zeniv.linux.org.uk>,
	linux-fsdevel@vger.kernel.org
Subject: [PATCH v2 2/3] fs: move file_start_write() into direct_splice_actor()
Date: Thu, 30 Nov 2023 16:16:23 +0200	[thread overview]
Message-ID: <20231130141624.3338942-3-amir73il@gmail.com> (raw)
In-Reply-To: <20231130141624.3338942-1-amir73il@gmail.com>

The callers of do_splice_direct() hold file_start_write() on the output
file.

This may cause file permission hooks to be called indirectly on an
overlayfs lower layer, which is on the same filesystem of the output
file and could lead to deadlock with fanotify permission events.

To fix this potential deadlock, move file_start_write() from the callers
into the direct_splice_actor(), so file_start_write() will not be held
while splicing from the input file.

Suggested-by: Josef Bacik <josef@toxicpanda.com>
Link: https://lore.kernel.org/r/20231128214258.GA2398475@perftesting/
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/overlayfs/copy_up.c |  2 --
 fs/read_write.c        |  2 --
 fs/splice.c            | 19 ++++++++++++++++---
 3 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
index 7a44c8212331..294b330aba9f 100644
--- a/fs/overlayfs/copy_up.c
+++ b/fs/overlayfs/copy_up.c
@@ -333,11 +333,9 @@ static int ovl_copy_up_file(struct ovl_fs *ofs, struct dentry *dentry,
 		if (error)
 			break;
 
-		ovl_start_write(dentry);
 		bytes = do_splice_direct(old_file, &old_pos,
 					 new_file, &new_pos,
 					 this_len, SPLICE_F_MOVE);
-		ovl_end_write(dentry);
 		if (bytes <= 0) {
 			error = bytes;
 			break;
diff --git a/fs/read_write.c b/fs/read_write.c
index 642c7ce1ced1..0bc99f38e623 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -1286,10 +1286,8 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
 		retval = rw_verify_area(WRITE, out.file, &out_pos, count);
 		if (retval < 0)
 			goto fput_out;
-		file_start_write(out.file);
 		retval = do_splice_direct(in.file, &pos, out.file, &out_pos,
 					  count, fl);
-		file_end_write(out.file);
 	} else {
 		if (out.file->f_flags & O_NONBLOCK)
 			fl |= SPLICE_F_NONBLOCK;
diff --git a/fs/splice.c b/fs/splice.c
index 9007b2c8baa8..7cda013e5a1e 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -1157,9 +1157,20 @@ static int direct_splice_actor(struct pipe_inode_info *pipe,
 			       struct splice_desc *sd)
 {
 	struct file *file = sd->u.file;
+	long ret;
+
+	file_start_write(file);
+	ret = do_splice_from(pipe, file, sd->opos, sd->total_len, sd->flags);
+	file_end_write(file);
+	return ret;
+}
 
-	return do_splice_from(pipe, file, sd->opos, sd->total_len,
-			      sd->flags);
+static int splice_file_range_actor(struct pipe_inode_info *pipe,
+					struct splice_desc *sd)
+{
+	struct file *file = sd->u.file;
+
+	return do_splice_from(pipe, file, sd->opos, sd->total_len, sd->flags);
 }
 
 static void direct_file_splice_eof(struct splice_desc *sd)
@@ -1233,6 +1244,8 @@ EXPORT_SYMBOL(do_splice_direct);
  *
  * Description:
  *    For use by generic_copy_file_range() and ->copy_file_range() methods.
+ *    Like do_splice_direct(), but vfs_copy_file_range() already holds
+ *    start_file_write() on @out file.
  *
  * Callers already called rw_verify_area() on the entire range.
  */
@@ -1242,7 +1255,7 @@ long splice_file_range(struct file *in, loff_t *ppos, struct file *out,
 	lockdep_assert(file_write_started(out));
 
 	return do_splice_direct_actor(in, ppos, out, opos, len, 0,
-				      direct_splice_actor);
+				      splice_file_range_actor);
 }
 EXPORT_SYMBOL(splice_file_range);
 
-- 
2.34.1


  parent reply	other threads:[~2023-11-30 14:16 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-30 14:16 [PATCH v2 0/3] Avert possible deadlock with splice() and fanotify Amir Goldstein
2023-11-30 14:16 ` [PATCH v2 1/3] fs: fork splice_file_range() from do_splice_direct() Amir Goldstein
2023-11-30 16:27   ` Jeff Layton
2023-12-04  8:37   ` Christoph Hellwig
2023-12-04  8:38     ` Christoph Hellwig
2023-12-04 13:29       ` Amir Goldstein
2023-12-04 14:07         ` Christoph Hellwig
2023-12-04 14:29           ` Amir Goldstein
2023-12-04 17:16             ` Jan Kara
2023-12-04 18:53               ` Amir Goldstein
2023-11-30 14:16 ` Amir Goldstein [this message]
2023-12-04  8:38   ` [PATCH v2 2/3] fs: move file_start_write() into direct_splice_actor() Christoph Hellwig
2023-11-30 14:16 ` [PATCH v2 3/3] fs: use do_splice_direct() for nfsd/ksmbd server-side-copy Amir Goldstein
2023-11-30 16:49   ` Jan Kara
2023-12-04  8:39   ` Christoph Hellwig
2023-12-04 13:19     ` Amir Goldstein
2023-12-04 14:02       ` Christoph Hellwig
2023-12-05  0:16   ` [PATCH] fs: read_write: make default in vfs_copy_file_range() reachable Bert Karwatzki
2023-12-05  3:45     ` Amir Goldstein
2023-12-05  5:01       ` Amir Goldstein
2023-12-05  9:50         ` Bert Karwatzki
2023-11-30 16:32 ` [PATCH v2 0/3] Avert possible deadlock with splice() and fanotify Jeff Layton
2023-12-01 10:40 ` Christian Brauner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231130141624.3338942-3-amir73il@gmail.com \
    --to=amir73il@gmail.com \
    --cc=axboe@kernel.dk \
    --cc=brauner@kernel.org \
    --cc=dhowells@redhat.com \
    --cc=hch@lst.de \
    --cc=jack@suse.cz \
    --cc=jlayton@kernel.org \
    --cc=josef@toxicpanda.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.