NFS: Use unsigned intermediates for manipulating header lengths (NFSv4 XDR)
authorChuck Lever <chuck.lever@oracle.com>
Fri, 26 Oct 2007 17:32:03 +0000 (13:32 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Wed, 30 Jan 2008 07:05:44 +0000 (02:05 -0500)
Clean up: prevent length underflow and mixed sign comparison when
unmarshalling NFS version 4 getacl, readdir, and readlink replies.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
fs/nfs/nfs4xdr.c

index 51dd380..2e1fe17 100644 (file)
@@ -3476,10 +3476,11 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n
        struct xdr_buf  *rcvbuf = &req->rq_rcv_buf;
        struct page     *page = *rcvbuf->pages;
        struct kvec     *iov = rcvbuf->head;
-       unsigned int    nr, pglen = rcvbuf->page_len;
+       size_t          hdrlen;
+       u32             recvd, pglen = rcvbuf->page_len;
        __be32          *end, *entry, *p, *kaddr;
-       uint32_t        len, attrlen, xlen;
-       int             hdrlen, recvd, status;
+       unsigned int    nr;
+       int             status;
 
        status = decode_op_hdr(xdr, OP_READDIR);
        if (status)
@@ -3503,6 +3504,7 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n
        end = p + ((pglen + readdir->pgbase) >> 2);
        entry = p;
        for (nr = 0; *p++; nr++) {
+               u32 len, attrlen, xlen;
                if (end - p < 3)
                        goto short_pkt;
                dprintk("cookie = %Lu, ", *((unsigned long long *)p));
@@ -3551,7 +3553,8 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req)
 {
        struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
        struct kvec *iov = rcvbuf->head;
-       int hdrlen, len, recvd;
+       size_t hdrlen;
+       u32 len, recvd;
        __be32 *p;
        char *kaddr;
        int status;
@@ -3646,7 +3649,8 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
        if (unlikely(bitmap[0] & (FATTR4_WORD0_ACL - 1U)))
                return -EIO;
        if (likely(bitmap[0] & FATTR4_WORD0_ACL)) {
-               int hdrlen, recvd;
+               size_t hdrlen;
+               u32 recvd;
 
                /* We ignore &savep and don't do consistency checks on
                 * the attr length.  Let userspace figure it out.... */