All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] bug in read_buf
@ 2010-04-20  2:16 Neil Brown
  2010-04-20 16:51 ` J. Bruce Fields
  0 siblings, 1 reply; 8+ messages in thread
From: Neil Brown @ 2010-04-20  2:16 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: linux-nfs


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.

I guess we never ever receive requests with any operation starting
beyond the first page!

[[
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;
 			}
 		}



^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2010-04-22 15:41 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-04-20  2:16 [PATCH] bug in read_buf Neil Brown
2010-04-20 16:51 ` J. Bruce Fields
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

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.