Forwarded: [PATCH] namei: fix parent inode unlock in end_creating_path()

syzbot posted 1 patch 1 month ago
fs/namei.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
Forwarded: [PATCH] namei: fix parent inode unlock in end_creating_path()
Posted by syzbot 1 month ago
For archival purposes, forwarding an incoming command email to
linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com.

***

Subject: [PATCH] namei: fix parent inode unlock in end_creating_path()
Author: kartikey406@gmail.com

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


end_creating_path() calls end_dirop() which unlocks
dentry->d_parent->d_inode. However, the lock was originally acquired on
path->dentry by start_dirop() inside filename_create(). If a concurrent
operation such as renameat2(RENAME_EXCHANGE) modifies the dentry tree
between lock and unlock, dentry->d_parent may no longer point to the
originally locked inode, causing an unbalanced unlock.

Fix this by unlocking path->dentry directly in end_creating_path()
instead of deriving the parent from the child dentry. This ensures the
lock and unlock always operate on the same inode regardless of
concurrent dentry tree modifications.

Reported-by: syzbot+2ed46b6b748df855347f@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=2ed46b6b748df855347f
Signed-off-by: Deepanshu Kartikey <Kartikey406@gmail.com>
---
 fs/namei.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/fs/namei.c b/fs/namei.c
index 58f715f7657e..c861de965d86 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -4959,7 +4959,10 @@ EXPORT_SYMBOL(start_creating_path);
  */
 void end_creating_path(const struct path *path, struct dentry *dentry)
 {
-	end_creating(dentry);
+	if (!IS_ERR(dentry)) {
+		inode_unlock(d_inode(path->dentry));
+		dput(dentry);
+	}
 	mnt_drop_write(path->mnt);
 	path_put(path);
 }
-- 
2.43.0