Forwarded: [PATCH] nilfs2: fix uninitialized btree node cache in nilfs_attach_btree_node_cache

From: syzbot

Date: Tue Mar 17 2026 - 03:36:52 EST


For archival purposes, forwarding an incoming command email to
linux-kernel@xxxxxxxxxxxxxxx, syzkaller-bugs@xxxxxxxxxxxxxxxx.

***

Subject: [PATCH] nilfs2: fix uninitialized btree node cache in nilfs_attach_btree_node_cache
Author: kartikey406@xxxxxxxxx

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


When nilfs_attach_btree_node_cache() finds a cached btnc_inode that is
not I_NEW, it skips nilfs_init_btnc_inode() leaving the btree node
cache in a stale or uninitialized state from a previous failed mount.
This causes i_assoc_inode to point to a broken inode, leading to a
null-ptr-deref in nilfs_mdt_save_to_shadow_map() when
NILFS_IOCTL_CLEAN_SEGMENTS is invoked.

Fix this by calling nilfs_init_btnc_inode() for cached btnc inodes as
well to ensure proper initialization regardless of inode cache state.

Reported-by: syzbot+4b4093b1f24ad789bf37@xxxxxxxxxxxxxxxxxxxxxxxxx
Closes: https://syzkaller.appspot.com/bug?extid=4b4093b1f24ad789bf37
Signed-off-by: Deepanshu Kartikey <Kartikey406@xxxxxxxxx>
---
fs/nilfs2/inode.c | 7 +++++++
fs/nilfs2/mdt.c | 8 ++++++++
2 files changed, 15 insertions(+)

diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
index 51bde45d5865..8312abbe343d 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -631,6 +631,9 @@ int nilfs_attach_btree_node_cache(struct inode *inode)
nilfs_iget_set, &args);
if (unlikely(!btnc_inode))
return -ENOMEM;
+ pr_err("NILFS DEBUG btnc: btnc=%px I_NEW=%d\n",
+ btnc_inode,
+ !!(inode_state_read_once(btnc_inode) & I_NEW));
if (inode_state_read_once(btnc_inode) & I_NEW) {
nilfs_init_btnc_inode(btnc_inode);
unlock_new_inode(btnc_inode);
@@ -686,6 +689,10 @@ struct inode *nilfs_iget_for_shadow(struct inode *inode)
nilfs_iget_set, &args);
if (unlikely(!s_inode))
return ERR_PTR(-ENOMEM);
+ pr_err("NILFS DEBUG: s_inode=%px I_NEW=%d i_assoc=%px\n",
+ s_inode,
+ !!(inode_state_read_once(s_inode) & I_NEW),
+ NILFS_I(s_inode)->i_assoc_inode);
if (!(inode_state_read_once(s_inode) & I_NEW))
return inode;

diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
index 946b0d3534a5..968a5be834cc 100644
--- a/fs/nilfs2/mdt.c
+++ b/fs/nilfs2/mdt.c
@@ -551,6 +551,14 @@ int nilfs_mdt_save_to_shadow_map(struct inode *inode)
struct inode *s_inode = shadow->inode;
int ret;

+ if (!ii->i_assoc_inode) {
+ pr_err("NILFS DEBUG: ii->i_assoc_inode is NULL, attaching\n");
+ dump_stack();
+ ret = nilfs_attach_btree_node_cache(inode);
+ if (ret) {
+ pr_err("NILFS: failed to attach btree node cache: %d\n", ret);
+ }
+ }
ret = nilfs_copy_dirty_pages(s_inode->i_mapping, inode->i_mapping);
if (ret)
goto out;
--
2.43.0