]> pilppa.com Git - linux-2.6-omap-h63xx.git/commitdiff
[PATCH] knfsd: Fix some minor sign problems in nfsd/xdr
authorNeilBrown <neilb@cse.unsw.edu.au>
Mon, 7 Nov 2005 09:00:26 +0000 (01:00 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Mon, 7 Nov 2005 15:53:48 +0000 (07:53 -0800)
There are a couple of tests which could possibly be confused by extremely
large numbers appearing in 'xdr' packets.  I think the closest to an exploit
you could get would be writing random data from a free page into a file - i.e.
 leak data out of kernel space.

I'm fairly sure they cannot be used for remote compromise.

Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
fs/nfsd/nfs3xdr.c
include/linux/nfsd/xdr3.h
include/linux/sunrpc/svc.h

index e0e134d6baba0013af5918f0dd0a4f9c3405b246..9147b8524d05262bd9f28b77c0e7636854367f09 100644 (file)
@@ -366,7 +366,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
        len = args->len = ntohl(*p++);
 
        hdr = (void*)p - rqstp->rq_arg.head[0].iov_base;
-       if (rqstp->rq_arg.len < len + hdr)
+       if (rqstp->rq_arg.len < hdr ||
+           rqstp->rq_arg.len - hdr < len)
                return 0;
 
        args->vec[0].iov_base = (void*)p;
index 21e18ce7ca63bc047b9a31be8da1700621326c15..3c2a71b43bacc38a33ad9b8ab3efa4aaf61d8190 100644 (file)
@@ -42,7 +42,7 @@ struct nfsd3_writeargs {
        __u64                   offset;
        __u32                   count;
        int                     stable;
-       int                     len;
+       __u32                   len;
        struct kvec             vec[RPCSVC_MAXPAGES];
        int                     vlen;
 };
index 5af8800e0ce328a05aa7cbaeaa0b604ba28b00ab..e4086ec8b952a3a87b5f16bd654df3c70a05066a 100644 (file)
@@ -171,7 +171,8 @@ xdr_argsize_check(struct svc_rqst *rqstp, u32 *p)
 {
        char *cp = (char *)p;
        struct kvec *vec = &rqstp->rq_arg.head[0];
-       return cp - (char*)vec->iov_base <= vec->iov_len;
+       return cp >= (char*)vec->iov_base
+               && cp <= (char*)vec->iov_base + vec->iov_len;
 }
 
 static inline int