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@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=d31a3b77e5cba96b9f69 Tested-by: syzbot+d31a3b77e5cba96b9f69@syzkaller.appspotmail.com Signed-off-by: Deepanshu Kartikey --- 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