mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
sunrpc: harden rq_procinfo lifecycle to prevent double-free
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: d9adbb6e10 ("sunrpc: delay pc_release callback until after the reply is sent")
Cc: stable@vger.kernel.org
Reported-by: Yuan Tan <yuantan098@gmail.com>
Reported-by: Yifan Wu <yifanwucs@gmail.com>
Reported-by: Juefei Pu <tomapufckgml@gmail.com>
Reported-by: Xin Liu <bird@lzu.edu.cn>
Suggested-by: Chuck Lever <cel@kernel.org>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Luxiao Xu <rakukuip@gmail.com>
Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
parent
18c1cc6988
commit
18d216788b
|
|
@ -1598,6 +1598,12 @@ static void svc_release_rqst(struct svc_rqst *rqstp)
|
|||
|
||||
if (procp && procp->pc_release)
|
||||
procp->pc_release(rqstp);
|
||||
|
||||
/*
|
||||
* A subsequent svc_release_rqst() on this rqstp must not
|
||||
* re-invoke pc_release against released state.
|
||||
*/
|
||||
rqstp->rq_procinfo = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1616,6 +1622,9 @@ void svc_process(struct svc_rqst *rqstp)
|
|||
svc_xprt_deferred_close(rqstp->rq_xprt);
|
||||
#endif
|
||||
|
||||
/* Discard a stale release hook from a previous RPC. */
|
||||
rqstp->rq_procinfo = NULL;
|
||||
|
||||
/*
|
||||
* Setup response xdr_buf.
|
||||
* Initially it has just one page
|
||||
|
|
@ -1672,6 +1681,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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user