[BUG] ntfs3: KASAN null-ptr-deref in ntfs_iget5 (fs/ntfs3/inode.c:543) on mount

From: Farhad Alemi

Date: Thu May 28 2026 - 21:24:23 EST


Hello Konstantin and the ntfs3 team,

I am reporting a mount-time KASAN null-ptr-deref in ntfs_iget5() found
by syzkaller while mounting a crafted NTFS image, as part of research
at the SEFCOM Lab at ASU.

Summary:
The crash trips at fs/ntfs3/inode.c:543, which is the second branch of
the iget5_locked() result handling in ntfs_iget5():

struct inode *ntfs_iget5(struct super_block *sb, const struct MFT_REF *ref,
const struct cpu_str *name)
{
struct inode *inode;

inode = iget5_locked(sb, ino_get(ref), ntfs_test_inode,
ntfs_set_inode,
(void *)ref);
if (unlikely(!inode))
return ERR_PTR(-ENOMEM);

/* If this is a freshly allocated inode, need to read it now. */
if (inode_state_read_once(inode) & I_NEW)
inode = ntfs_read_mft(inode, name, ref);
else if (ref->seq != ntfs_i(inode)->mi.mrec->seq) { <-- :543
...
}

The dereference chain at line 543 is ntfs_i(inode)->mi.mrec->seq.
KASAN reports a null-ptr-deref in range
[0x0000000000000210-0x0000000000000217] (see crash-report.txt).

The call chain to this site in the observed crash is:

__se_sys_mount fs/namespace.c:4360
do_new_mount fs/namespace.c:3834
vfs_get_tree fs/super.c:1754
get_tree_bdev_flags fs/super.c:1694
ntfs_fill_super fs/ntfs3/super.c:1686
ntfs_iget5 fs/ntfs3/inode.c:543

Observed on:
- Linux 7.1.0-rc3-00200-g70eda68668d1-dirty, x86_64, QEMU Q35
- KASAN enabled (SMP KASAN NOPTI per crash header)
- The only local dirty file in my tree is drivers/tty/serial/serial_core.c,
containing a local ttyS0 console guard for the fuzzing harness. It is
unrelated to fs/ntfs3/.
- Image trigger: just before the crash the kernel prints
"ntfs3(loop6): Different NTFS sector size (4096) and media sector size
(512)." -- i.e. the mounted image declares a 4 KiB NTFS sector while
the loop device has 512-byte sectors.
- Source inspection of linus/master at commit e8c2f9fdadee
(v7.1-rc4-754-ge8c2f9fdadee) shows the buggy line is unchanged:
fs/ntfs3/inode.c:543 still does `else if (ref->seq !=
ntfs_i(inode)->mi.mrec->seq)` with no NULL/IS_ERR check on
ntfs_i(inode)->mi.mrec before the load. As no reproducer is available
for this seed, I have not re-run the against e8c2f9fdadee.

Impact:
A mount(2) of the crafted image kills the kernel with a general
protection fault; the trapping RIP is
ntfs_iget5+0x161/0x38e0 at fs/ntfs3/inode.c:543.

Expected behavior:
Either the chain `ntfs_i(inode)->mi.mrec->seq` at line 543 needs to be
guarded against the case where any of the intermediate pointers is
NULL/uninitialised, or ntfs_iget5() should not be reached with such an
inode in the cache in the first place. The maintainer is best placed
to choose which side of the contract owns the guard.

Novelty check:
I searched the syzbot dashboard's upstream open and fixed namespaces,
and the ntfs3 subsystem filter, for "ntfs_iget5" and "fs/ntfs3/inode.c:543".
The only existing ntfs_iget5 ticket is extid 4d48dcd9e88d37df77b3,
"KASAN: slab-use-after-free Read in ntfs_iget5", first reported
2026-03-31, still open.

That ticket is a different code path in the same function:

syzbot 4d48dcd9: ntfs_iget5+0x33a3/0x38f0 fs/ntfs3/inode.c:542
post-mount KASAN slab-use-after-free Read
reached via ntfs_file_fsync -> ni_write_parents

This report: ntfs_iget5+0x161/0x38e0 fs/ntfs3/inode.c:543
mount-time KASAN null-ptr-deref in range [0x210,0x217]
reached via __se_sys_mount -> ntfs_fill_super

I am sending this as a separate report because the two appear to
be distinct root causes, but please feel free to close as a dup of
4d48dcd9 if you'd prefer them tracked together.

A NULL-pointer dereference at the same condition
`else if (ref->seq != ntfs_i(inode)->mi.mrec->seq)` (then at
fs/ntfs3/inode.c:519, now at :543; the condition line is byte-
identical across both versions) was reported to lkml by Dipanjan
Das on 2023-02-18 for kernel 6.2.0-rc5:

Subject: BUG: unable to handle kernel NULL pointer dereference in
ntfs_iget5
Mirror: https://lkml.iu.edu/hypermail/linux/kernel/2302.2/02508.html

Per `git log linus/master -L 540,560:fs/ntfs3/inode.c`, no null-guard
on ntfs_i(inode)->mi.mrec at this site has been merged since.


I appreciate your time and consideration, and I'm grateful for your
work on this subsystem. I'd be glad to test any candidate patches.

Regards,
loop6: detected capacity change from 0 to 8192
ntfs3(loop6): Different NTFS sector size (4096) and media sector size (512).
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000042: 0000 [#1] SMP KASAN NOPTI
KASAN: null-ptr-deref in range [0x0000000000000210-0x0000000000000217]
CPU: 0 UID: 0 PID: 52967 Comm: syz.6.5660 Not tainted 7.1.0-rc3-00200-g70eda68668d1-dirty #1 PREEMPT(full)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
RIP: 0010:ntfs_iget5+0x161/0x38e0 fs/ntfs3/inode.c:543
Code: 81 c3 e0 fd ff ff 48 89 d8 48 c1 e8 03 42 80 3c 28 00 74 08 48 89 df e8 0d 93 4d ff 4c 8b 3b 49 83 c7 10 4c 89 f8 48 c1 e8 03 <42> 0f b6 04 28 84 c0 0f 85 d4 31 00 00 41 0f b7 1f 45 0f b7 fc 44
RSP: 0018:ffffc90001bdf660 EFLAGS: 00010206
RAX: 0000000000000042 RBX: ffff88812bbde840 RCX: 0000000000000002
RDX: ffff888168df4a00 RSI: 0000000000000000 RDI: 0000000000000000
RBP: ffffc90001bdf8b0 R08: ffffffff87c14903 R09: 1ffffffff0f82920
R10: dffffc0000000000 R11: fffffbfff0f82921 R12: 0000000000000005
R13: dffffc0000000000 R14: 1ffff9200037befc R15: 0000000000000210
FS: 00007f1194d376c0(0000) GS:ffff8882ab6b6000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f97e7e78684 CR3: 000000011b177000 CR4: 0000000000750ef0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000600
PKRU: 80000000
Call Trace:
<TASK>
ntfs_fill_super+0x4299/0x4590 fs/ntfs3/super.c:1686
get_tree_bdev_flags+0x436/0x500 fs/super.c:1694
vfs_get_tree+0x97/0x2b0 fs/super.c:1754
fc_mount fs/namespace.c:1193 [inline]
do_new_mount_fc fs/namespace.c:3758 [inline]
do_new_mount+0x346/0xd30 fs/namespace.c:3834
do_mount fs/namespace.c:4167 [inline]
__do_sys_mount fs/namespace.c:4383 [inline]
__se_sys_mount+0x322/0x420 fs/namespace.c:4360
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x15f/0x560 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f11962e91be
Code: 0f 1f 40 00 48 c7 c2 b0 ff ff ff f7 d8 64 89 02 b8 ff ff ff ff c3 66 0f 1f 44 00 00 f3 0f 1e fa 49 89 ca b8 a5 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f1194d36e28 EFLAGS: 00000246 ORIG_RAX: 00000000000000a5
RAX: ffffffffffffffda RBX: 00007f1194d36ec0 RCX: 00007f11962e91be
RDX: 0000200000020bc0 RSI: 0000200000020c00 RDI: 00007f1194d36e80
RBP: 0000200000020bc0 R08: 00007f1194d36ec0 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000200000020c00
R13: 00007f1194d36e80 R14: 0000000000020b8c R15: 0000200000020c40
</TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:ntfs_iget5+0x161/0x38e0 fs/ntfs3/inode.c:543
Code: 81 c3 e0 fd ff ff 48 89 d8 48 c1 e8 03 42 80 3c 28 00 74 08 48 89 df e8 0d 93 4d ff 4c 8b 3b 49 83 c7 10 4c 89 f8 48 c1 e8 03 <42> 0f b6 04 28 84 c0 0f 85 d4 31 00 00 41 0f b7 1f 45 0f b7 fc 44
RSP: 0018:ffffc90001bdf660 EFLAGS: 00010206
RAX: 0000000000000042 RBX: ffff88812bbde840 RCX: 0000000000000002
RDX: ffff888168df4a00 RSI: 0000000000000000 RDI: 0000000000000000
RBP: ffffc90001bdf8b0 R08: ffffffff87c14903 R09: 1ffffffff0f82920
R10: dffffc0000000000 R11: fffffbfff0f82921 R12: 0000000000000005
R13: dffffc0000000000 R14: 1ffff9200037befc R15: 0000000000000210
FS: 00007f1194d376c0(0000) GS:ffff8882ab6b6000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f756ab81000 CR3: 000000011b177000 CR4: 0000000000750ef0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000600
PKRU: 80000000
----------------
Code disassembly (best guess):
0: 81 c3 e0 fd ff ff add $0xfffffde0,%ebx
6: 48 89 d8 mov %rbx,%rax
9: 48 c1 e8 03 shr $0x3,%rax
d: 42 80 3c 28 00 cmpb $0x0,(%rax,%r13,1)
12: 74 08 je 0x1c
14: 48 89 df mov %rbx,%rdi
17: e8 0d 93 4d ff call 0xff4d9329
1c: 4c 8b 3b mov (%rbx),%r15
1f: 49 83 c7 10 add $0x10,%r15
23: 4c 89 f8 mov %r15,%rax
26: 48 c1 e8 03 shr $0x3,%rax
* 2a: 42 0f b6 04 28 movzbl (%rax,%r13,1),%eax <-- trapping instruction
2f: 84 c0 test %al,%al
31: 0f 85 d4 31 00 00 jne 0x320b
37: 41 0f b7 1f movzwl (%r15),%ebx
3b: 45 0f b7 fc movzwl %r12w,%r15d
3f: 44 rex.R

<<<<<<<<<<<<<<< tail report >>>>>>>>>>>>>>>