Re: [PATCH 6.18.y 3/3] nfsd: release layout stid on setlease failure
"Chuck Lever" <[email protected]>
| Newsgroups | gmane.linux.kernel.stable,gmane.linux.nfs |
|---|---|
| Message-ID | <[email protected]> |
Please note: The correct Author for this patch is "Chris Mason <[email protected]>" On Thu, Jul 2, 2026, at 4:24 PM, Chuck Lever wrote: > commit 30d55c8aabb261bc3f427d6b9aae7ef6206063f9 upstream. > > nfs4_alloc_stid() publishes the new stid into cl->cl_stateids via > idr_alloc_cyclic() under cl_lock before returning to > nfsd4_alloc_layout_stateid(). When nfsd4_layout_setlease() then > fails, the error path frees the layout stateid directly with > kmem_cache_free() without ever calling idr_remove(), leaving the > IDR slot pointing at freed slab memory. Any subsequent IDR walker > (states_show, client teardown) dereferences the dangling pointer. > > The correct teardown for an IDR-published stid is nfs4_put_stid(), > which removes the IDR slot under cl_lock, dispatches sc_free > (nfsd4_free_layout_stateid) to release ls->ls_file via > nfsd4_close_layout(), and drops the nfs4_file reference in its > tail. > > A second issue blocks that switch: nfsd4_free_layout_stateid() > unconditionally inspects ls->ls_fence_work via > delayed_work_pending() under ls_lock, but > INIT_DELAYED_WORK(&ls->ls_fence_work, ...) currently runs only > after the setlease call. On the setlease-failure path the > destructor would touch an uninitialized delayed_work. > > nfsd4_alloc_layout_stateid() > nfs4_alloc_stid() /* idr_alloc_cyclic under cl_lock */ > nfsd4_layout_setlease() /* fails */ > nfs4_put_stid() > nfsd4_free_layout_stateid() > delayed_work_pending(&ls->ls_fence_work) /* needs INIT */ > nfsd4_close_layout() /* nfsd_file_put(ls->ls_file) */ > put_nfs4_file() > > Fix by hoisting the ls_fenced / ls_fence_delay / INIT_DELAYED_WORK > initialization above the nfsd4_layout_setlease() call, and replace > the manual nfsd_file_put + put_nfs4_file + kmem_cache_free cleanup > with a single nfs4_put_stid(stp). > > Fixes: c5c707f96fc9 ("nfsd: implement pNFS layout recalls") > Cc: [email protected] > Assisted-by: kres (claude-opus-4-7) > Signed-off-by: Chris Mason <[email protected]> > Reviewed-by: Jeff Layton <[email protected]> > Signed-off-by: Chuck Lever <[email protected]> > [ cel: drop fence_work init hoist absent from 6.18.y ] > Signed-off-by: Chuck Lever <[email protected]> > --- > fs/nfsd/nfs4layouts.c | 4 +--- > 1 file changed, 1 insertion(+), 3 deletions(-) > > diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c > index 683bd1130afe..62762e43f810 100644 > --- a/fs/nfsd/nfs4layouts.c > +++ b/fs/nfsd/nfs4layouts.c > @@ -256,9 +256,7 @@ nfsd4_alloc_layout_stateid(struct > nfsd4_compound_state *cstate, > BUG_ON(!ls->ls_file); > > if (nfsd4_layout_setlease(ls)) { > - nfsd_file_put(ls->ls_file); > - put_nfs4_file(fp); > - kmem_cache_free(nfs4_layout_stateid_cache, ls); > + nfs4_put_stid(stp); > return NULL; > } > > -- > 2.54.0 -- Chuck Lever