[syzbot] [nilfs?] general protection fault in nilfs_mdt_save_to_shadow_map

1 view
Skip to first unread message

syzbot

unread,
Mar 16, 2026, 11:14:31 PM (16 hours ago) Mar 16
to konishi...@gmail.com, linux-...@vger.kernel.org, linux...@vger.kernel.org, sl...@dubeyko.com, syzkall...@googlegroups.com
Hello,

syzbot found the following issue on:

HEAD commit: b84a0ebe421c Add linux-next specific files for 20260313
git tree: linux-next
console output: https://syzkaller.appspot.com/x/log.txt?x=115098ba580000
kernel config: https://syzkaller.appspot.com/x/.config?x=d079c776411aaf59
dashboard link: https://syzkaller.appspot.com/bug?extid=4b4093b1f24ad789bf37
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=15e844da580000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=11775d52580000

Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/ed9cdd5f6ba1/disk-b84a0ebe.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/856b866a24e9/vmlinux-b84a0ebe.xz
kernel image: https://storage.googleapis.com/syzbot-assets/b1d5ecff5545/bzImage-b84a0ebe.xz
mounted in repro: https://storage.googleapis.com/syzbot-assets/66467c518306/mount_0.gz

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+4b4093...@syzkaller.appspotmail.com

loop0: detected capacity change from 0 to 4096
NILFS (loop0): invalid segment: Checksum error in segment payload
NILFS (loop0): trying rollback from an earlier position
NILFS (loop0): recovery complete
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000006: 0000 [#1] SMP KASAN PTI
KASAN: null-ptr-deref in range [0x0000000000000030-0x0000000000000037]
CPU: 0 UID: 0 PID: 6003 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2026
RIP: 0010:nilfs_mdt_save_to_shadow_map+0x141/0x1c0 fs/nilfs2/mdt.c:559
Code: 3f 4c 8d 63 d8 4c 89 e0 48 c1 e8 03 42 80 3c 28 00 74 08 4c 89 e7 e8 2e 0b 83 fe 4d 8b 24 24 49 83 c4 30 4c 89 e0 48 c1 e8 03 <42> 80 3c 28 00 74 08 4c 89 e7 e8 10 0b 83 fe 49 8b 34 24 4c 89 ff
RSP: 0018:ffffc90002767708 EFLAGS: 00010206
RAX: 0000000000000006 RBX: ffff8880605d4560 RCX: 0000000000000000
RDX: ffff88802cde8000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: 0000000000000000 R08: ffff88802cde8000 R09: 0000000000000003
R10: 0000000000000406 R11: 0000000000000000 R12: 0000000000000030
R13: dffffc0000000000 R14: ffff8880764a6538 R15: ffff8880605d3b18
FS: 000055556403c500(0000) GS:ffff888125436000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000001b30263fff CR3: 0000000074cae000 CR4: 00000000003526f0
Call Trace:
<TASK>
nilfs_clean_segments+0x162/0xa50 fs/nilfs2/segment.c:2521
nilfs_ioctl_clean_segments fs/nilfs2/ioctl.c:916 [inline]
nilfs_ioctl+0x261f/0x2780 fs/nilfs2/ioctl.c:1346
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:597 [inline]
__se_sys_ioctl+0xfc/0x170 fs/ioctl.c:583
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fd2a5f9c799
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007ffd6d77cd18 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007fd2a6215fa0 RCX: 00007fd2a5f9c799
RDX: 0000200000000640 RSI: 0000000040786e88 RDI: 0000000000000004
RBP: 00007fd2a6032c99 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007fd2a6215fac R14: 00007fd2a6215fa0 R15: 00007fd2a6215fa0
</TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:nilfs_mdt_save_to_shadow_map+0x141/0x1c0 fs/nilfs2/mdt.c:559
Code: 3f 4c 8d 63 d8 4c 89 e0 48 c1 e8 03 42 80 3c 28 00 74 08 4c 89 e7 e8 2e 0b 83 fe 4d 8b 24 24 49 83 c4 30 4c 89 e0 48 c1 e8 03 <42> 80 3c 28 00 74 08 4c 89 e7 e8 10 0b 83 fe 49 8b 34 24 4c 89 ff
RSP: 0018:ffffc90002767708 EFLAGS: 00010206
RAX: 0000000000000006 RBX: ffff8880605d4560 RCX: 0000000000000000
RDX: ffff88802cde8000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: 0000000000000000 R08: ffff88802cde8000 R09: 0000000000000003
R10: 0000000000000406 R11: 0000000000000000 R12: 0000000000000030
R13: dffffc0000000000 R14: ffff8880764a6538 R15: ffff8880605d3b18
FS: 000055556403c500(0000) GS:ffff888125536000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f1536619000 CR3: 0000000074cae000 CR4: 00000000003526f0
----------------
Code disassembly (best guess), 1 bytes skipped:
0: 4c 8d 63 d8 lea -0x28(%rbx),%r12
4: 4c 89 e0 mov %r12,%rax
7: 48 c1 e8 03 shr $0x3,%rax
b: 42 80 3c 28 00 cmpb $0x0,(%rax,%r13,1)
10: 74 08 je 0x1a
12: 4c 89 e7 mov %r12,%rdi
15: e8 2e 0b 83 fe call 0xfe830b48
1a: 4d 8b 24 24 mov (%r12),%r12
1e: 49 83 c4 30 add $0x30,%r12
22: 4c 89 e0 mov %r12,%rax
25: 48 c1 e8 03 shr $0x3,%rax
* 29: 42 80 3c 28 00 cmpb $0x0,(%rax,%r13,1) <-- trapping instruction
2e: 74 08 je 0x38
30: 4c 89 e7 mov %r12,%rdi
33: e8 10 0b 83 fe call 0xfe830b48
38: 49 8b 34 24 mov (%r12),%rsi
3c: 4c 89 ff mov %r15,%rdi


---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzk...@googlegroups.com.

syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.

If the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-title

If you want syzbot to run the reproducer, reply with:
#syz test: git://repo/address.git branch-or-commit-hash
If you attach or paste a git patch, syzbot will apply it before testing.

If you want to overwrite report's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)

If the report is a duplicate of another one, reply with:
#syz dup: exact-subject-of-another-report

If you want to undo deduplication, reply with:
#syz undup

syzbot

unread,
Mar 16, 2026, 11:40:34 PM (15 hours ago) Mar 16
to linux-...@vger.kernel.org, syzkall...@googlegroups.com
For archival purposes, forwarding an incoming command email to
linux-...@vger.kernel.org, syzkall...@googlegroups.com.

***

Subject: [PATCH] nilfs2: fix NULL i_assoc_inode dereference in nilfs_mdt_save_to_shadow_map
Author: karti...@gmail.com

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


When nilfs_dat_read() is called a second time during rollback recovery
from a corrupted segment (checksum error), nilfs_iget_locked() returns
a cached DAT inode that is not I_NEW, causing the function to skip
nilfs_mdt_setup_shadow_map(). This leaves i_assoc_inode as NULL in the
DAT inode, which later causes a general protection fault in
nilfs_mdt_save_to_shadow_map() when NILFS_IOCTL_CLEAN_SEGMENTS is
invoked immediately after mount.

Fix this by redirecting the non-I_NEW path to a new reinit_shadow label
that calls nilfs_mdt_setup_shadow_map() if the shadow map has not been
initialized yet, ensuring i_assoc_inode is always valid before the
segment cleaner uses it.

Reported-by: syzbot+4b4093...@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=4b4093b1f24ad789bf37
Signed-off-by: Deepanshu Kartikey <Karti...@gmail.com>
---
fs/nilfs2/dat.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/fs/nilfs2/dat.c b/fs/nilfs2/dat.c
index 674380837ab9..c0b656e1c4ef 100644
--- a/fs/nilfs2/dat.c
+++ b/fs/nilfs2/dat.c
@@ -507,7 +507,7 @@ int nilfs_dat_read(struct super_block *sb, size_t entry_size,
if (unlikely(!dat))
return -ENOMEM;
if (!(inode_state_read_once(dat) & I_NEW))
- goto out;
+ goto reinit_shadow;

err = nilfs_mdt_init(dat, NILFS_MDT_GFP, sizeof(*di));
if (err)
@@ -529,6 +529,14 @@ int nilfs_dat_read(struct super_block *sb, size_t entry_size,
goto failed;

unlock_new_inode(dat);
+ goto out;
+reinit_shadow:
+ di = NILFS_DAT_I(dat);
+ if (!di->mi.mi_shadow) {
+ err = nilfs_mdt_setup_shadow_map(dat, &di->shadow);
+ if (err)
+ goto failed;
+ }
out:
*inodep = dat;
return 0;
--
2.43.0

syzbot

unread,
12:06 AM (15 hours ago) 12:06 AM
to karti...@gmail.com, linux-...@vger.kernel.org, syzkall...@googlegroups.com
Hello,

syzbot has tested the proposed patch but the reproducer is still triggering an issue:
general protection fault in nilfs_mdt_save_to_shadow_map

loop0: detected capacity change from 0 to 4096
NILFS (loop0): invalid segment: Checksum error in segment payload
NILFS (loop0): trying rollback from an earlier position
NILFS (loop0): recovery complete
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000006: 0000 [#1] SMP KASAN PTI
KASAN: null-ptr-deref in range [0x0000000000000030-0x0000000000000037]
CPU: 1 UID: 0 PID: 6533 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2026
RIP: 0010:nilfs_mdt_save_to_shadow_map+0x141/0x1c0 fs/nilfs2/mdt.c:559
Code: 3f 4c 8d 63 d8 4c 89 e0 48 c1 e8 03 42 80 3c 28 00 74 08 4c 89 e7 e8 de c8 82 fe 4d 8b 24 24 49 83 c4 30 4c 89 e0 48 c1 e8 03 <42> 80 3c 28 00 74 08 4c 89 e7 e8 c0 c8 82 fe 49 8b 34 24 4c 89 ff
RSP: 0018:ffffc90003467708 EFLAGS: 00010206
RAX: 0000000000000006 RBX: ffff888058b3c560 RCX: 0000000000000000
RDX: ffff888031629e80 RSI: 0000000000000000 RDI: 0000000000000000
RBP: 0000000000000000 R08: ffff888031629e80 R09: 0000000000000003
R10: 0000000000000406 R11: 0000000000000000 R12: 0000000000000030
R13: dffffc0000000000 R14: ffff88801cadd138 R15: ffff888058b3bb18
FS: 00007f88139416c0(0000) GS:ffff888125537000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000001b2e963fff CR3: 0000000023756000 CR4: 00000000003526f0
Call Trace:
<TASK>
nilfs_clean_segments+0x162/0xa50 fs/nilfs2/segment.c:2521
nilfs_ioctl_clean_segments fs/nilfs2/ioctl.c:916 [inline]
nilfs_ioctl+0x261f/0x2780 fs/nilfs2/ioctl.c:1346
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:597 [inline]
__se_sys_ioctl+0xfc/0x170 fs/ioctl.c:583
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f881299c799
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f8813941028 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007f8812c15fa0 RCX: 00007f881299c799
RDX: 0000200000000640 RSI: 0000000040786e88 RDI: 0000000000000004
RBP: 00007f8812a32c99 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f8812c16038 R14: 00007f8812c15fa0 R15: 00007fff51656638
</TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:nilfs_mdt_save_to_shadow_map+0x141/0x1c0 fs/nilfs2/mdt.c:559
Code: 3f 4c 8d 63 d8 4c 89 e0 48 c1 e8 03 42 80 3c 28 00 74 08 4c 89 e7 e8 de c8 82 fe 4d 8b 24 24 49 83 c4 30 4c 89 e0 48 c1 e8 03 <42> 80 3c 28 00 74 08 4c 89 e7 e8 c0 c8 82 fe 49 8b 34 24 4c 89 ff
RSP: 0018:ffffc90003467708 EFLAGS: 00010206
RAX: 0000000000000006 RBX: ffff888058b3c560 RCX: 0000000000000000
RDX: ffff888031629e80 RSI: 0000000000000000 RDI: 0000000000000000
RBP: 0000000000000000 R08: ffff888031629e80 R09: 0000000000000003
R10: 0000000000000406 R11: 0000000000000000 R12: 0000000000000030
R13: dffffc0000000000 R14: ffff88801cadd138 R15: ffff888058b3bb18
FS: 00007f88139416c0(0000) GS:ffff888125437000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f88129e9e80 CR3: 0000000023756000 CR4: 00000000003526f0
----------------
Code disassembly (best guess), 1 bytes skipped:
0: 4c 8d 63 d8 lea -0x28(%rbx),%r12
4: 4c 89 e0 mov %r12,%rax
7: 48 c1 e8 03 shr $0x3,%rax
b: 42 80 3c 28 00 cmpb $0x0,(%rax,%r13,1)
10: 74 08 je 0x1a
12: 4c 89 e7 mov %r12,%rdi
15: e8 de c8 82 fe call 0xfe82c8f8
1a: 4d 8b 24 24 mov (%r12),%r12
1e: 49 83 c4 30 add $0x30,%r12
22: 4c 89 e0 mov %r12,%rax
25: 48 c1 e8 03 shr $0x3,%rax
* 29: 42 80 3c 28 00 cmpb $0x0,(%rax,%r13,1) <-- trapping instruction
2e: 74 08 je 0x38
30: 4c 89 e7 mov %r12,%rdi
33: e8 c0 c8 82 fe call 0xfe82c8f8
38: 49 8b 34 24 mov (%r12),%rsi
3c: 4c 89 ff mov %r15,%rdi


Tested on:

commit: 95c541dd Add linux-next specific files for 20260316
git tree: linux-next
console output: https://syzkaller.appspot.com/x/log.txt?x=12f93d52580000
kernel config: https://syzkaller.appspot.com/x/.config?x=ed431987028345c6
dashboard link: https://syzkaller.appspot.com/bug?extid=4b4093b1f24ad789bf37
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
patch: https://syzkaller.appspot.com/x/patch.diff?x=1650a8da580000

syzbot

unread,
12:25 AM (14 hours ago) 12:25 AM
to linux-...@vger.kernel.org, syzkall...@googlegroups.com
For archival purposes, forwarding an incoming command email to
linux-...@vger.kernel.org, syzkall...@googlegroups.com.

***

Subject: [PATCH] nilfs2: fix wrong inode returned from nilfs_iget_for_shadow on cache hit
nilfs_iget_for_shadow() returns the original inode instead of the
cached shadow inode when the shadow inode already exists (I_NEW not
set). This causes nilfs_mdt_setup_shadow_map() to store the original
inode as shadow->inode, so subsequent calls to
nilfs_mdt_save_to_shadow_map() dereference the wrong inode's
i_assoc_inode, which may be NULL, leading to a general protection
fault.

This can be triggered by mounting a corrupted NILFS2 image that causes
rollback recovery, followed immediately by NILFS_IOCTL_CLEAN_SEGMENTS.
During rollback, nilfs_dat_read() is called twice, causing
nilfs_iget_for_shadow() to hit the cached path and return the wrong
inode.

Fix this by returning s_inode instead of inode on the cache hit path.
fs/nilfs2/inode.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
index 51bde45d5865..1f9bc63eb295 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -687,7 +687,7 @@ struct inode *nilfs_iget_for_shadow(struct inode *inode)
if (unlikely(!s_inode))
return ERR_PTR(-ENOMEM);
if (!(inode_state_read_once(s_inode) & I_NEW))
- return inode;
+ return s_inode;

NILFS_I(s_inode)->i_flags = 0;
memset(NILFS_I(s_inode)->i_bmap, 0, sizeof(struct nilfs_bmap));
--
2.43.0

syzbot

unread,
1:34 AM (13 hours ago) 1:34 AM
to karti...@gmail.com, linux-...@vger.kernel.org, syzkall...@googlegroups.com
Hello,

syzbot has tested the proposed patch but the reproducer is still triggering an issue:
general protection fault in nilfs_mdt_save_to_shadow_map

loop0: detected capacity change from 0 to 4096
NILFS (loop0): invalid segment: Checksum error in segment payload
NILFS (loop0): trying rollback from an earlier position
NILFS (loop0): recovery complete
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000006: 0000 [#1] SMP KASAN PTI
KASAN: null-ptr-deref in range [0x0000000000000030-0x0000000000000037]
CPU: 0 UID: 0 PID: 6523 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2026
RIP: 0010:nilfs_mdt_save_to_shadow_map+0x141/0x1c0 fs/nilfs2/mdt.c:559
Code: 3f 4c 8d 63 d8 4c 89 e0 48 c1 e8 03 42 80 3c 28 00 74 08 4c 89 e7 e8 2e c9 82 fe 4d 8b 24 24 49 83 c4 30 4c 89 e0 48 c1 e8 03 <42> 80 3c 28 00 74 08 4c 89 e7 e8 10 c9 82 fe 49 8b 34 24 4c 89 ff
RSP: 0018:ffffc90003277708 EFLAGS: 00010206
RAX: 0000000000000006 RBX: ffff88807317c560 RCX: 0000000000000000
RDX: ffff888035688000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: 0000000000000000 R08: ffff888035688000 R09: 0000000000000003
R10: 0000000000000406 R11: 0000000000000000 R12: 0000000000000030
R13: dffffc0000000000 R14: ffff8880207a1938 R15: ffff88807317bb18
FS: 00007f2a5c0606c0(0000) GS:ffff888125437000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000001b2f663fff CR3: 000000005f52c000 CR4: 00000000003526f0
Call Trace:
<TASK>
nilfs_clean_segments+0x162/0xa50 fs/nilfs2/segment.c:2521
nilfs_ioctl_clean_segments fs/nilfs2/ioctl.c:916 [inline]
nilfs_ioctl+0x261f/0x2780 fs/nilfs2/ioctl.c:1346
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:597 [inline]
__se_sys_ioctl+0xfc/0x170 fs/ioctl.c:583
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f2a5b19c799
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f2a5c060028 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007f2a5b415fa0 RCX: 00007f2a5b19c799
RDX: 0000200000000640 RSI: 0000000040786e88 RDI: 0000000000000004
RBP: 00007f2a5b232c99 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f2a5b416038 R14: 00007f2a5b415fa0 R15: 00007ffc84e2c978
</TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:nilfs_mdt_save_to_shadow_map+0x141/0x1c0 fs/nilfs2/mdt.c:559
Code: 3f 4c 8d 63 d8 4c 89 e0 48 c1 e8 03 42 80 3c 28 00 74 08 4c 89 e7 e8 2e c9 82 fe 4d 8b 24 24 49 83 c4 30 4c 89 e0 48 c1 e8 03 <42> 80 3c 28 00 74 08 4c 89 e7 e8 10 c9 82 fe 49 8b 34 24 4c 89 ff
RSP: 0018:ffffc90003277708 EFLAGS: 00010206
RAX: 0000000000000006 RBX: ffff88807317c560 RCX: 0000000000000000
RDX: ffff888035688000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: 0000000000000000 R08: ffff888035688000 R09: 0000000000000003
R10: 0000000000000406 R11: 0000000000000000 R12: 0000000000000030
R13: dffffc0000000000 R14: ffff8880207a1938 R15: ffff88807317bb18
FS: 00007f2a5c0606c0(0000) GS:ffff888125437000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f2a5b1e9e80 CR3: 000000005f52c000 CR4: 00000000003526f0
----------------
Code disassembly (best guess), 1 bytes skipped:
0: 4c 8d 63 d8 lea -0x28(%rbx),%r12
4: 4c 89 e0 mov %r12,%rax
7: 48 c1 e8 03 shr $0x3,%rax
b: 42 80 3c 28 00 cmpb $0x0,(%rax,%r13,1)
10: 74 08 je 0x1a
12: 4c 89 e7 mov %r12,%rdi
15: e8 2e c9 82 fe call 0xfe82c948
1a: 4d 8b 24 24 mov (%r12),%r12
1e: 49 83 c4 30 add $0x30,%r12
22: 4c 89 e0 mov %r12,%rax
25: 48 c1 e8 03 shr $0x3,%rax
* 29: 42 80 3c 28 00 cmpb $0x0,(%rax,%r13,1) <-- trapping instruction
2e: 74 08 je 0x38
30: 4c 89 e7 mov %r12,%rdi
33: e8 10 c9 82 fe call 0xfe82c948
38: 49 8b 34 24 mov (%r12),%rsi
3c: 4c 89 ff mov %r15,%rdi


Tested on:

commit: 95c541dd Add linux-next specific files for 20260316
git tree: linux-next
console output: https://syzkaller.appspot.com/x/log.txt?x=177f5602580000
kernel config: https://syzkaller.appspot.com/x/.config?x=ed431987028345c6
dashboard link: https://syzkaller.appspot.com/bug?extid=4b4093b1f24ad789bf37
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
patch: https://syzkaller.appspot.com/x/patch.diff?x=111962d6580000

syzbot

unread,
2:25 AM (12 hours ago) 2:25 AM
to linux-...@vger.kernel.org, syzkall...@googlegroups.com
For archival purposes, forwarding an incoming command email to
linux-...@vger.kernel.org, syzkall...@googlegroups.com.

***

Subject: [PATCH] nilfs2: fix missing i_assoc_inode initialization in nilfs_iget_for_shadow
When nilfs_iget_for_shadow() finds a cached shadow inode (I_NEW not
set), it returns the original inode instead of the cached shadow inode.
This causes nilfs_mdt_setup_shadow_map() to store the wrong inode as
shadow->inode, so subsequent calls to nilfs_mdt_save_to_shadow_map()
dereference the wrong inode's i_assoc_inode which may be NULL, leading
to a general protection fault.

Fix this by returning s_inode instead of inode on the cache hit path.

Reported-by: syzbot+4b4093...@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=4b4093b1f24ad789bf37
Signed-off-by: Deepanshu Kartikey <Karti...@gmail.com>
---
fs/nilfs2/inode.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
index 51bde45d5865..60cfcc209cf7 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -686,6 +686,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;

--
2.43.0

syzbot

unread,
2:43 AM (12 hours ago) 2:43 AM
to karti...@gmail.com, linux-...@vger.kernel.org, syzkall...@googlegroups.com
Hello,

syzbot has tested the proposed patch but the reproducer is still triggering an issue:
general protection fault in nilfs_mdt_save_to_shadow_map

NILFS (loop0): invalid segment: Checksum error in segment payload
NILFS (loop0): trying rollback from an earlier position
NILFS DEBUG: s_inode=ffff888073b0bf30 I_NEW=1 i_assoc=0000000000000000
NILFS (loop0): recovery complete
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000006: 0000 [#1] SMP KASAN PTI
KASAN: null-ptr-deref in range [0x0000000000000030-0x0000000000000037]
CPU: 1 UID: 0 PID: 6570 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2026
RIP: 0010:nilfs_mdt_save_to_shadow_map+0x141/0x1c0 fs/nilfs2/mdt.c:559
Code: 3f 4c 8d 63 d8 4c 89 e0 48 c1 e8 03 42 80 3c 28 00 74 08 4c 89 e7 e8 de c8 82 fe 4d 8b 24 24 49 83 c4 30 4c 89 e0 48 c1 e8 03 <42> 80 3c 28 00 74 08 4c 89 e7 e8 c0 c8 82 fe 49 8b 34 24 4c 89 ff
RSP: 0018:ffffc90003567708 EFLAGS: 00010206
RAX: 0000000000000006 RBX: ffff888073b0c560 RCX: 0000000000000000
RDX: ffff888079f78000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: 0000000000000000 R08: ffff888079f78000 R09: 0000000000000003
R10: 0000000000000406 R11: 0000000000000000 R12: 0000000000000030
R13: dffffc0000000000 R14: ffff88807d17c538 R15: ffff888073b0bb18
FS: 00007f607df766c0(0000) GS:ffff888125537000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000001b31a63fff CR3: 000000006ae06000 CR4: 00000000003526f0
Call Trace:
<TASK>
nilfs_clean_segments+0x162/0xa50 fs/nilfs2/segment.c:2521
nilfs_ioctl_clean_segments fs/nilfs2/ioctl.c:916 [inline]
nilfs_ioctl+0x261f/0x2780 fs/nilfs2/ioctl.c:1346
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:597 [inline]
__se_sys_ioctl+0xfc/0x170 fs/ioctl.c:583
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f607d19c799
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f607df76028 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007f607d415fa0 RCX: 00007f607d19c799
RDX: 0000200000000640 RSI: 0000000040786e88 RDI: 0000000000000004
RBP: 00007f607d232c99 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f607d416038 R14: 00007f607d415fa0 R15: 00007ffce886a6e8
</TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:nilfs_mdt_save_to_shadow_map+0x141/0x1c0 fs/nilfs2/mdt.c:559
Code: 3f 4c 8d 63 d8 4c 89 e0 48 c1 e8 03 42 80 3c 28 00 74 08 4c 89 e7 e8 de c8 82 fe 4d 8b 24 24 49 83 c4 30 4c 89 e0 48 c1 e8 03 <42> 80 3c 28 00 74 08 4c 89 e7 e8 c0 c8 82 fe 49 8b 34 24 4c 89 ff
RSP: 0018:ffffc90003567708 EFLAGS: 00010206
RAX: 0000000000000006 RBX: ffff888073b0c560 RCX: 0000000000000000
RDX: ffff888079f78000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: 0000000000000000 R08: ffff888079f78000 R09: 0000000000000003
R10: 0000000000000406 R11: 0000000000000000 R12: 0000000000000030
R13: dffffc0000000000 R14: ffff88807d17c538 R15: ffff888073b0bb18
FS: 00007f607df766c0(0000) GS:ffff888125537000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f607d1e9e80 CR3: 000000006ae06000 CR4: 00000000003526f0
----------------
Code disassembly (best guess), 1 bytes skipped:
0: 4c 8d 63 d8 lea -0x28(%rbx),%r12
4: 4c 89 e0 mov %r12,%rax
7: 48 c1 e8 03 shr $0x3,%rax
b: 42 80 3c 28 00 cmpb $0x0,(%rax,%r13,1)
10: 74 08 je 0x1a
12: 4c 89 e7 mov %r12,%rdi
15: e8 de c8 82 fe call 0xfe82c8f8
1a: 4d 8b 24 24 mov (%r12),%r12
1e: 49 83 c4 30 add $0x30,%r12
22: 4c 89 e0 mov %r12,%rax
25: 48 c1 e8 03 shr $0x3,%rax
* 29: 42 80 3c 28 00 cmpb $0x0,(%rax,%r13,1) <-- trapping instruction
2e: 74 08 je 0x38
30: 4c 89 e7 mov %r12,%rdi
33: e8 c0 c8 82 fe call 0xfe82c8f8
38: 49 8b 34 24 mov (%r12),%rsi
3c: 4c 89 ff mov %r15,%rdi


Tested on:

commit: 95c541dd Add linux-next specific files for 20260316
git tree: linux-next
console output: https://syzkaller.appspot.com/x/log.txt?x=1134a8da580000
kernel config: https://syzkaller.appspot.com/x/.config?x=ed431987028345c6
dashboard link: https://syzkaller.appspot.com/bug?extid=4b4093b1f24ad789bf37
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
patch: https://syzkaller.appspot.com/x/patch.diff?x=14b778da580000

syzbot

unread,
2:47 AM (12 hours ago) 2:47 AM
to linux-...@vger.kernel.org, syzkall...@googlegroups.com
For archival purposes, forwarding an incoming command email to
linux-...@vger.kernel.org, syzkall...@googlegroups.com.

***

Subject: [PATCH] nilfs2: fix uninitialized btree node cache in nilfs_attach_btree_node_cache
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.
fs/nilfs2/inode.c | 7 +++++++
1 file changed, 7 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)

syzbot

unread,
3:05 AM (12 hours ago) 3:05 AM
to karti...@gmail.com, linux-...@vger.kernel.org, syzkall...@googlegroups.com
Hello,

syzbot has tested the proposed patch but the reproducer is still triggering an issue:
general protection fault in nilfs_mdt_save_to_shadow_map

NILFS (loop0): trying rollback from an earlier position
NILFS DEBUG: s_inode=ffff888058f1bf30 I_NEW=1 i_assoc=0000000000000000
NILFS DEBUG btnc: btnc=ffff888058f1b900 I_NEW=1
NILFS (loop0): recovery complete
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000006: 0000 [#1] SMP KASAN PTI
KASAN: null-ptr-deref in range [0x0000000000000030-0x0000000000000037]
CPU: 0 UID: 0 PID: 6529 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2026
RIP: 0010:nilfs_mdt_save_to_shadow_map+0x141/0x1c0 fs/nilfs2/mdt.c:559
Code: 3f 4c 8d 63 d8 4c 89 e0 48 c1 e8 03 42 80 3c 28 00 74 08 4c 89 e7 e8 ce ca 82 fe 4d 8b 24 24 49 83 c4 30 4c 89 e0 48 c1 e8 03 <42> 80 3c 28 00 74 08 4c 89 e7 e8 b0 ca 82 fe 49 8b 34 24 4c 89 ff
RSP: 0018:ffffc900040a7708 EFLAGS: 00010206
RAX: 0000000000000006 RBX: ffff888058f1c560 RCX: 0000000000000000
RDX: ffff88803798bd00 RSI: 0000000000000000 RDI: 0000000000000000
RBP: 0000000000000000 R08: ffff88803798bd00 R09: 0000000000000003
R10: 0000000000000406 R11: 0000000000000000 R12: 0000000000000030
R13: dffffc0000000000 R14: ffff88802bac9138 R15: ffff888058f1bb18
FS: 00007f1d2e3856c0(0000) GS:ffff888125437000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000001b2e263fff CR3: 00000000373ba000 CR4: 00000000003526f0
Call Trace:
<TASK>
nilfs_clean_segments+0x162/0xa50 fs/nilfs2/segment.c:2521
nilfs_ioctl_clean_segments fs/nilfs2/ioctl.c:916 [inline]
nilfs_ioctl+0x261f/0x2780 fs/nilfs2/ioctl.c:1346
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:597 [inline]
__se_sys_ioctl+0xfc/0x170 fs/ioctl.c:583
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f1d2d59c799
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f1d2e385028 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007f1d2d815fa0 RCX: 00007f1d2d59c799
RDX: 0000200000000640 RSI: 0000000040786e88 RDI: 0000000000000004
RBP: 00007f1d2d632c99 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f1d2d816038 R14: 00007f1d2d815fa0 R15: 00007ffc09d78608
</TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:nilfs_mdt_save_to_shadow_map+0x141/0x1c0 fs/nilfs2/mdt.c:559
Code: 3f 4c 8d 63 d8 4c 89 e0 48 c1 e8 03 42 80 3c 28 00 74 08 4c 89 e7 e8 ce ca 82 fe 4d 8b 24 24 49 83 c4 30 4c 89 e0 48 c1 e8 03 <42> 80 3c 28 00 74 08 4c 89 e7 e8 b0 ca 82 fe 49 8b 34 24 4c 89 ff
RSP: 0018:ffffc900040a7708 EFLAGS: 00010206
RAX: 0000000000000006 RBX: ffff888058f1c560 RCX: 0000000000000000
RDX: ffff88803798bd00 RSI: 0000000000000000 RDI: 0000000000000000
RBP: 0000000000000000 R08: ffff88803798bd00 R09: 0000000000000003
R10: 0000000000000406 R11: 0000000000000000 R12: 0000000000000030
R13: dffffc0000000000 R14: ffff88802bac9138 R15: ffff888058f1bb18
FS: 00007f1d2e3856c0(0000) GS:ffff888125537000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000556adf0f25e0 CR3: 00000000373ba000 CR4: 00000000003526f0
----------------
Code disassembly (best guess), 1 bytes skipped:
0: 4c 8d 63 d8 lea -0x28(%rbx),%r12
4: 4c 89 e0 mov %r12,%rax
7: 48 c1 e8 03 shr $0x3,%rax
b: 42 80 3c 28 00 cmpb $0x0,(%rax,%r13,1)
10: 74 08 je 0x1a
12: 4c 89 e7 mov %r12,%rdi
15: e8 ce ca 82 fe call 0xfe82cae8
1a: 4d 8b 24 24 mov (%r12),%r12
1e: 49 83 c4 30 add $0x30,%r12
22: 4c 89 e0 mov %r12,%rax
25: 48 c1 e8 03 shr $0x3,%rax
* 29: 42 80 3c 28 00 cmpb $0x0,(%rax,%r13,1) <-- trapping instruction
2e: 74 08 je 0x38
30: 4c 89 e7 mov %r12,%rdi
33: e8 b0 ca 82 fe call 0xfe82cae8
38: 49 8b 34 24 mov (%r12),%rsi
3c: 4c 89 ff mov %r15,%rdi


Tested on:

commit: 95c541dd Add linux-next specific files for 20260316
git tree: linux-next
console output: https://syzkaller.appspot.com/x/log.txt?x=17ecc216580000
kernel config: https://syzkaller.appspot.com/x/.config?x=ed431987028345c6
dashboard link: https://syzkaller.appspot.com/bug?extid=4b4093b1f24ad789bf37
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
patch: https://syzkaller.appspot.com/x/patch.diff?x=1530d602580000

syzbot

unread,
3:36 AM (11 hours ago) 3:36 AM
to linux-...@vger.kernel.org, syzkall...@googlegroups.com
For archival purposes, forwarding an incoming command email to
linux-...@vger.kernel.org, syzkall...@googlegroups.com.

***

Subject: [PATCH] nilfs2: fix uninitialized btree node cache in nilfs_attach_btree_node_cache
Author: karti...@gmail.com

#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+4b4093...@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=4b4093b1f24ad789bf37
Signed-off-by: Deepanshu Kartikey <Karti...@gmail.com>
---
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

Edward Adam Davis

unread,
4:09 AM (11 hours ago) 4:09 AM
to syzbot+4b4093...@syzkaller.appspotmail.com, linux-...@vger.kernel.org, syzkall...@googlegroups.com
#syz test

diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index 1491a4d4b1e1..7e0b24361d0b 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -2518,9 +2518,11 @@ int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv,

nilfs_transaction_lock(sb, &ti, 1);

- err = nilfs_mdt_save_to_shadow_map(nilfs->ns_dat);
- if (unlikely(err))
- goto out_unlock;
+ if (argv[0].v_nmembs > 0) {
+ err = nilfs_mdt_save_to_shadow_map(nilfs->ns_dat);
+ if (unlikely(err))
+ goto out_unlock;
+ }

err = nilfs_ioctl_prepare_clean_segments(nilfs, argv, kbufs);
if (unlikely(err)) {

syzbot

unread,
4:15 AM (11 hours ago) 4:15 AM
to karti...@gmail.com, linux-...@vger.kernel.org, syzkall...@googlegroups.com
Hello,

syzbot has tested the proposed patch and the reproducer did not trigger any issue:

Reported-by: syzbot+4b4093...@syzkaller.appspotmail.com
Tested-by: syzbot+4b4093...@syzkaller.appspotmail.com

Tested on:

commit: 95c541dd Add linux-next specific files for 20260316
git tree: linux-next
console output: https://syzkaller.appspot.com/x/log.txt?x=10a362d6580000
kernel config: https://syzkaller.appspot.com/x/.config?x=ed431987028345c6
dashboard link: https://syzkaller.appspot.com/bug?extid=4b4093b1f24ad789bf37
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
patch: https://syzkaller.appspot.com/x/patch.diff?x=16bcc216580000

Note: testing is done by a robot and is best-effort only.

syzbot

unread,
4:26 AM (10 hours ago) 4:26 AM
to linux-...@vger.kernel.org, syzkall...@googlegroups.com
For archival purposes, forwarding an incoming command email to
linux-...@vger.kernel.org, syzkall...@googlegroups.com.

***

Subject: [PATCH] nilfs2: fix NULL i_assoc_inode dereference in nilfs_mdt_save_to_shadow_map
The DAT inode's btree node cache (i_assoc_inode) is initialized lazily
during btree operations. However, nilfs_mdt_save_to_shadow_map()
assumes i_assoc_inode is already initialized when copying dirty pages
to the shadow map during GC.

If NILFS_IOCTL_CLEAN_SEGMENTS is called immediately after mount before
any btree operation has occurred on the DAT inode, i_assoc_inode is
NULL leading to a general protection fault.

Fix this by calling nilfs_attach_btree_node_cache() on the DAT inode
in nilfs_dat_read() at mount time, ensuring i_assoc_inode is always
initialized before any GC operation can use it.
fs/nilfs2/dat.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/fs/nilfs2/dat.c b/fs/nilfs2/dat.c
index 674380837ab9..888dc1831c86 100644
--- a/fs/nilfs2/dat.c
+++ b/fs/nilfs2/dat.c
@@ -524,6 +524,9 @@ int nilfs_dat_read(struct super_block *sb, size_t entry_size,
if (err)
goto failed;

+ err = nilfs_attach_btree_node_cache(dat);
+ if (err)
+ goto failed;
err = nilfs_read_inode_common(dat, raw_inode);
if (err)
goto failed;
--
2.43.0

Edward Adam Davis

unread,
4:29 AM (10 hours ago) 4:29 AM
to syzbot+4b4093...@syzkaller.appspotmail.com, konishi...@gmail.com, linux-...@vger.kernel.org, linux...@vger.kernel.org, sl...@dubeyko.com, syzkall...@googlegroups.com
The value of argv0.v_nmembs passed from userspace is 0. This prevents
nilfs_iget_for_gc() from being called to initialize the gcinode during
the execution of nilfs_ioctl_move_blocks(). Consequently, this triggers
a null-ptr-deref involving ii->i_assoc_inode within the subsequent call
sequence: nilfs_clean_segments()->nilfs_mdt_save_to_shadow_map() [1].

A check for argv[0].v_nmembs has been added to nilfs_clean_segments()
to prevent this potential null-ptr-deref of ii->i_assoc_inode.

[1]
KASAN: null-ptr-deref in range [0x0000000000000030-0x0000000000000037]
Call Trace:
nilfs_clean_segments+0x162/0xa50 fs/nilfs2/segment.c:2521
nilfs_ioctl_clean_segments fs/nilfs2/ioctl.c:916 [inline]
nilfs_ioctl+0x261f/0x2780 fs/nilfs2/ioctl.c:1346

Signed-off-by: Edward Adam Davis <ead...@qq.com>
---
fs/nilfs2/segment.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
--
2.43.0

syzbot

unread,
4:41 AM (10 hours ago) 4:41 AM
to ead...@qq.com, linux-...@vger.kernel.org, syzkall...@googlegroups.com
Hello,

syzbot has tested the proposed patch and the reproducer did not trigger any issue:

Reported-by: syzbot+4b4093...@syzkaller.appspotmail.com
Tested-by: syzbot+4b4093...@syzkaller.appspotmail.com

Tested on:

commit: 95c541dd Add linux-next specific files for 20260316
git tree: linux-next
console output: https://syzkaller.appspot.com/x/log.txt?x=13a2006a580000
kernel config: https://syzkaller.appspot.com/x/.config?x=ed431987028345c6
dashboard link: https://syzkaller.appspot.com/bug?extid=4b4093b1f24ad789bf37
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
patch: https://syzkaller.appspot.com/x/patch.diff?x=13533d52580000

syzbot

unread,
4:56 AM (10 hours ago) 4:56 AM
to karti...@gmail.com, linux-...@vger.kernel.org, syzkall...@googlegroups.com
Hello,

syzbot has tested the proposed patch and the reproducer did not trigger any issue:

Reported-by: syzbot+4b4093...@syzkaller.appspotmail.com
Tested-by: syzbot+4b4093...@syzkaller.appspotmail.com

Tested on:

commit: 95c541dd Add linux-next specific files for 20260316
git tree: linux-next
console output: https://syzkaller.appspot.com/x/log.txt?x=1692c216580000
kernel config: https://syzkaller.appspot.com/x/.config?x=ed431987028345c6
dashboard link: https://syzkaller.appspot.com/bug?extid=4b4093b1f24ad789bf37
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
patch: https://syzkaller.appspot.com/x/patch.diff?x=10733d52580000

Deepanshu Kartikey

unread,
11:13 AM (4 hours ago) 11:13 AM
to ead...@qq.com, konishi...@gmail.com, linux-...@vger.kernel.org, linux...@vger.kernel.org, sl...@dubeyko.com, syzbot+4b4093...@syzkaller.appspotmail.com, syzkall...@googlegroups.com
Hi Edward,

On Mon, 17 Mar 2026, Edward Adam Davis wrote:

> The value of argv0.v_nmembs passed from userspace is 0. This prevents
> nilfs_iget_for_gc() from being called to initialize the gcinode during
> the execution of nilfs_ioctl_move_blocks(). Consequently, this triggers
> a null-ptr-deref involving ii->i_assoc_inode within the subsequent call
> sequence: nilfs_clean_segments()->nilfs_mdt_save_to_shadow_map() [1].

This analysis is incorrect. The null-ptr-deref is not caused by
nilfs_iget_for_gc() not being called. The real problem is that
ns_dat->i_assoc_inode (the DAT inode's btree node cache) is never
initialized at mount time.

> A check for argv[0].v_nmembs has been added to nilfs_clean_segments()
> to prevent this potential null-ptr-deref of ii->i_assoc_inode.

This fixes the symptom but not the root cause. Also note that in
the original syzkaller reproducer:

argv[0].v_nmembs = 0xd = 13 > 0

Your check would NOT prevent the crash with the original reproducer.

The correct fix is to initialize the btnode cache eagerly in
nilfs_dat_read() at mount time, since i_assoc_inode is only
initialized lazily during btree operations. When
NILFS_IOCTL_CLEAN_SEGMENTS is called before any btree operation
has occurred, i_assoc_inode is NULL.

I have already submitted this fix and syzbot confirmed it as fixed:

https://lore.kernel.org/all/20260317090109.87...@gmail.com/T/

Regards,
Deepanshu Kartikey

Deepanshu Kartikey

unread,
11:15 AM (4 hours ago) 11:15 AM
to ead...@qq.com, konishi...@gmail.com, linux-...@vger.kernel.org, linux...@vger.kernel.org, sl...@dubeyko.com, syzbot+4b4093...@syzkaller.appspotmail.com, syzkall...@googlegroups.com
Hi Edward,

On Mon, 17 Mar 2026, Edward Adam Davis wrote:

> The value of argv0.v_nmembs passed from userspace is 0. This prevents
> nilfs_iget_for_gc() from being called to initialize the gcinode during
> the execution of nilfs_ioctl_move_blocks(). Consequently, this triggers
> a null-ptr-deref involving ii->i_assoc_inode within the subsequent call
> sequence: nilfs_clean_segments()->nilfs_mdt_save_to_shadow_map() [1].

This analysis is incorrect. The null-ptr-deref is not caused by
nilfs_iget_for_gc() not being called. The real problem is that
ns_dat->i_assoc_inode (the DAT inode's btree node cache) is never
initialized at mount time.

> A check for argv[0].v_nmembs has been added to nilfs_clean_segments()
> to prevent this potential null-ptr-deref of ii->i_assoc_inode.

Ryusuke Konishi

unread,
12:51 PM (2 hours ago) 12:51 PM
to Deepanshu Kartikey, ead...@qq.com, linux-...@vger.kernel.org, linux...@vger.kernel.org, sl...@dubeyko.com, syzbot+4b4093...@syzkaller.appspotmail.com, syzkall...@googlegroups.com
Hi Deepanshu and Edward,
Deepanshu's suggestion seems close to the answer, but I think there's
a slight leap in the root cause analysis.

When nilfs_dat_read() is in a b-tree configuration, it normally calls
nilfs_attach_btree_node_cache() via nilfs_read_inode_common() ->
nilfs_bmap_read() -> nilfs_btree_init().

Therefore, the problem seems to be one of the following two:
(1) nilfs_mdt_save_to_shadow_map(), called from a GC ioctl specifying
the dat, calls nilfs_copy_dirty_pages() assuming a b-tree node cache
exists, regardless of whether the DAT is direct mapping or b-tree
mapping.
(The DAT mapping method switching is not considered.)

(2) The DAT is in b-tree mapping mode, but nilfs_btree_init() is not
being called because the i_mode of the DAT inode is corrupt.

Both appear to be potential bugs, but their fixes are different.
Have you determined which of these is causing this bug?

Regards,
Ryusuke Konishi
Reply all
Reply to author
Forward
0 new messages