ntfs3: Use after free race condition in ntfs_read_folio()?

Dirk Behme <[email protected]> Wed, 27 May 2026 06:34:30 +0200
Newsgroups dev.linux.lists.ntfs3
Message-ID <[email protected]>
Hi,

on a custom ARM64 board with kernel 6.1.157 we got a report about a data 
abort Oops [1] in ntfs_read_folio() [2]. The disassembly is [3].

Analysing this the failing instruction is

385f82e8 	ldurb	w8, [x23, #-8]

with x23: ffff8d623ef35800 - 8 matching the fault address ffff8d623ef357f8.

Matching this to the C code we think the compiler summarises

struct ntfs_inode *ni = ntfs_i(inode);
if (is_resident(ni)) {

to one assembly instruction to access the ni_flags in struct ntfs_inode 
via the inode [4].

Getting a data abort trying to access the ni_flags, we assume that the 
whole struct ntfs_inode has been freed, already. While missing to reset 
/ clear some reference to it. What in sum looks like a use after free 
race condition accessing struct ntfs_inode in ntfs_read_folio().

We have searched for something obvious in more recent commits but 
couldn't find anything what looks related. Have we missed anything?

What do you think? Any idea?

Thanks

Dirk

[1]

Unable to handle kernel paging request at virtual address ffff8d623ef357f8
Mem abort info:
   ESR = 0x0000000096000004
   EC = 0x25: DABT (current EL), IL = 32 bits
   SET = 0, FnV = 0
   EA = 0, S1PTW = 0
   FSC = 0x04: level 0 translation fault
Data abort info:
   ISV = 0, ISS = 0x00000004
   CM = 0, WnR = 0
[ffff8d623ef357f8] address between user and kernel address ranges
Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP
Modules linked in: ... ntfs3 ...
CPU: 3 PID: 9611 Comm: binder:529_A Tainted: G           O       6.1.157 #1
Hardware name: ARM64 custom board
pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : ntfs_read_folio+0x24/0xe0 [ntfs3]
lr : filemap_read_folio+0x6c/0x15c
sp : ffffffc01c05bad0
x29: ffffffc01c05bad0 x28: 00000000fffffa00 x27: 0000000000080001
x26: 00000000ffffffff x25: ff00000000000000 x24: ffffff8d623ef4e8
x23: ffff8d623ef35800 x22: 0000000000000000 x21: ffffffc001591414
x20: fffffffe378c42c0 x19: fffffffe378c42c0 x18: ffffffc0109a0080
x17: 000000001b98ee9a x16: 000000001b98ee9a x15: ffffffc00158ed90
x14: 0000000000000007 x13: 000000000001d3a2 x12: ffffffce57fbe000
x11: 0000000000000001 x10: 0000000000000001 x9 : 0000000000000100
x8 : ffffff8d623ef4e7 x7 : 0000000000000000 x6 : 0000000000000000
x5 : ffffff8ca937808c x4 : ffffffc01c05bb50 x3 : 0000000006100cca
x2 : fffffffe378c42c0 x1 : fffffffe378c42c0 x0 : 0000000000000000
Call trace:
  ntfs_read_folio+0x24/0xe0 [ntfs3]
  filemap_read_folio+0x6c/0x15c
  do_read_cache_folio+0x144/0x338
  read_cache_page+0x1c/0x58
  ntfs_fill_super+0xde8/0xf20 [ntfs3]
  get_tree_bdev+0x1c4/0x258
  ntfs_fs_get_tree+0x18/0x28 [ntfs3]
  vfs_get_tree+0x48/0xfc
  do_new_mount+0x154/0x36c
  path_mount+0x270/0x4e4
  __arm64_sys_mount+0x1b4/0x3dc
  invoke_syscall+0x58/0x118
  el0_svc_common+0xb4/0xf4
  do_el0_svc+0x24/0x80
  el0_svc+0x2c/0x90
  el0t_64_sync_handler+0x68/0xb4
  el0t_64_sync+0x1a4/0x1a8
Code: 910003fd f9400c28 aa0103f3 f9400117 (385f82e8)
---[ end trace 0000000000000000 ]---
Kernel panic - not syncing: Oops: Fatal exception
SMP: stopping secondary CPUs

[2]

static int ntfs_read_folio(struct file *file, struct folio *folio)
{
	struct page *page = &folio->page;
	int err;
	struct address_space *mapping = page->mapping;
	struct inode *inode = mapping->host;
	struct ntfs_inode *ni = ntfs_i(inode);

	if (is_resident(ni)) {
		ni_lock(ni);
		err = attr_data_read_resident(ni, page);
		ni_unlock(ni);
		if (err != E_NTFS_NONRESIDENT) {
			unlock_page(page);
			return err;
		}
	}

	if (is_compressed(ni)) {
		ni_lock(ni);
		err = ni_readpage_cmpr(ni, page);
		ni_unlock(ni);
		return err;
	}

	/* Normal + sparse files. */
	return mpage_read_folio(folio, ntfs_get_block);
}

[3]

000000000001e934 <ntfs_read_folio>:
    1e934:	d503233f 	paciasp
    1e938:	a9bc7bfd 	stp	x29, x30, [sp, #-64]!
    1e93c:	f9000bf7 	str	x23, [sp, #16]
    1e940:	a90257f6 	stp	x22, x21, [sp, #32]
    1e944:	a9034ff4 	stp	x20, x19, [sp, #48]
    1e948:	910003fd 	mov	x29, sp
    1e94c:	f9400c28 	ldr	x8, [x1, #24]
    1e950:	aa0103f3 	mov	x19, x1
    1e954:	f9400117 	ldr	x23, [x8]
    1e958:	385f82e8 	ldurb	w8, [x23, #-8]

[4]

struct ntfs_inode {
	....

	size_t ni_flags; // NI_FLAG_XXX

	struct inode vfs_inode;
};