Re: [PATCH v2 1/1] sunrpc: harden rq_procinfo lifecycle to prevent double-free
From: Jeff Layton <jlayton@kernel.org>
Date: 2026-05-21 13:36:28
Also in:
linux-nfs
On Thu, 2026-05-21 at 15:06 +0800, Ren Wei wrote:
quoted hunk ↗ jump to hunk
From: Luxiao Xu <redacted> The svc_release_rqst() function executes the callback inside rqstp->rq_procinfo->pc_release. However, if a worker thread begins processing a new request and encounters an early error path (e.g., unsupported protocol, short frame, or bad auth) before a valid rq_procinfo is installed, a stale release hook can be re-triggered against reused state from the previous RPC, resulting in a double-free or use-after-free vulnerability. Harden the lifecycle of rq_procinfo by: 1. Ensuring svc_release_rqst() always clears rq_procinfo after the optional pc_release() call, regardless of whether the hook exists. 2. Explicitly clearing rq_procinfo at request entry in svc_process() before any early decode or drop paths. 3. Ensuring svc_process_bc() does the same at backchannel entry. This guarantees that error flows will not encounter a non-NULL stale rq_procinfo pointer when there is nothing to release. Fixes: d9adbb6e10bf ("sunrpc: delay pc_release callback until after the reply is sent") Cc: stable@kernel.org Reported-by: Yuan Tan <redacted> Reported-by: Yifan Wu <redacted> Reported-by: Juefei Pu <redacted> Reported-by: Xin Liu <redacted> Suggested-by: Chuck Lever <cel@kernel.org> Signed-off-by: Luxiao Xu <redacted> Signed-off-by: Ren Wei <redacted> --- changes in v2: - Extended the fix to clear rq_procinfo at request entries (both in svc_process and svc_process_bc) before early decode/drop paths. - Moved the pointer clearing in svc_release_rqst outside the conditional block to ensure it always clears, as suggested by Chuck. - v1 Link: https://lore.kernel.org/all/8c4cfe3656a817a64da9cf62e42282a1f308b9dd.1779253342.git.rakukuip@gmail.com/ (local) --- net/sunrpc/svc.c | 4 ++++ 1 file changed, 4 insertions(+)diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index d8ccb8e4b5c2..67933c10fe5a 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c@@ -1574,6 +1574,8 @@ static void svc_release_rqst(struct svc_rqst *rqstp) if (procp && procp->pc_release) procp->pc_release(rqstp); + + rqstp->rq_procinfo = NULL; } /**@@ -1596,6 +1598,7 @@ void svc_process(struct svc_rqst *rqstp) * Setup response xdr_buf. * Initially it has just one page */ + rqstp->rq_procinfo = NULL; rqstp->rq_next_page = &rqstp->rq_respages[1]; resv->iov_base = page_address(rqstp->rq_respages[0]); resv->iov_len = 0;@@ -1648,6 +1651,7 @@ void svc_process_bc(struct rpc_rqst *req, struct svc_rqst *rqstp) int proc_error; /* Build the svc_rqst used by the common processing routine */ + rqstp->rq_procinfo = NULL; rqstp->rq_xid = req->rq_xid; rqstp->rq_prot = req->rq_xprt->prot; rqstp->rq_bc_net = req->rq_xprt->xprt_net;
Reviewed-by: Jeff Layton <jlayton@kernel.org>