diff options
author | Trond Myklebust <trondmy@gmail.com> | 2019-09-16 09:12:19 -0400 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2019-09-20 15:15:24 -0400 |
commit | 9ba828861c56a21d211d5d10f5643774b1ea330d (patch) | |
tree | 45468b00aca4baedcad2cbbd9c6ed5fba9c0bd21 | |
parent | f925ab926d1a9c2112d34ecb59fbb050bb58646c (diff) |
SUNRPC: Don't try to parse incomplete RPC messages
If the copy of the RPC reply into our buffers did not complete, and
we could end up with a truncated message. In that case, just resend
the call.
Fixes: a0584ee9aed80 ("SUNRPC: Use struct xdr_stream when decoding...")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
-rw-r--r-- | net/sunrpc/clnt.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 44d5cf318813..8b622ceb1158 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -2465,6 +2465,7 @@ call_decode(struct rpc_task *task) | |||
2465 | struct rpc_clnt *clnt = task->tk_client; | 2465 | struct rpc_clnt *clnt = task->tk_client; |
2466 | struct rpc_rqst *req = task->tk_rqstp; | 2466 | struct rpc_rqst *req = task->tk_rqstp; |
2467 | struct xdr_stream xdr; | 2467 | struct xdr_stream xdr; |
2468 | int err; | ||
2468 | 2469 | ||
2469 | dprint_status(task); | 2470 | dprint_status(task); |
2470 | 2471 | ||
@@ -2487,6 +2488,15 @@ call_decode(struct rpc_task *task) | |||
2487 | * before it changed req->rq_reply_bytes_recvd. | 2488 | * before it changed req->rq_reply_bytes_recvd. |
2488 | */ | 2489 | */ |
2489 | smp_rmb(); | 2490 | smp_rmb(); |
2491 | |||
2492 | /* | ||
2493 | * Did we ever call xprt_complete_rqst()? If not, we should assume | ||
2494 | * the message is incomplete. | ||
2495 | */ | ||
2496 | err = -EAGAIN; | ||
2497 | if (!req->rq_reply_bytes_recvd) | ||
2498 | goto out; | ||
2499 | |||
2490 | req->rq_rcv_buf.len = req->rq_private_buf.len; | 2500 | req->rq_rcv_buf.len = req->rq_private_buf.len; |
2491 | 2501 | ||
2492 | /* Check that the softirq receive buffer is valid */ | 2502 | /* Check that the softirq receive buffer is valid */ |
@@ -2495,7 +2505,9 @@ call_decode(struct rpc_task *task) | |||
2495 | 2505 | ||
2496 | xdr_init_decode(&xdr, &req->rq_rcv_buf, | 2506 | xdr_init_decode(&xdr, &req->rq_rcv_buf, |
2497 | req->rq_rcv_buf.head[0].iov_base, req); | 2507 | req->rq_rcv_buf.head[0].iov_base, req); |
2498 | switch (rpc_decode_header(task, &xdr)) { | 2508 | err = rpc_decode_header(task, &xdr); |
2509 | out: | ||
2510 | switch (err) { | ||
2499 | case 0: | 2511 | case 0: |
2500 | task->tk_action = rpc_exit_task; | 2512 | task->tk_action = rpc_exit_task; |
2501 | task->tk_status = rpcauth_unwrap_resp(task, &xdr); | 2513 | task->tk_status = rpcauth_unwrap_resp(task, &xdr); |