mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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: a0584ee9ae ("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>
			
			
This commit is contained in:
		
							parent
							
								
									f925ab926d
								
							
						
					
					
						commit
						9ba828861c
					
				
					 1 changed files with 13 additions and 1 deletions
				
			
		| 
						 | 
					@ -2465,6 +2465,7 @@ call_decode(struct rpc_task *task)
 | 
				
			||||||
	struct rpc_clnt	*clnt = task->tk_client;
 | 
						struct rpc_clnt	*clnt = task->tk_client;
 | 
				
			||||||
	struct rpc_rqst	*req = task->tk_rqstp;
 | 
						struct rpc_rqst	*req = task->tk_rqstp;
 | 
				
			||||||
	struct xdr_stream xdr;
 | 
						struct xdr_stream xdr;
 | 
				
			||||||
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dprint_status(task);
 | 
						dprint_status(task);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2487,6 +2488,15 @@ call_decode(struct rpc_task *task)
 | 
				
			||||||
	 * before it changed req->rq_reply_bytes_recvd.
 | 
						 * before it changed req->rq_reply_bytes_recvd.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	smp_rmb();
 | 
						smp_rmb();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Did we ever call xprt_complete_rqst()? If not, we should assume
 | 
				
			||||||
 | 
						 * the message is incomplete.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						err = -EAGAIN;
 | 
				
			||||||
 | 
						if (!req->rq_reply_bytes_recvd)
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	req->rq_rcv_buf.len = req->rq_private_buf.len;
 | 
						req->rq_rcv_buf.len = req->rq_private_buf.len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Check that the softirq receive buffer is valid */
 | 
						/* Check that the softirq receive buffer is valid */
 | 
				
			||||||
| 
						 | 
					@ -2495,7 +2505,9 @@ call_decode(struct rpc_task *task)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	xdr_init_decode(&xdr, &req->rq_rcv_buf,
 | 
						xdr_init_decode(&xdr, &req->rq_rcv_buf,
 | 
				
			||||||
			req->rq_rcv_buf.head[0].iov_base, req);
 | 
								req->rq_rcv_buf.head[0].iov_base, req);
 | 
				
			||||||
	switch (rpc_decode_header(task, &xdr)) {
 | 
						err = rpc_decode_header(task, &xdr);
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						switch (err) {
 | 
				
			||||||
	case 0:
 | 
						case 0:
 | 
				
			||||||
		task->tk_action = rpc_exit_task;
 | 
							task->tk_action = rpc_exit_task;
 | 
				
			||||||
		task->tk_status = rpcauth_unwrap_resp(task, &xdr);
 | 
							task->tk_status = rpcauth_unwrap_resp(task, &xdr);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue