Commit 7987b694 authored by Trond Myklebust's avatar Trond Myklebust Committed by Anna Schumaker

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: default avatarOlga Kornievskaia <olga.kornievskaia@gmail.com>
Reported-by: default avatarNick Bowler <nbowler@draconx.ca>
Fixes: cea57789 ("SUNRPC: Clean up")
Cc: stable@vger.kernel.org # v5.1+
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent ec6017d9
...@@ -2426,17 +2426,21 @@ call_decode(struct rpc_task *task) ...@@ -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 @@ rpc_decode_header(struct rpc_task *task, struct xdr_stream *xdr) ...@@ -2572,11 +2576,7 @@ rpc_decode_header(struct rpc_task *task, struct xdr_stream *xdr)
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? */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment