diff options
author | NeilBrown <neilb@cse.unsw.edu.au> | 2005-11-07 01:00:26 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-07 07:53:48 -0800 |
commit | 0ba7536d5d47e4ecf2259a80b207158dc4e711eb (patch) | |
tree | 0e8528e65f25b9992cfad43e74018a0986f46c38 | |
parent | 70c3b76c28b012452d63bb27f6d0517afb05d86f (diff) |
[PATCH] knfsd: Fix some minor sign problems in nfsd/xdr
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>
-rw-r--r-- | fs/nfsd/nfs3xdr.c | 3 | ||||
-rw-r--r-- | include/linux/nfsd/xdr3.h | 2 | ||||
-rw-r--r-- | include/linux/sunrpc/svc.h | 3 |
3 files changed, 5 insertions, 3 deletions
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index e0e134d6bab..9147b8524d0 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c @@ -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; diff --git a/include/linux/nfsd/xdr3.h b/include/linux/nfsd/xdr3.h index 21e18ce7ca6..3c2a71b43ba 100644 --- a/include/linux/nfsd/xdr3.h +++ b/include/linux/nfsd/xdr3.h @@ -42,7 +42,7 @@ struct nfsd3_writeargs { __u64 offset; __u32 count; int stable; - int len; + __u32 len; struct kvec vec[RPCSVC_MAXPAGES]; int vlen; }; diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 5af8800e0ce..e4086ec8b95 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -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 |