SUNRPC: Move fault injection call sites
[ Upstream commit7638e0bfae] I've hit some crashes that occur in the xprt_rdma_inject_disconnect path. It appears that, for some provides, rdma_disconnect() can take so long that the transport can disconnect and release its hardware resources while rdma_disconnect() is still running, resulting in a UAF in the provider. The transport's fault injection method may depend on the stability of transport data structures. That means it needs to be invoked only from contexts that hold the transport write lock. Fixes:4a06825839("SUNRPC: Transport fault injection") Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
bfeb4e607d
commit
7b906077fd
3 changed files with 8 additions and 5 deletions
|
|
@ -1802,7 +1802,6 @@ call_allocate(struct rpc_task *task)
|
|||
|
||||
status = xprt->ops->buf_alloc(task);
|
||||
trace_rpc_buf_alloc(task, status);
|
||||
xprt_inject_disconnect(xprt);
|
||||
if (status == 0)
|
||||
return;
|
||||
if (status != -ENOMEM) {
|
||||
|
|
|
|||
|
|
@ -1455,7 +1455,10 @@ bool xprt_prepare_transmit(struct rpc_task *task)
|
|||
|
||||
void xprt_end_transmit(struct rpc_task *task)
|
||||
{
|
||||
xprt_release_write(task->tk_rqstp->rq_xprt, task);
|
||||
struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt;
|
||||
|
||||
xprt_inject_disconnect(xprt);
|
||||
xprt_release_write(xprt, task);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1857,7 +1860,6 @@ void xprt_release(struct rpc_task *task)
|
|||
spin_unlock(&xprt->transport_lock);
|
||||
if (req->rq_buffer)
|
||||
xprt->ops->buf_free(task);
|
||||
xprt_inject_disconnect(xprt);
|
||||
xdr_free_bvec(&req->rq_rcv_buf);
|
||||
xdr_free_bvec(&req->rq_snd_buf);
|
||||
if (req->rq_cred != NULL)
|
||||
|
|
|
|||
|
|
@ -262,8 +262,10 @@ xprt_rdma_connect_worker(struct work_struct *work)
|
|||
* xprt_rdma_inject_disconnect - inject a connection fault
|
||||
* @xprt: transport context
|
||||
*
|
||||
* If @xprt is connected, disconnect it to simulate spurious connection
|
||||
* loss.
|
||||
* If @xprt is connected, disconnect it to simulate spurious
|
||||
* connection loss. Caller must hold @xprt's send lock to
|
||||
* ensure that data structures and hardware resources are
|
||||
* stable during the rdma_disconnect() call.
|
||||
*/
|
||||
static void
|
||||
xprt_rdma_inject_disconnect(struct rpc_xprt *xprt)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue