From: Andreas Gruenbacher <agruen@suse.de>

The bounds check in xdr_xcode_array2 can overflow.  Reported by Florian
Weimer <fw@deneb.enyo.de>.

Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Cc: Trond Myklebust <trond.myklebust@fys.uio.no>
Cc: Neil Brown <neilb@cse.unsw.edu.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 net/sunrpc/xdr.c |    7 +++----
 1 files changed, 3 insertions(+), 4 deletions(-)

diff -puN net/sunrpc/xdr.c~xdr-input-validation net/sunrpc/xdr.c
--- 25/net/sunrpc/xdr.c~xdr-input-validation	Fri Jun 24 17:04:17 2005
+++ 25-akpm/net/sunrpc/xdr.c	Fri Jun 24 17:04:17 2005
@@ -993,8 +993,7 @@ xdr_xcode_array2(struct xdr_buf *buf, un
 			return -EINVAL;
 	} else {
 		if (xdr_decode_word(buf, base, &desc->array_len) != 0 ||
-		    (unsigned long) base + 4 + desc->array_len *
-				    desc->elem_size > buf->len)
+		    desc->array_len > (buf->len - base - 4) / desc->elem_size)
 			return -EINVAL;
 	}
 	base += 4;
@@ -1187,8 +1186,8 @@ int
 xdr_encode_array2(struct xdr_buf *buf, unsigned int base,
 		  struct xdr_array2_desc *desc)
 {
-	if ((unsigned long) base + 4 + desc->array_len * desc->elem_size >
-	    buf->head->iov_len + buf->page_len + buf->tail->iov_len)
+	if (buf->head->iov_len + buf->page_len + buf->tail->iov_len -
+	    base < desc->array_len * desc->elem_size + 4)
 		return -EINVAL;
 
 	return xdr_xcode_array2(buf, base, desc, 1);
_