From 650d370cfbc66a96dd14d517bd704689b5bda4e5 Mon Sep 17 00:00:00 2001 From: Zhenghang Xiao Date: Tue, 26 May 2026 18:45:54 +0800 Subject: nfsd: set SC_STATUS_FREED in nfsd4_drop_revoked_stid for delegations nfsd4_drop_revoked_stid() handles FREE_STATEID for admin-revoked delegations but does not set SC_STATUS_FREED before releasing cl_lock. revoke_delegation() uses this flag to detect whether FREE_STATEID has already processed the delegation -- without it, the freed delegation is added to cl_revoked via list_add(), producing a use-after-free when cl_revoked is later traversed in __destroy_client(). The SC_STATUS_REVOKED path in nfsd4_free_stateid() (line 7983) already sets SC_STATUS_FREED correctly. Apply the same pattern to the SC_STATUS_ADMIN_REVOKED path in nfsd4_drop_revoked_stid(). Fixes: 8dd91e8d31fe ("nfsd: fix race between laundromat and free_stateid") Cc: stable@vger.kernel.org Signed-off-by: Zhenghang Xiao Reviewed-by: Jeff Layton Link: https://patch.msgid.link/20260526104554.46262-1-kipreyyy@gmail.com Signed-off-by: Chuck Lever --- fs/nfsd/nfs4state.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index a4e3ef1b6763..8f90fba53357 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -5172,6 +5172,7 @@ static void nfsd4_drop_revoked_stid(struct nfs4_stid *s) case SC_TYPE_DELEG: dp = delegstateid(s); list_del_init(&dp->dl_recall_lru); + s->sc_status |= SC_STATUS_FREED; spin_unlock(&cl->cl_lock); nfs4_put_stid(s); break; -- cgit v1.2.3