From 78c8f2cf802eb8d52d14dad4abaa71178d7413d4 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 9 Oct 2006 22:08:22 -0400 Subject: [PATCH] --- yaml --- r: 42508 b: refs/heads/master c: bee57c99c322d64407b80c8171958b4384902da4 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/net/sunrpc/xdr.c | 59 +++++++++++++++++++----------------------- 2 files changed, 27 insertions(+), 34 deletions(-) diff --git a/[refs] b/[refs] index 99fdf572e831..182bff4ce1bd 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 4e3e43ad14c574281034a27420abf1993694ac11 +refs/heads/master: bee57c99c322d64407b80c8171958b4384902da4 diff --git a/trunk/net/sunrpc/xdr.c b/trunk/net/sunrpc/xdr.c index ebdff6beba31..5a6485946f3c 100644 --- a/trunk/net/sunrpc/xdr.c +++ b/trunk/net/sunrpc/xdr.c @@ -773,44 +773,37 @@ xdr_encode_word(struct xdr_buf *buf, unsigned int base, u32 obj) * entirely in the head or the tail, set object to point to it; otherwise * try to find space for it at the end of the tail, copy it there, and * set obj to point to it. */ -int -xdr_buf_read_netobj(struct xdr_buf *buf, struct xdr_netobj *obj, unsigned int offset) +int xdr_buf_read_netobj(struct xdr_buf *buf, struct xdr_netobj *obj, unsigned int offset) { - unsigned int tail_offset = buf->head[0].iov_len + buf->page_len; - unsigned int obj_end_offset; + struct xdr_buf subbuf; if (xdr_decode_word(buf, offset, &obj->len)) - goto out; - obj_end_offset = offset + 4 + obj->len; - - if (obj_end_offset <= buf->head[0].iov_len) { - /* The obj is contained entirely in the head: */ - obj->data = buf->head[0].iov_base + offset + 4; - } else if (offset + 4 >= tail_offset) { - if (obj_end_offset - tail_offset - > buf->tail[0].iov_len) - goto out; - /* The obj is contained entirely in the tail: */ - obj->data = buf->tail[0].iov_base - + offset - tail_offset + 4; - } else { - /* use end of tail as storage for obj: - * (We don't copy to the beginning because then we'd have - * to worry about doing a potentially overlapping copy. - * This assumes the object is at most half the length of the - * tail.) */ - if (obj->len > buf->tail[0].iov_len) - goto out; - obj->data = buf->tail[0].iov_base + buf->tail[0].iov_len - - obj->len; - if (read_bytes_from_xdr_buf(buf, offset + 4, - obj->data, obj->len)) - goto out; + return -EFAULT; + if (xdr_buf_subsegment(buf, &subbuf, offset + 4, obj->len)) + return -EFAULT; - } + /* Is the obj contained entirely in the head? */ + obj->data = subbuf.head[0].iov_base; + if (subbuf.head[0].iov_len == obj->len) + return 0; + /* ..or is the obj contained entirely in the tail? */ + obj->data = subbuf.tail[0].iov_base; + if (subbuf.tail[0].iov_len == obj->len) + return 0; + + /* use end of tail as storage for obj: + * (We don't copy to the beginning because then we'd have + * to worry about doing a potentially overlapping copy. + * This assumes the object is at most half the length of the + * tail.) */ + if (obj->len > buf->buflen - buf->len) + return -ENOMEM; + if (buf->tail[0].iov_len != 0) + obj->data = buf->tail[0].iov_base + buf->tail[0].iov_len; + else + obj->data = buf->head[0].iov_base + buf->head[0].iov_len; + __read_bytes_from_xdr_buf(&subbuf, obj->data, obj->len); return 0; -out: - return -1; } /* Returns 0 on success, or else a negative error code. */