mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
sunrpc: defer rq_argp and rq_resp free until after RCU grace period
svc_rqst_free() frees rqstp->rq_argp and rqstp->rq_resp synchronously
via kfree(), but defers the rqstp struct free via kfree_rcu(). After
svc_exit_thread() calls list_del_rcu() and svc_rqst_free(), there is
a window where RCU readers that started before list_del_rcu() can still
traverse the thread list and find the rqstp. These readers (e.g.
nfsd_nl_rpc_status_get_dumpit()) dereference rqstp->rq_argp, which has
already been freed — a use-after-free.
Fix this by moving the kfree of rq_argp and rq_resp into an explicit
call_rcu() callback alongside the struct free. Resources not accessed
by RCU readers (bvec, buffer pages, scratch folio, auth_data) remain
synchronously freed.
Fixes: 812443865c ("sunrpc: add a rcu_head to svc_rqst and use kfree_rcu to free it")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260611-nfsd-testing-v2-4-5b90e276f2d9@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
This commit is contained in:
parent
e13d505af7
commit
c479bde671
|
|
@ -716,6 +716,15 @@ svc_release_buffer(struct svc_rqst *rqstp)
|
|||
}
|
||||
}
|
||||
|
||||
static void svc_rqst_free_rcu(struct rcu_head *head)
|
||||
{
|
||||
struct svc_rqst *rqstp = container_of(head, struct svc_rqst, rq_rcu_head);
|
||||
|
||||
kfree(rqstp->rq_resp);
|
||||
kfree(rqstp->rq_argp);
|
||||
kfree(rqstp);
|
||||
}
|
||||
|
||||
static void
|
||||
svc_rqst_free(struct svc_rqst *rqstp)
|
||||
{
|
||||
|
|
@ -724,10 +733,8 @@ svc_rqst_free(struct svc_rqst *rqstp)
|
|||
svc_release_buffer(rqstp);
|
||||
if (rqstp->rq_scratch_folio)
|
||||
folio_put(rqstp->rq_scratch_folio);
|
||||
kfree(rqstp->rq_resp);
|
||||
kfree(rqstp->rq_argp);
|
||||
kfree(rqstp->rq_auth_data);
|
||||
kfree_rcu(rqstp, rq_rcu_head);
|
||||
call_rcu(&rqstp->rq_rcu_head, svc_rqst_free_rcu);
|
||||
}
|
||||
|
||||
static struct svc_rqst *
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user