[PATCH v2 1/2] nilfs2: check new inode's nlink when rename
Wang Jianjian <[email protected]>
| Newsgroups | org.kernel.vger.linux-nilfs |
|---|---|
| Message-ID | <[email protected]> |
Syzbot reported below warning:
inode->i_nlink == 0
WARNING: fs/inode.c:417 at drop_nlink+0xc5/0x110 fs/inode.c:417, CPU#0:
syz.0.17/5467
The reason is as below:
1. setup a tracepoint bpf program on nilfs_transaction_transition and it
will send signal 33 when hit it.
2. rename foo -> file1
vfs_rename
nilfs_rename
// nilfs will remove old dentry from buffer cache and decrase
// target inode's links to zero
nilfs_transaction_commit
nilfs_construct_segment // fs mounted with SYNC
nilfs_segctor_sync
signal_pending // pend sigal 33 by bpf program sent
// set error to ERESTARTSYS
// vfs got error, dentry will not be unhashed and left in cache
3. above rename will be executed again(ERESTARTSYS) and get dentry from
cache but nilfs_rename will return ENOENT since old dentry had been
removed from buffer cache.
4. another renameat2 bar -> file1. This will find the old file1's dentry but its
links had been zero so that trigger this warning.
Reported-by: [email protected]
Closes: https://syzkaller.appspot.com/bug?extid=f6c7e1f1809f235eeb90
Signed-off-by: Wang Jianjian <[email protected]>
---
fs/nilfs2/namei.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c
index e2fe95de3d71..2ad1c83188e2 100644
--- a/fs/nilfs2/namei.c
+++ b/fs/nilfs2/namei.c
@@ -397,6 +397,12 @@ static int nilfs_rename(struct mnt_idmap *idmap,
struct folio *new_folio;
struct nilfs_dir_entry *new_de;
+ if (new_inode->i_nlink == 0) {
+ nilfs_error(old_dir->i_sb, "inode %lu links is zero", new_inode->i_ino);
+ err = -EIO;
+ goto out_dir;
+ }
+
err = -ENOTEMPTY;
if (old_is_dir && !nilfs_empty_dir(new_inode))
goto out_dir;
--
2.34.1