* [PATCH] ocfs2: stabilize the dentry name while tracing reads
@ 2026-10-15 16:58 Cen Zhang
0 siblings, 0 replies; only message in thread
From: Cen Zhang @ 2026-10-15 16:58 UTC (permalink / raw)
To: mark, jlbec, joseph.qi, heming.zhao, boyu.mt
Cc: ocfs2-devel, linux-kernel, stable, baijiaju1990, jjzuming, zzzccc427
An open file pins its dentry, but not the external allocation backing
an individual dentry name. ocfs2_file_read_iter() passes d_name.name to
its trace event without holding d_lock or a name snapshot. The event's
__string field needs those bytes for both strlen() sizing and the
subsequent copy.
With the read event enabled, a read of an open long-named file can be
preempted after evaluating the trace argument. A successful concurrent
long-to-short rename of the same dentry can then reclaim that name,
provided no other name snapshot retains it:
Reader Renamer
ocfs2_file_read_iter()
load old d_name.name
<preempted>
vfs_rename()
take_dentry_name_snapshot()
ocfs2_rename()
ocfs2_dentry_move()
d_move()/copy_name()
release_dentry_name_snapshot()
kfree_rcu() reclamation completes
trace callback calls strlen()
through the old name pointer
The pointer load precedes the rename, and sizing follows reclamation,
so strlen() reads freed name storage. The tracepoint's SRCU section
protects its probes, and the event callback disables preemption only
after the caller has loaded the name pointer.
Hold d_lock from argument evaluation until the trace call returns,
following the name tracing in ocfs2_find_local_alias(). This prevents
rename from replacing the name while the event sizes and copies it.
Check whether the event is enabled before taking the lock to avoid
adding locking to reads when tracing is disabled.
KASAN report as below:
BUG: KASAN: slab-use-after-free in strlen+0x85/0xa0
Read of size 1 at addr ffff88810a5b2b18 by task python3/496
[CPU and host details omitted.]
Call Trace:
<TASK>
dump_stack_lvl+0x93/0xd0
print_report+0xce/0x630
? strlen+0x85/0xa0
? srso_alias_return_thunk+0x5/0xfbef5
? __virt_addr_valid+0x20e/0x420
? strlen+0x85/0xa0
kasan_report+0xe0/0x110
? strlen+0x85/0xa0
strlen+0x85/0xa0
trace_event_raw_event_ocfs2__file_ops+0xf0/0x480
? __pfx_trace_event_raw_event_ocfs2__file_ops+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? pmbd_probe_hit_cookie+0xe7/0x1c0
? srso_alias_return_thunk+0x5/0xfbef5
? __pfx_pmbd_probe_hit_cookie+0x10/0x10
ocfs2_file_read_iter+0x6cd/0xb30
? __pfx_ocfs2_file_read_iter+0x10/0x10
? selinux_file_permission+0x11d/0x540
? srso_alias_return_thunk+0x5/0xfbef5
? security_file_permission+0x26/0x80
vfs_read+0x7d2/0xc20
? __pfx_vfs_read+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? __pfx_do_sys_openat2+0x10/0x10
ksys_read+0x111/0x200
? __pfx_ksys_read+0x10/0x10
? irqentry_exit+0xbe/0x820
? srso_alias_return_thunk+0x5/0xfbef5
? trace_hardirqs_on_prepare+0x11d/0x150
? srso_alias_return_thunk+0x5/0xfbef5
do_syscall_64+0x114/0x620
entry_SYSCALL_64_after_hwframe+0x77/0x7f
[User register dump omitted.]
</TASK>
Allocated by task 489:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
__kasan_kmalloc+0xaa/0xb0
__kmalloc_noprof+0x2de/0x780
__d_alloc+0x5fc/0x8c0
d_alloc_parallel+0x106/0x11d0
lookup_open+0x3ff/0x13e0
path_openat+0x95e/0x2020
do_file_open+0x21e/0x470
do_sys_openat2+0xf4/0x1b0
__x64_sys_openat+0x136/0x1e0
do_syscall_64+0x114/0x620
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Freed by task 0:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
kasan_save_free_info+0x3b/0x60
__kasan_slab_free+0x5f/0x80
__rcu_free_sheaf_prepare+0x65/0x2a0
rcu_free_sheaf_nobarn+0x1d/0x50
rcu_core+0x6be/0x1ed0
handle_softirqs+0x1fa/0x8d0
__irq_exit_rcu+0x113/0x1e0
irq_exit_rcu+0xe/0x20
sysvec_apic_timer_interrupt+0x6c/0x80
asm_sysvec_apic_timer_interrupt+0x1a/0x20
The buggy address belongs to the object at ffff88810a5b2b00
which belongs to the cache kmalloc-rcl-192 of size 192
The buggy address is located 24 bytes inside of
freed 192-byte region [ffff88810a5b2b00, ffff88810a5b2bc0)
[Page and shadow-memory dumps omitted.]
Fixes: 468eedde23d6 ("ocfs2: Remove mlog(0) from fs/ocfs2/file.c")
Cc: <stable@vger.kernel.org>
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
Assisted-by: LLM
---
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index d6e977ba6565..e2a42257f243 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -2542,11 +2542,17 @@ static ssize_t ocfs2_file_read_iter(struct kiocb *iocb,
int direct_io = iocb->ki_flags & IOCB_DIRECT ? 1 : 0;
int nowait = iocb->ki_flags & IOCB_NOWAIT ? 1 : 0;
- trace_ocfs2_file_read_iter(inode, filp, filp->f_path.dentry,
- (unsigned long long)OCFS2_I(inode)->ip_blkno,
- filp->f_path.dentry->d_name.len,
- filp->f_path.dentry->d_name.name,
- to->nr_segs); /* GRRRRR */
+ if (trace_ocfs2_file_read_iter_enabled()) {
+ struct dentry *dentry = filp->f_path.dentry;
+
+ spin_lock(&dentry->d_lock);
+ trace_ocfs2_file_read_iter(inode, filp, dentry,
+ OCFS2_I(inode)->ip_blkno,
+ dentry->d_name.len,
+ dentry->d_name.name,
+ to->nr_segs); /* GRRRRR */
+ spin_unlock(&dentry->d_lock);
+ }
if (!inode) {
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-10-15 16:58 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-15 16:58 [PATCH] ocfs2: stabilize the dentry name while tracing reads Cen Zhang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®