public inbox for driver-core@lists.linux.dev
 help / color / mirror / Atom feed
* [PATCH] kernfs: protect of->kn access in fop_read_iter/fop_mmap
@ 2026-04-27 13:35 Ravineet Singh
  2026-04-27 17:14 ` Tejun Heo
  0 siblings, 1 reply; 3+ messages in thread
From: Ravineet Singh @ 2026-04-27 13:35 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Tejun Heo
  Cc: driver-core, linux-kernel, stable, stable, David Nyström

kernfs_fop_read_iter() and kernfs_fop_mmap() dereference of->kn->flags
without holding an active reference on the kernfs node. If the node is
removed concurrently, this leads to a use-after-free:

[  448.037888] Unable to handle kernel paging request at virtual address ffffff821d8cedf0
[  448.093213] Mem abort info:
[  448.104535]   ESR = 0x0000000096000005
[  448.113391]   EC = 0x25: DABT (current EL), IL = 32 bits
[  448.126411]   SET = 0, FnV = 0
[  448.130758]   EA = 0, S1PTW = 0
[  448.134268]   FSC = 0x05: level 1 translation fault
[  448.140335] Data abort info:
[  448.143275]   ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000
[  448.150223]   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
[  448.155668]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[  448.161233] swapper pgtable: 4k pages, 39-bit VAs, pgdp=00000000afab8000
[  448.168835] [ffffff821d8cedf0] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000
[  448.178817] Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP
[  448.284717] pc : kernfs_fop_read_iter+0x1c/0x1ac
[  448.289416] lr : vfs_read+0x1c0/0x2a0
[  448.368374] Call trace:
[  448.370855]  kernfs_fop_read_iter+0x1c/0x1ac
[  448.375156]  vfs_read+0x1c0/0x2a0
[  448.378508]  ksys_read+0x6c/0x100
[  448.381901]  __arm64_sys_read+0x18/0x20
[  448.385768]  invoke_syscall.constprop.0+0x4c/0xe0
[  448.390502]  do_el0_svc+0x3c/0xb8
[  448.393898]  el0_svc+0x18/0x4c
[  448.396990]  el0t_64_sync_handler+0x118/0x124
[  448.401377]  el0t_64_sync+0x14c/0x150

Use kernfs_get_active_of() to obtain an active reference that also
checks the released flag, consistent with other of->kn accesses in
fs/kernfs/file.c. These paths were not covered when
kernfs_get_active_of() was introduced in commit 3c9ba2777d6c8
("kernfs: Fix UAF in polling when open file is released").

Fixes: 4eaad21a6ac9 ("kernfs: implement ->read_iter")
Cc: stable <stable@kernel.org>
Signed-off-by: Ravineet Singh <ravineet.a.singh@est.tech>
Signed-off-by: David Nyström <david.nystrom@est.tech>
---
 fs/kernfs/file.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c
index 1163aa7697384..6a52d24a63156 100644
--- a/fs/kernfs/file.c
+++ b/fs/kernfs/file.c
@@ -293,7 +293,16 @@ static ssize_t kernfs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
 
 static ssize_t kernfs_fop_read_iter(struct kiocb *iocb, struct iov_iter *iter)
 {
-	if (kernfs_of(iocb->ki_filp)->kn->flags & KERNFS_HAS_SEQ_SHOW)
+	struct kernfs_open_file *of = kernfs_of(iocb->ki_filp);
+	bool has_seq;
+
+	if (!kernfs_get_active_of(of))
+		return -ENODEV;
+
+	has_seq = of->kn->flags & KERNFS_HAS_SEQ_SHOW;
+	kernfs_put_active_of(of);
+
+	if (has_seq)
 		return seq_read_iter(iocb, iter);
 	return kernfs_file_read_iter(iocb, iter);
 }
@@ -458,6 +467,7 @@ static int kernfs_fop_mmap(struct file *file, struct vm_area_struct *vma)
 {
 	struct kernfs_open_file *of = kernfs_of(file);
 	const struct kernfs_ops *ops;
+	bool has_mmap;
 	int rc;
 
 	/*
@@ -467,7 +477,13 @@ static int kernfs_fop_mmap(struct file *file, struct vm_area_struct *vma)
 	 * without grabbing @of->mutex by testing HAS_MMAP flag.  See the
 	 * comment in kernfs_fop_open() for more details.
 	 */
-	if (!(of->kn->flags & KERNFS_HAS_MMAP))
+	if (!kernfs_get_active_of(of))
+		return -ENODEV;
+
+	has_mmap = of->kn->flags & KERNFS_HAS_MMAP;
+	kernfs_put_active_of(of);
+
+	if (!has_mmap)
 		return -ENODEV;
 
 	mutex_lock(&of->mutex);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] kernfs: protect of->kn access in fop_read_iter/fop_mmap
  2026-04-27 13:35 [PATCH] kernfs: protect of->kn access in fop_read_iter/fop_mmap Ravineet Singh
@ 2026-04-27 17:14 ` Tejun Heo
  2026-04-28  8:01   ` Ravineet Singh
  0 siblings, 1 reply; 3+ messages in thread
From: Tejun Heo @ 2026-04-27 17:14 UTC (permalink / raw)
  To: Ravineet Singh
  Cc: Greg Kroah-Hartman, driver-core, linux-kernel, stable, stable,
	David Nyström

Hello,

On Mon, Apr 27, 2026 at 03:35:21PM +0200, Ravineet Singh wrote:
> kernfs_fop_read_iter() and kernfs_fop_mmap() dereference of->kn->flags
> without holding an active reference on the kernfs node. If the node is
> removed concurrently, this leads to a use-after-free:
> 
> [  448.037888] Unable to handle kernel paging request at virtual address ffffff821d8cedf0
> [  448.093213] Mem abort info:
> [  448.104535]   ESR = 0x0000000096000005
> [  448.113391]   EC = 0x25: DABT (current EL), IL = 32 bits
> [  448.126411]   SET = 0, FnV = 0
> [  448.130758]   EA = 0, S1PTW = 0
> [  448.134268]   FSC = 0x05: level 1 translation fault
> [  448.140335] Data abort info:
> [  448.143275]   ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000
> [  448.150223]   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
> [  448.155668]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
> [  448.161233] swapper pgtable: 4k pages, 39-bit VAs, pgdp=00000000afab8000
> [  448.168835] [ffffff821d8cedf0] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000
> [  448.178817] Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP
> [  448.284717] pc : kernfs_fop_read_iter+0x1c/0x1ac
> [  448.289416] lr : vfs_read+0x1c0/0x2a0
> [  448.368374] Call trace:
> [  448.370855]  kernfs_fop_read_iter+0x1c/0x1ac
> [  448.375156]  vfs_read+0x1c0/0x2a0
> [  448.378508]  ksys_read+0x6c/0x100
> [  448.381901]  __arm64_sys_read+0x18/0x20
> [  448.385768]  invoke_syscall.constprop.0+0x4c/0xe0
> [  448.390502]  do_el0_svc+0x3c/0xb8
> [  448.393898]  el0_svc+0x18/0x4c
> [  448.396990]  el0t_64_sync_handler+0x118/0x124
> [  448.401377]  el0t_64_sync+0x14c/0x150

Do you have a repro for this?

> Use kernfs_get_active_of() to obtain an active reference that also
> checks the released flag, consistent with other of->kn accesses in
> fs/kernfs/file.c. These paths were not covered when
> kernfs_get_active_of() was introduced in commit 3c9ba2777d6c8
> ("kernfs: Fix UAF in polling when open file is released").

My memory is hazy but of->kn should be valid as long as of is alive. inode
holds the pin to its kn until inode is released and open files pin their
inodes. Active ref is something different - it's used to implement revoke
semantics so that the backend kernfs implementation can disconnect from
lingering open files, but that's not what controls the object lifetimes.

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] kernfs: protect of->kn access in fop_read_iter/fop_mmap
  2026-04-27 17:14 ` Tejun Heo
@ 2026-04-28  8:01   ` Ravineet Singh
  0 siblings, 0 replies; 3+ messages in thread
From: Ravineet Singh @ 2026-04-28  8:01 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Greg Kroah-Hartman, driver-core, linux-kernel, stable, stable,
	David Nyström

On Mon, Apr 27, 2026 at 07:14:48AM -1000, Tejun Heo wrote:
> Hello,
Hi,
thanks for the review.
>
> On Mon, Apr 27, 2026 at 03:35:21PM +0200, Ravineet Singh wrote:
> > kernfs_fop_read_iter() and kernfs_fop_mmap() dereference of->kn->flags
> > without holding an active reference on the kernfs node. If the node is
> > removed concurrently, this leads to a use-after-free:
> >
> > [  448.037888] Unable to handle kernel paging request at virtual address ffffff821d8cedf0
> > [  448.093213] Mem abort info:
> > [  448.104535]   ESR = 0x0000000096000005
> > [  448.113391]   EC = 0x25: DABT (current EL), IL = 32 bits
> > [  448.126411]   SET = 0, FnV = 0
> > [  448.130758]   EA = 0, S1PTW = 0
> > [  448.134268]   FSC = 0x05: level 1 translation fault
> > [  448.140335] Data abort info:
> > [  448.143275]   ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000
> > [  448.150223]   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
> > [  448.155668]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
> > [  448.161233] swapper pgtable: 4k pages, 39-bit VAs, pgdp=00000000afab8000
> > [  448.168835] [ffffff821d8cedf0] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000
> > [  448.178817] Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP
> > [  448.284717] pc : kernfs_fop_read_iter+0x1c/0x1ac
> > [  448.289416] lr : vfs_read+0x1c0/0x2a0
> > [  448.368374] Call trace:
> > [  448.370855]  kernfs_fop_read_iter+0x1c/0x1ac
> > [  448.375156]  vfs_read+0x1c0/0x2a0
> > [  448.378508]  ksys_read+0x6c/0x100
> > [  448.381901]  __arm64_sys_read+0x18/0x20
> > [  448.385768]  invoke_syscall.constprop.0+0x4c/0xe0
> > [  448.390502]  do_el0_svc+0x3c/0xb8
> > [  448.393898]  el0_svc+0x18/0x4c
> > [  448.396990]  el0t_64_sync_handler+0x118/0x124
> > [  448.401377]  el0t_64_sync+0x14c/0x150
>
> Do you have a repro for this?
No, unfortunately not, the crash was only seen once on an ARM64 platform
and we haven't been able to reproduce it since.
>
> > Use kernfs_get_active_of() to obtain an active reference that also
> > checks the released flag, consistent with other of->kn accesses in
> > fs/kernfs/file.c. These paths were not covered when
> > kernfs_get_active_of() was introduced in commit 3c9ba2777d6c8
> > ("kernfs: Fix UAF in polling when open file is released").
>
> My memory is hazy but of->kn should be valid as long as of is alive. inode
> holds the pin to its kn until inode is released and open files pin their
> inodes. Active ref is something different - it's used to implement revoke
> semantics so that the backend kernfs implementation can disconnect from
> lingering open files, but that's not what controls the object lifetimes.
>
> Thanks.
>
> --
> tejun
You're right about the lifetime model. The patch does not solve the issue, please ignore the patch.
I'll dig deeper into the actual root cause of the crash.


Thanks,
Ravineet

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-04-28  8:01 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-27 13:35 [PATCH] kernfs: protect of->kn access in fop_read_iter/fop_mmap Ravineet Singh
2026-04-27 17:14 ` Tejun Heo
2026-04-28  8:01   ` Ravineet Singh

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox