mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	SUNRPC: Handle zero length fragments correctly
A zero length fragment is really a bug, but let's ensure we don't go nuts when one turns up. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
This commit is contained in:
		
							parent
							
								
									ae05355151
								
							
						
					
					
						commit
						e92053a52e
					
				
					 1 changed files with 29 additions and 14 deletions
				
			
		| 
						 | 
					@ -405,8 +405,8 @@ xs_read_xdr_buf(struct socket *sock, struct msghdr *msg, int flags,
 | 
				
			||||||
	size_t want, seek_init = seek, offset = 0;
 | 
						size_t want, seek_init = seek, offset = 0;
 | 
				
			||||||
	ssize_t ret;
 | 
						ssize_t ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (seek < buf->head[0].iov_len) {
 | 
						want = min_t(size_t, count, buf->head[0].iov_len);
 | 
				
			||||||
		want = min_t(size_t, count, buf->head[0].iov_len);
 | 
						if (seek < want) {
 | 
				
			||||||
		ret = xs_read_kvec(sock, msg, flags, &buf->head[0], want, seek);
 | 
							ret = xs_read_kvec(sock, msg, flags, &buf->head[0], want, seek);
 | 
				
			||||||
		if (ret <= 0)
 | 
							if (ret <= 0)
 | 
				
			||||||
			goto sock_err;
 | 
								goto sock_err;
 | 
				
			||||||
| 
						 | 
					@ -417,8 +417,8 @@ xs_read_xdr_buf(struct socket *sock, struct msghdr *msg, int flags,
 | 
				
			||||||
			goto out;
 | 
								goto out;
 | 
				
			||||||
		seek = 0;
 | 
							seek = 0;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		seek -= buf->head[0].iov_len;
 | 
							seek -= want;
 | 
				
			||||||
		offset += buf->head[0].iov_len;
 | 
							offset += want;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	want = xs_alloc_sparse_pages(buf,
 | 
						want = xs_alloc_sparse_pages(buf,
 | 
				
			||||||
| 
						 | 
					@ -443,8 +443,8 @@ xs_read_xdr_buf(struct socket *sock, struct msghdr *msg, int flags,
 | 
				
			||||||
		offset += want;
 | 
							offset += want;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (seek < buf->tail[0].iov_len) {
 | 
						want = min_t(size_t, count - offset, buf->tail[0].iov_len);
 | 
				
			||||||
		want = min_t(size_t, count - offset, buf->tail[0].iov_len);
 | 
						if (seek < want) {
 | 
				
			||||||
		ret = xs_read_kvec(sock, msg, flags, &buf->tail[0], want, seek);
 | 
							ret = xs_read_kvec(sock, msg, flags, &buf->tail[0], want, seek);
 | 
				
			||||||
		if (ret <= 0)
 | 
							if (ret <= 0)
 | 
				
			||||||
			goto sock_err;
 | 
								goto sock_err;
 | 
				
			||||||
| 
						 | 
					@ -454,7 +454,7 @@ xs_read_xdr_buf(struct socket *sock, struct msghdr *msg, int flags,
 | 
				
			||||||
		if (ret != want)
 | 
							if (ret != want)
 | 
				
			||||||
			goto out;
 | 
								goto out;
 | 
				
			||||||
	} else
 | 
						} else
 | 
				
			||||||
		offset += buf->tail[0].iov_len;
 | 
							offset = seek_init;
 | 
				
			||||||
	ret = -EMSGSIZE;
 | 
						ret = -EMSGSIZE;
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
	*read = offset - seek_init;
 | 
						*read = offset - seek_init;
 | 
				
			||||||
| 
						 | 
					@ -482,6 +482,14 @@ xs_read_stream_request_done(struct sock_xprt *transport)
 | 
				
			||||||
	return transport->recv.fraghdr & cpu_to_be32(RPC_LAST_STREAM_FRAGMENT);
 | 
						return transport->recv.fraghdr & cpu_to_be32(RPC_LAST_STREAM_FRAGMENT);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					xs_read_stream_check_eor(struct sock_xprt *transport,
 | 
				
			||||||
 | 
							struct msghdr *msg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (xs_read_stream_request_done(transport))
 | 
				
			||||||
 | 
							msg->msg_flags |= MSG_EOR;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static ssize_t
 | 
					static ssize_t
 | 
				
			||||||
xs_read_stream_request(struct sock_xprt *transport, struct msghdr *msg,
 | 
					xs_read_stream_request(struct sock_xprt *transport, struct msghdr *msg,
 | 
				
			||||||
		int flags, struct rpc_rqst *req)
 | 
							int flags, struct rpc_rqst *req)
 | 
				
			||||||
| 
						 | 
					@ -493,17 +501,24 @@ xs_read_stream_request(struct sock_xprt *transport, struct msghdr *msg,
 | 
				
			||||||
	xs_read_header(transport, buf);
 | 
						xs_read_header(transport, buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	want = transport->recv.len - transport->recv.offset;
 | 
						want = transport->recv.len - transport->recv.offset;
 | 
				
			||||||
	ret = xs_read_xdr_buf(transport->sock, msg, flags, buf,
 | 
						if (want != 0) {
 | 
				
			||||||
			transport->recv.copied + want, transport->recv.copied,
 | 
							ret = xs_read_xdr_buf(transport->sock, msg, flags, buf,
 | 
				
			||||||
			&read);
 | 
									transport->recv.copied + want,
 | 
				
			||||||
	transport->recv.offset += read;
 | 
									transport->recv.copied,
 | 
				
			||||||
	transport->recv.copied += read;
 | 
									&read);
 | 
				
			||||||
 | 
							transport->recv.offset += read;
 | 
				
			||||||
 | 
							transport->recv.copied += read;
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
							read = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (transport->recv.offset == transport->recv.len) {
 | 
						if (transport->recv.offset == transport->recv.len) {
 | 
				
			||||||
		if (xs_read_stream_request_done(transport))
 | 
							xs_read_stream_check_eor(transport, msg);
 | 
				
			||||||
			msg->msg_flags |= MSG_EOR;
 | 
					 | 
				
			||||||
		return read;
 | 
							return read;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (want == 0)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (ret) {
 | 
						switch (ret) {
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue