Re: [PATCH] splice: prevent deadlock when splicing a file to itself
From: Christian Brauner
Date: Tue Mar 31 2026 - 05:40:59 EST
On Fri, Mar 20, 2026 at 06:36:15PM +0530, Deepanshu Kartikey wrote:
>
> When do_splice_direct_actor() is called with the same inode
> for both input and output files (either via the same fd or a
> dup'd fd), it causes a hung task in blkdev_write_iter().
>
> The deadlock occurs because sendfile() calls do_splice_direct()
> which tries to acquire inode_lock_shared() for reading, while
> the write side already holds the same inode lock, causing the
> task to block indefinitely in rwsem_down_read_slowpath().
>
> Fix this by checking if the input and output files share the
> same inode before proceeding, returning -EINVAL if they do.
> This mirrors the existing check in do_splice() for the
> pipe-to-pipe case where ipipe == opipe.
>
> Reported-by: syzbot+d31a3b77e5cba96b9f69@xxxxxxxxxxxxxxxxxxxxxxxxx
> Closes: https://syzkaller.appspot.com/bug?extid=d31a3b77e5cba96b9f69
> Tested-by: syzbot+d31a3b77e5cba96b9f69@xxxxxxxxxxxxxxxxxxxxxxxxx
> Signed-off-by: Deepanshu Kartikey <Kartikey406@xxxxxxxxx>
> ---
@Jens?
> fs/splice.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/fs/splice.c b/fs/splice.c
> index 9d8f63e2fd1a..c0ad1859de34 100644
> --- a/fs/splice.c
> +++ b/fs/splice.c
> @@ -1199,6 +1199,9 @@ static ssize_t do_splice_direct_actor(struct file *in, loff_t *ppos,
> if (unlikely(out->f_flags & O_APPEND))
> return -EINVAL;
>
> + /* Prevent deadlock when splicing a file to itself */
> + if (file_inode(in) == file_inode(out))
> + return -EINVAL;
> ret = splice_direct_to_actor(in, &sd, actor);
> if (ret > 0)
> *ppos = sd.pos;
> --
> 2.43.0
>