From: "J. Bruce Fields" <bfields@fieldses.org>
To: Neil Brown <neilb@suse.de>
Cc: linux-nfs@vger.kernel.org
Subject: Re: [PATCH] bug in read_buf
Date: Tue, 20 Apr 2010 12:51:52 -0400 [thread overview]
Message-ID: <20100420165152.GD28826@fieldses.org> (raw)
In-Reply-To: <19405.3732.562014.510508@notabene.brown>
On Tue, Apr 20, 2010 at 12:16:52PM +1000, Neil Brown wrote:
>
> Surely this can never have worked... which implies that the code has
> never been used?
>
> When read_buf is called to move over to the next page in the pagelist
> of an NFSv4 request, it sets argp->end to essentially a random
> number, certainly not an address within the page which argp->p now
> points to. So subsequent calls to READ_BUF will think there is much
> more than a page of spare space (the cast to u32 ensures an unsigned
> comparison) so we can expect to fall off the end of the second
> page.
Yipes, thanks.
> I guess we never ever receive requests with any operation starting
> beyond the first page!
putfh-write-getattr, for example, is common enough. The write decoding
should leave arg->end set correctly. But there are two read_buf()'s in
decode_getattr(), and I can't see why we don't hit this bug on a write
that leaves that final getattr exactly straddling a page boundary.
--b.
> [[
> I found this while looking at why fsstress over NFS over RDMA caused
> a bad memory dereference in READ32, suggesting that 'p' had a bad
> value. However it was ffff8801299188f0, which is not an "I've fallen
> off the end of the page" sort of value. So I think it must be a
> different bug :-( It is as if the page is being unmapped underneath
> us...
> ]]
> NeilBrown
>
>
>
>
> diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
> index e170317..34ccf81 100644
> --- a/fs/nfsd/nfs4xdr.c
> +++ b/fs/nfsd/nfs4xdr.c
> @@ -161,10 +161,10 @@ static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes)
> argp->p = page_address(argp->pagelist[0]);
> argp->pagelist++;
> if (argp->pagelen < PAGE_SIZE) {
> - argp->end = p + (argp->pagelen>>2);
> + argp->end = argp->p + (argp->pagelen>>2);
> argp->pagelen = 0;
> } else {
> - argp->end = p + (PAGE_SIZE>>2);
> + argp->end = argp->p + (PAGE_SIZE>>2);
> argp->pagelen -= PAGE_SIZE;
> }
> memcpy(((char*)p)+avail, argp->p, (nbytes - avail));
> @@ -1426,10 +1426,10 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
> argp->p = page_address(argp->pagelist[0]);
> argp->pagelist++;
> if (argp->pagelen < PAGE_SIZE) {
> - argp->end = p + (argp->pagelen>>2);
> + argp->end = argp->p + (argp->pagelen>>2);
> argp->pagelen = 0;
> } else {
> - argp->end = p + (PAGE_SIZE>>2);
> + argp->end = argp->p + (PAGE_SIZE>>2);
> argp->pagelen -= PAGE_SIZE;
> }
> }
>
>
next prev parent reply other threads:[~2010-04-20 16:51 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-04-20 2:16 [PATCH] bug in read_buf Neil Brown
2010-04-20 16:51 ` J. Bruce Fields [this message]
2010-04-20 19:24 ` William A. (Andy) Adamson
[not found] ` <g2k89c397151004201224wb35ae389g961523bbef23f452-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2010-04-20 19:39 ` J. Bruce Fields
2010-04-21 22:35 ` J. Bruce Fields
2010-04-21 22:36 ` J. Bruce Fields
2010-04-21 23:08 ` Neil Brown
2010-04-22 15:41 ` William A. (Andy) Adamson
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=20100420165152.GD28826@fieldses.org \
--to=bfields@fieldses.org \
--cc=linux-nfs@vger.kernel.org \
--cc=neilb@suse.de \
/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.