SUNRPC: Fix a use after free when a server rejects the RPCSEC_GSS credential
The addition of rpc_check_timeout() to call_decode causes an Oops
when the RPCSEC_GSS credential is rejected.
The reason is that rpc_decode_header() will call xprt_release() in
order to free task->tk_rqstp, which is needed by rpc_check_timeout()
to check whether or not we should exit due to a soft timeout.
The fix is to move the call to xprt_release() into call_decode() so
we can perform it after rpc_check_timeout().
Reported-by: Olga Kornievskaia <olga.kornievskaia@gmail.com>
Reported-by: Nick Bowler <nbowler@draconx.ca>
Fixes: cea57789e4
("SUNRPC: Clean up")
Cc: stable@vger.kernel.org # v5.1+
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
parent
ec6017d903
commit
7987b694ad
|
@ -2426,17 +2426,21 @@ call_decode(struct rpc_task *task)
|
||||||
return;
|
return;
|
||||||
case -EAGAIN:
|
case -EAGAIN:
|
||||||
task->tk_status = 0;
|
task->tk_status = 0;
|
||||||
/* Note: rpc_decode_header() may have freed the RPC slot */
|
xdr_free_bvec(&req->rq_rcv_buf);
|
||||||
if (task->tk_rqstp == req) {
|
req->rq_reply_bytes_recvd = 0;
|
||||||
xdr_free_bvec(&req->rq_rcv_buf);
|
req->rq_rcv_buf.len = 0;
|
||||||
req->rq_reply_bytes_recvd = 0;
|
if (task->tk_client->cl_discrtry)
|
||||||
req->rq_rcv_buf.len = 0;
|
xprt_conditional_disconnect(req->rq_xprt,
|
||||||
if (task->tk_client->cl_discrtry)
|
req->rq_connect_cookie);
|
||||||
xprt_conditional_disconnect(req->rq_xprt,
|
|
||||||
req->rq_connect_cookie);
|
|
||||||
}
|
|
||||||
task->tk_action = call_encode;
|
task->tk_action = call_encode;
|
||||||
rpc_check_timeout(task);
|
rpc_check_timeout(task);
|
||||||
|
break;
|
||||||
|
case -EKEYREJECTED:
|
||||||
|
task->tk_action = call_reserve;
|
||||||
|
rpc_check_timeout(task);
|
||||||
|
rpcauth_invalcred(task);
|
||||||
|
/* Ensure we obtain a new XID if we retry! */
|
||||||
|
xprt_release(task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2572,11 +2576,7 @@ out_msg_denied:
|
||||||
break;
|
break;
|
||||||
task->tk_cred_retry--;
|
task->tk_cred_retry--;
|
||||||
trace_rpc__stale_creds(task);
|
trace_rpc__stale_creds(task);
|
||||||
rpcauth_invalcred(task);
|
return -EKEYREJECTED;
|
||||||
/* Ensure we obtain a new XID! */
|
|
||||||
xprt_release(task);
|
|
||||||
task->tk_action = call_reserve;
|
|
||||||
return -EAGAIN;
|
|
||||||
case rpc_autherr_badcred:
|
case rpc_autherr_badcred:
|
||||||
case rpc_autherr_badverf:
|
case rpc_autherr_badverf:
|
||||||
/* possibly garbled cred/verf? */
|
/* possibly garbled cred/verf? */
|
||||||
|
|
Loading…
Reference in New Issue