All of lore.kernel.org
 help / color / mirror / Atom feed
From: NeilBrown <neilb@suse.com>
To: "J. Bruce Fields" <bfields@fieldses.org>
Cc: linux-nfs@vger.kernel.org
Subject: Re: [PATCH] nfsd: check for oversized NFSv2/v3 arguments
Date: Wed, 26 Apr 2017 16:31:59 +1000	[thread overview]
Message-ID: <87inlrptls.fsf@notabene.neil.brown.name> (raw)
In-Reply-To: <20170425204016.GA15279@fieldses.org>

[-- Attachment #1: Type: text/plain, Size: 5935 bytes --]

On Tue, Apr 25 2017, J. Bruce Fields wrote:

>> > +	if (!*(rqstp->rq_next_page))
>> > +		return 0;
>> 
>> Why the extra parentheses?  "->" is at the highest precedence level for C.
>
> I've been doing this stuff enough years, you'd think I'd have bothered
> to memorize the C operator precedence table by now.
>
> Anyway, this change is actually unrelated and not entirely necessary;
> dropped.
>
>> i.e. either keep it simple (like the v2 code) or make it tidy (with head
>> and tail), but not half-and-half??
>
> What the heck, let's go all out.

Looks good, thanks.


>
> You only live once!

:-)

NeilBrown


>
> --b.
>
> commit db44bac41bbf
> Author: J. Bruce Fields <bfields@redhat.com>
> Date:   Tue Apr 25 16:21:34 2017 -0400
>
>     nfsd4: minor NFSv2/v3 write decoding cleanup
>     
>     Use a couple shortcuts that will simplify a following bugfix.
>     
>     Cc: stable@vger.kernel.org
>     Signed-off-by: J. Bruce Fields <bfields@redhat.com>
>
> diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
> index dba2ff8eaa68..d18cfddbe115 100644
> --- a/fs/nfsd/nfs3xdr.c
> +++ b/fs/nfsd/nfs3xdr.c
> @@ -358,6 +358,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
>  {
>  	unsigned int len, v, hdr, dlen;
>  	u32 max_blocksize = svc_max_payload(rqstp);
> +	struct kvec *head = rqstp->rq_arg.head;
> +	struct kvec *tail = rqstp->rq_arg.tail;
>  
>  	p = decode_fh(p, &args->fh);
>  	if (!p)
> @@ -377,9 +379,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
>  	 * Check to make sure that we got the right number of
>  	 * bytes.
>  	 */
> -	hdr = (void*)p - rqstp->rq_arg.head[0].iov_base;
> -	dlen = rqstp->rq_arg.head[0].iov_len + rqstp->rq_arg.page_len
> -		+ rqstp->rq_arg.tail[0].iov_len - hdr;
> +	hdr = (void*)p - head->iov_base;
> +	dlen = head->iov_len + rqstp->rq_arg.page_len + tail->iov_len - hdr;
>  	/*
>  	 * Round the length of the data which was specified up to
>  	 * the next multiple of XDR units and then compare that
> @@ -396,7 +397,7 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
>  		len = args->len = max_blocksize;
>  	}
>  	rqstp->rq_vec[0].iov_base = (void*)p;
> -	rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr;
> +	rqstp->rq_vec[0].iov_len = head->iov_len - hdr;
>  	v = 0;
>  	while (len > rqstp->rq_vec[v].iov_len) {
>  		len -= rqstp->rq_vec[v].iov_len;
> diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
> index 41b468a6a90f..59bd88a23a3d 100644
> --- a/fs/nfsd/nfsxdr.c
> +++ b/fs/nfsd/nfsxdr.c
> @@ -280,6 +280,7 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
>  					struct nfsd_writeargs *args)
>  {
>  	unsigned int len, hdr, dlen;
> +	struct kvec *head = rqstp->rq_arg.head;
>  	int v;
>  
>  	p = decode_fh(p, &args->fh);
> @@ -300,9 +301,8 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
>  	 * Check to make sure that we got the right number of
>  	 * bytes.
>  	 */
> -	hdr = (void*)p - rqstp->rq_arg.head[0].iov_base;
> -	dlen = rqstp->rq_arg.head[0].iov_len + rqstp->rq_arg.page_len
> -		- hdr;
> +	hdr = (void*)p - head->iov_base;
> +	dlen = head->iov_len + rqstp->rq_arg.page_len - hdr;
>  
>  	/*
>  	 * Round the length of the data which was specified up to
> @@ -316,7 +316,7 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
>  		return 0;
>  
>  	rqstp->rq_vec[0].iov_base = (void*)p;
> -	rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr;
> +	rqstp->rq_vec[0].iov_len = head->iov_len - hdr;
>  	v = 0;
>  	while (len > rqstp->rq_vec[v].iov_len) {
>  		len -= rqstp->rq_vec[v].iov_len;
> commit 13bf9fbff0e5
> Author: J. Bruce Fields <bfields@redhat.com>
> Date:   Fri Apr 21 15:26:30 2017 -0400
>
>     nfsd: stricter decoding of write-like NFSv2/v3 ops
>     
>     The NFSv2/v3 code does not systematically check whether we decode past
>     the end of the buffer.  This generally appears to be harmless, but there
>     are a few places where we do arithmetic on the pointers involved and
>     don't account for the possibility that a length could be negative.  Add
>     checks to catch these.
>     
>     Reported-by: Tuomas Haanpää <thaan@synopsys.com>
>     Reported-by: Ari Kauppi <ari@synopsys.com>
>     Reviewed-by: NeilBrown <neilb@suse.com>
>     Cc: stable@vger.kernel.org
>     Signed-off-by: J. Bruce Fields <bfields@redhat.com>
>
> diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
> index d18cfddbe115..452334694a5d 100644
> --- a/fs/nfsd/nfs3xdr.c
> +++ b/fs/nfsd/nfs3xdr.c
> @@ -369,6 +369,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
>  	args->count = ntohl(*p++);
>  	args->stable = ntohl(*p++);
>  	len = args->len = ntohl(*p++);
> +	if ((void *)p > head->iov_base + head->iov_len)
> +		return 0;
>  	/*
>  	 * The count must equal the amount of data passed.
>  	 */
> @@ -472,6 +474,8 @@ nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p,
>  	/* first copy and check from the first page */
>  	old = (char*)p;
>  	vec = &rqstp->rq_arg.head[0];
> +	if ((void *)old > vec->iov_base + vec->iov_len)
> +		return 0;
>  	avail = vec->iov_len - (old - (char*)vec->iov_base);
>  	while (len && avail && *old) {
>  		*new++ = *old++;
> diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
> index 59bd88a23a3d..de07ff625777 100644
> --- a/fs/nfsd/nfsxdr.c
> +++ b/fs/nfsd/nfsxdr.c
> @@ -302,6 +302,8 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
>  	 * bytes.
>  	 */
>  	hdr = (void*)p - head->iov_base;
> +	if (hdr > head->iov_len)
> +		return 0;
>  	dlen = head->iov_len + rqstp->rq_arg.page_len - hdr;
>  
>  	/*
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

  reply	other threads:[~2017-04-26  6:32 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-14 15:04 [PATCH] nfsd: check for oversized NFSv2/v3 arguments J. Bruce Fields
2017-04-14 15:09 ` J. Bruce Fields
2017-04-18  0:25   ` NeilBrown
2017-04-18 17:13     ` J. Bruce Fields
2017-04-19  0:17       ` NeilBrown
2017-04-19  0:44         ` J. Bruce Fields
2017-04-20  0:57           ` NeilBrown
2017-04-20 15:16             ` J. Bruce Fields
2017-04-20 16:19       ` J. Bruce Fields
2017-04-20 21:30         ` J. Bruce Fields
2017-04-20 22:11           ` NeilBrown
2017-04-20 22:19             ` J. Bruce Fields
2017-04-21 21:12         ` J. Bruce Fields
2017-04-23 22:21           ` NeilBrown
2017-04-24 14:06             ` J. Bruce Fields
2017-04-24 21:19               ` J. Bruce Fields
2017-04-24 21:20                 ` J. Bruce Fields
2017-04-25  3:15                   ` NeilBrown
2017-04-25 20:40                     ` J. Bruce Fields
2017-04-26  6:31                       ` NeilBrown [this message]
2017-04-25  3:00                 ` NeilBrown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87inlrptls.fsf@notabene.neil.brown.name \
    --to=neilb@suse.com \
    --cc=bfields@fieldses.org \
    --cc=linux-nfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.