From: Cen Zhang <zzzccc427@gmail.com>
To: mark@fasheh.com, jlbec@evilplan.org, joseph.qi@linux.alibaba.com,
heming.zhao@suse.com, jack@suse.cz, akpm@linux-foundation.org,
srinivas.eeda@oracle.com, rgoldwyn@suse.de
Cc: ocfs2-devel@lists.linux.dev, linux-kernel@vger.kernel.org,
stable@vger.kernel.org, baijiaju1990@gmail.com,
jjzuming@gmail.com, zzzccc427@gmail.com
Subject: [PATCH] ocfs2: Keep the dentry lock inode alive until callbacks drain
Date: Fri, 16 Oct 2026 00:03:20 +0800 [thread overview]
Message-ID: <pm-ocfs2-objects-candidate-0012-v5-a0413a339b72c02fc885@gmail.com> (raw)
The inode reference held by a DENTRY lock must outlive callbacks on
that lock. ocfs2_drop_dentry_lock() drops dl_inode before marking the
lock freeing and waiting for DLM unlock completion, although the BAST
path still reads dl_inode->i_sb in ocfs2_get_dentry_osb().
An EX request, such as a remote unlink or rename, can make the
downconvert worker delete all matching aliases. If no other inode
reference remains, its post_unlock callback performs the final iput().
The O2CB DLM can deliver another BAST while the request is still
blocked, for example when another holder releases the same resource:
Downconvert worker DLM callback
------------------ ------------
Remove dentry aliases
Clear QUEUED; post_unlock()
ocfs2_drop_dentry_lock()
iput(dl->dl_inode)
[inode reclaimed after RCU]
Duplicate BAST
ocfs2_blocking_ast()
ocfs2_get_dentry_osb()
Read freed dl_inode->i_sb
ocfs2_simple_drop_lockres()
Call ocfs2_simple_drop_lockres() before iput() so the existing inode
reference remains held while queued work and DLM callbacks are drained.
The inode can only be evicted after the DENTRY lock has been unlocked.
KASAN report as below:
BUG: KASAN: slab-use-after-free in ocfs2_get_dentry_osb+0x155/0x170
Read of size 8 at addr ffff8881100ff888 by task dlm-5B530197BEF/575
CPU: 0 UID: 0 PID: 575 Comm: dlm-5B530197BEF Not tainted 7.3.0-rc4-next-20260921-pmb-ocfs2-functional-v1+ #1 PREEMPT(lazy)
Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Call Trace:
<TASK>
dump_stack_lvl+0x93/0xd0
print_report+0xce/0x630
? ocfs2_get_dentry_osb+0x155/0x170
? srso_alias_return_thunk+0x5/0xfbef5
? __virt_addr_valid+0x20e/0x420
? ocfs2_get_dentry_osb+0x155/0x170
kasan_report+0xe0/0x110
? ocfs2_get_dentry_osb+0x155/0x170
? __pfx_ocfs2_get_dentry_osb+0x10/0x10
? __pfx_o2dlm_blocking_ast_wrapper+0x10/0x10
ocfs2_get_dentry_osb+0x155/0x170
ocfs2_blocking_ast+0xd3/0x6d0
? srso_alias_return_thunk+0x5/0xfbef5
? __lock_acquire+0x5a3/0x2140
? srso_alias_return_thunk+0x5/0xfbef5
? __mlog_printk+0x212/0x2a0
? __pfx_ocfs2_blocking_ast+0x10/0x10
? __pfx_o2dlm_blocking_ast_wrapper+0x10/0x10
dlm_do_local_bast+0x20c/0x300
? srso_alias_return_thunk+0x5/0xfbef5
? __pfx_dlm_do_local_bast+0x10/0x10
? dlm_thread+0x2e36/0x4480
dlm_thread+0x32b8/0x4480
? __pfx_dlm_thread+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? __kthread_parkme+0xc1/0x220
? srso_alias_return_thunk+0x5/0xfbef5
? lock_release+0xc8/0x290
? __pfx_autoremove_wake_function+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? srso_alias_return_thunk+0x5/0xfbef5
? __kthread_parkme+0x177/0x220
? __pfx_dlm_thread+0x10/0x10
kthread+0x351/0x460
? srso_alias_return_thunk+0x5/0xfbef5
? __pfx_kthread+0x10/0x10
ret_from_fork+0x659/0x940
? __pfx_ret_from_fork+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? __switch_to+0x74f/0xf70
? __pfx_kthread+0x10/0x10
ret_from_fork_asm+0x1a/0x30
</TASK>
Allocated by task 584:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
__kasan_slab_alloc+0x89/0x90
kmem_cache_alloc_lru_noprof+0x205/0x5c0
ocfs2_alloc_inode+0x2b/0x100
alloc_inode+0x69/0x230
new_inode+0x23/0x1a0
ocfs2_get_init_inode+0x84/0x190
ocfs2_mknod+0x8a3/0x2150
ocfs2_create+0x14f/0x3c0
lookup_open+0x88f/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
kmem_cache_free+0x242/0x580
i_callback+0x4b/0x80
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
Last potentially related work creation:
kasan_save_stack+0x33/0x60
kasan_record_aux_stack+0xa7/0xc0
__call_rcu_common.constprop.0+0x80/0x280
destroy_inode+0x131/0x1b0
evict+0x543/0x9f0
iput+0x680/0xb80
ocfs2_dentry_lock_put+0xca/0x230
ocfs2_process_blocked_lock+0x1fb/0x420
ocfs2_downconvert_thread+0x327/0x730
kthread+0x351/0x460
ret_from_fork+0x659/0x940
ret_from_fork_asm+0x1a/0x30
The buggy address belongs to the object at ffff8881100ff000
which belongs to the cache ocfs2_inode_cache of size 3400
The buggy address is located 2184 bytes inside of
freed 3400-byte region [ffff8881100ff000, ffff8881100ffd48)
[page and shadow-memory details omitted]
Fixes: 8ed6b23709b3 ("ocfs2: revert iput deferring code in ocfs2_drop_dentry_lock")
Cc: <stable@vger.kernel.org>
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
Assisted-by: LLM
---
diff --git a/fs/ocfs2/dcache.c b/fs/ocfs2/dcache.c
index e06774fd89d8..e2b560797f17 100644
--- a/fs/ocfs2/dcache.c
+++ b/fs/ocfs2/dcache.c
@@ -354,8 +354,9 @@ out_attach:
static void ocfs2_drop_dentry_lock(struct ocfs2_super *osb,
struct ocfs2_dentry_lock *dl)
{
- iput(dl->dl_inode);
+ /* Keep the inode alive until DENTRY callbacks have completed. */
ocfs2_simple_drop_lockres(osb, &dl->dl_lockres);
+ iput(dl->dl_inode);
ocfs2_lock_res_free(&dl->dl_lockres);
kfree(dl);
}
reply other threads:[~2026-10-15 16:03 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=pm-ocfs2-objects-candidate-0012-v5-a0413a339b72c02fc885@gmail.com \
--to=zzzccc427@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=baijiaju1990@gmail.com \
--cc=heming.zhao@suse.com \
--cc=jack@suse.cz \
--cc=jjzuming@gmail.com \
--cc=jlbec@evilplan.org \
--cc=joseph.qi@linux.alibaba.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mark@fasheh.com \
--cc=ocfs2-devel@lists.linux.dev \
--cc=rgoldwyn@suse.de \
--cc=srinivas.eeda@oracle.com \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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®