Commit 334ccfd5 authored by Trond Myklebust's avatar Trond Myklebust

[PATCH] RPC: Ensure XDR iovec length is initialized correctly in call_header

 Fix up call_header() so that it calls xdr_adjust_iovec().
 Fix calculation of the scratch buffer length in xdr_init_encode().
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent d05fdb0c
...@@ -957,7 +957,9 @@ call_header(struct rpc_task *task) ...@@ -957,7 +957,9 @@ call_header(struct rpc_task *task)
*p++ = htonl(clnt->cl_prog); /* program number */ *p++ = htonl(clnt->cl_prog); /* program number */
*p++ = htonl(clnt->cl_vers); /* program version */ *p++ = htonl(clnt->cl_vers); /* program version */
*p++ = htonl(task->tk_msg.rpc_proc->p_proc); /* procedure */ *p++ = htonl(task->tk_msg.rpc_proc->p_proc); /* procedure */
return rpcauth_marshcred(task, p); p = rpcauth_marshcred(task, p);
req->rq_slen = xdr_adjust_iovec(&req->rq_svec[0], p);
return p;
} }
/* /*
......
...@@ -281,6 +281,7 @@ svc_process(struct svc_serv *serv, struct svc_rqst *rqstp) ...@@ -281,6 +281,7 @@ svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
rqstp->rq_res.len = 0; rqstp->rq_res.len = 0;
rqstp->rq_res.page_base = 0; rqstp->rq_res.page_base = 0;
rqstp->rq_res.page_len = 0; rqstp->rq_res.page_len = 0;
rqstp->rq_res.buflen = PAGE_SIZE;
rqstp->rq_res.tail[0].iov_len = 0; rqstp->rq_res.tail[0].iov_len = 0;
/* tcp needs a space for the record length... */ /* tcp needs a space for the record length... */
if (rqstp->rq_prot == IPPROTO_TCP) if (rqstp->rq_prot == IPPROTO_TCP)
......
...@@ -616,12 +616,24 @@ xdr_shift_buf(struct xdr_buf *buf, size_t len) ...@@ -616,12 +616,24 @@ xdr_shift_buf(struct xdr_buf *buf, size_t len)
void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p) void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p)
{ {
struct kvec *iov = buf->head; struct kvec *iov = buf->head;
int scratch_len = buf->buflen - buf->page_len - buf->tail[0].iov_len;
BUG_ON(scratch_len < 0);
xdr->buf = buf; xdr->buf = buf;
xdr->iov = iov; xdr->iov = iov;
xdr->end = (uint32_t *)((char *)iov->iov_base + iov->iov_len); xdr->p = (uint32_t *)((char *)iov->iov_base + iov->iov_len);
buf->len = iov->iov_len = (char *)p - (char *)iov->iov_base; xdr->end = (uint32_t *)((char *)iov->iov_base + scratch_len);
xdr->p = p; BUG_ON(iov->iov_len > scratch_len);
if (p != xdr->p && p != NULL) {
size_t len;
BUG_ON(p < xdr->p || p > xdr->end);
len = (char *)p - (char *)xdr->p;
xdr->p = p;
buf->len += len;
iov->iov_len += len;
}
} }
EXPORT_SYMBOL(xdr_init_encode); EXPORT_SYMBOL(xdr_init_encode);
......
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