Forwarded: [PATCH] splice: prevent deadlock when splicing a file to itself

syzbot posted 1 patch 2 weeks ago
fs/splice.c | 3 +++
1 file changed, 3 insertions(+)
Forwarded: [PATCH] splice: prevent deadlock when splicing a file to itself
Posted by syzbot 2 weeks ago
For archival purposes, forwarding an incoming command email to
linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com.

***

Subject: [PATCH] splice: prevent deadlock when splicing a file to itself
Author: kartikey406@gmail.com

#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master


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
Signed-off-by: Deepanshu Kartikey <Kartikey406@gmail.com>
---
 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