[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20190609164129.387769377@linuxfoundation.org>
Date: Sun, 9 Jun 2019 18:41:39 +0200
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
stable@...r.kernel.org,
Olga Kornievskaia <olga.kornievskaia@...il.com>,
Nick Bowler <nbowler@...conx.ca>,
Trond Myklebust <trond.myklebust@...merspace.com>,
Anna Schumaker <Anna.Schumaker@...app.com>
Subject: [PATCH 5.1 28/70] SUNRPC: Fix a use after free when a server rejects the RPCSEC_GSS credential
From: Trond Myklebust <trond.myklebust@...merspace.com>
commit 7987b694ade8cc465ce10fb3dceaa614f13ceaf3 upstream.
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@...il.com>
Reported-by: Nick Bowler <nbowler@...conx.ca>
Fixes: cea57789e408 ("SUNRPC: Clean up")
Cc: stable@...r.kernel.org # v5.1+
Signed-off-by: Trond Myklebust <trond.myklebust@...merspace.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@...app.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
---
net/sunrpc/clnt.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -2387,17 +2387,21 @@ call_decode(struct rpc_task *task)
return;
case -EAGAIN:
task->tk_status = 0;
- /* Note: rpc_decode_header() may have freed the RPC slot */
- if (task->tk_rqstp == req) {
- xdr_free_bvec(&req->rq_rcv_buf);
- req->rq_reply_bytes_recvd = 0;
- req->rq_rcv_buf.len = 0;
- if (task->tk_client->cl_discrtry)
- xprt_conditional_disconnect(req->rq_xprt,
- req->rq_connect_cookie);
- }
+ xdr_free_bvec(&req->rq_rcv_buf);
+ req->rq_reply_bytes_recvd = 0;
+ req->rq_rcv_buf.len = 0;
+ if (task->tk_client->cl_discrtry)
+ xprt_conditional_disconnect(req->rq_xprt,
+ req->rq_connect_cookie);
task->tk_action = call_encode;
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);
}
}
@@ -2533,11 +2537,7 @@ out_msg_denied:
break;
task->tk_cred_retry--;
trace_rpc__stale_creds(task);
- rpcauth_invalcred(task);
- /* Ensure we obtain a new XID! */
- xprt_release(task);
- task->tk_action = call_reserve;
- return -EAGAIN;
+ return -EKEYREJECTED;
case rpc_autherr_badcred:
case rpc_autherr_badverf:
/* possibly garbled cred/verf? */
Powered by blists - more mailing lists