Thread (3 messages) 3 messages, 3 authors, 2026-05-21

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>
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help