Re: [PATCH v2] ocfs2: rebase copied fsdlm LVB pointers in locking_state
Cen Zhang <[email protected]> Mon, 25 May 2026 11:42:03 +0800
| Newsgroups | dev.linux.lists.ocfs2-devel |
|---|---|
| Message-ID | <CAB7XQsFfaaymc_2B5O0dA6YmR9vGDqXTpM=QvWmSf+g5BNtmxw@mail.gmail.com> |
Hi Joseph, Thanks for checking. Yes, the commit log in v2 was accidentally truncated in a few places. Sorry about that. I'll send a v3 with the commit message fixed. The code change itself is unchanged. Thanks, Zhang Cen Joseph Qi <[email protected]> 于2026年5月25日周一 11:26写道: > > > > On 5/24/26 7:07 PM, Zhang Cen wrote: > > value under ocfs2_dlm_tracking_lock and later formats that copy in > > Seens it is cut off at the beginning? > > > ocfs2_dlm_seq_show(). That is fine for the inline fields, but the > > userspace fsdlm stack stores the LVB through lksb_fsdlm.sb_lvbptr. Once > > the iterator drops the tracking lock, a copied non-NULL sb_lvbptr still > > points into the original lockres owner, so teardown can free that > > > > This is also incomplete. > > > Rebase the copied sb_lvbptr to the copied l_lksb before dumping the raw > > LVB. The seq snapshot already carries the inline LVB storage reserved in > > without borrowing the original lockres lifetime. > > > > The buggy scenario involves two paths, with each column showing the order > > within that path: > > > > locking_state reader: lockres teardown: > > 1. ocfs2_dlm_seq_start()/next() 1. file release or another owner > > copies struct ocfs2_lock_res teardown reaches > > 2. ocfs2_dlm_seq_show() formats ocfs2_lock_res_free() > > the copied row 2. the lockres is removed from the > > 3. ocfs2_dlm_lvb() follows the tracking list > > copied sb_lvbptr 3. the owner frees the original > > lockres container > > > > Validation reproduced this kernel report: > > KASAN slab-use-after-free in ocfs2_dlm_seq_show+0x1bd/0x430 > > RIP: 0033:0x7f8ec4b1e29d > > The buggy address belongs to the object at ffff88810a1e0800 which belongs > > > > And here. > > Thanks, > Joseph > > > Fixes: cf4d8d75d8ab ("ocfs2: add fsdlm to stackglue") > > Assisted-by: Codex:gpt-5.5 > > Signed-off-by: Zhang Cen <[email protected]> > > --- > > v2: > > Document the introducing fsdlm stackglue commit. > > > > fs/ocfs2/dlmglue.c | 17 +++++++++++++++++ > > 1 file changed, 17 insertions(+) > > > > diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c > > index 7283bb2c5a31..a23dd8f86c89 100644 > > --- a/fs/ocfs2/dlmglue.c > > +++ b/fs/ocfs2/dlmglue.c > > @@ -3134,6 +3134,22 @@ static void *ocfs2_dlm_seq_next(struct seq_file *m, void *v, loff_t *pos) > > * - Add last pr/ex unlock times and first lock wait time in usecs > > */ > > #define OCFS2_DLM_DEBUG_STR_VERSION 4 > > + > > +/* > > + * The debug iterator snapshots lockres by value, so a userspace-stack LVB > > + * pointer copied from the original lockres must be rebased to the copied > > + * lksb before the dump walks the raw bytes. > > + */ > > +static void ocfs2_dlm_seq_rebase_lvb(struct ocfs2_lock_res *lockres) > > +{ > > + if (!ocfs2_stack_supports_plocks()) > > + return; > > + > > + if (lockres->l_lksb.lksb_fsdlm.sb_lvbptr) > > + lockres->l_lksb.lksb_fsdlm.sb_lvbptr = > > + (char *)&lockres->l_lksb + sizeof(struct dlm_lksb); > > +} > > + > > static int ocfs2_dlm_seq_show(struct seq_file *m, void *v) > > { > > int i; > > @@ -3191,6 +3207,7 @@ static int ocfs2_dlm_seq_show(struct seq_file *m, void *v) > > lockres->l_blocking); > > > > /* Dump the raw LVB */ > > + ocfs2_dlm_seq_rebase_lvb(lockres); > > lvb = ocfs2_dlm_lvb(&lockres->l_lksb); > > for(i = 0; i < DLM_LVB_LEN; i++) > > seq_printf(m, "0x%x\t", lvb[i]); >