aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2008-01-11 17:06:52 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-01-13 12:57:57 -0500
commitba67a39efde8312e386c6f603054f8945433d91f (patch)
treea804a00351abf9f81f26f679f0cbaaedba2eb188
parent84427eaef1fb91704c7112bdb598c810003b99f3 (diff)
knfsd: Allow NFSv2/3 WRITE calls to succeed when krb5i etc is used.
When RPCSEC/GSS and krb5i is used, requests are padded, typically to a multiple of 8 bytes. This can make the request look slightly longer than it really is. As of f34b95689d2ce001c "The NFSv2/NFSv3 server does not handle zero length WRITE request correctly", the xdr decode routines for NFSv2 and NFSv3 reject requests that aren't the right length, so krb5i (for example) WRITE requests can get lost. This patch relaxes the appropriate test and enhances the related comment. Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Cc: Peter Staubach <staubach@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/nfsd/nfs3xdr.c5
-rw-r--r--fs/nfsd/nfsxdr.c5
2 files changed, 8 insertions, 2 deletions
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 2d116d2298f8..f917fd25858a 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -388,8 +388,11 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
388 * Round the length of the data which was specified up to 388 * Round the length of the data which was specified up to
389 * the next multiple of XDR units and then compare that 389 * the next multiple of XDR units and then compare that
390 * against the length which was actually received. 390 * against the length which was actually received.
391 * Note that when RPCSEC/GSS (for example) is used, the
392 * data buffer can be padded so dlen might be larger
393 * than required. It must never be smaller.
391 */ 394 */
392 if (dlen != XDR_QUADLEN(len)*4) 395 if (dlen < XDR_QUADLEN(len)*4)
393 return 0; 396 return 0;
394 397
395 if (args->count > max_blocksize) { 398 if (args->count > max_blocksize) {
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 986f9b32083c..b86e3658a0af 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -313,8 +313,11 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
313 * Round the length of the data which was specified up to 313 * Round the length of the data which was specified up to
314 * the next multiple of XDR units and then compare that 314 * the next multiple of XDR units and then compare that
315 * against the length which was actually received. 315 * against the length which was actually received.
316 * Note that when RPCSEC/GSS (for example) is used, the
317 * data buffer can be padded so dlen might be larger
318 * than required. It must never be smaller.
316 */ 319 */
317 if (dlen != XDR_QUADLEN(len)*4) 320 if (dlen < XDR_QUADLEN(len)*4)
318 return 0; 321 return 0;
319 322
320 rqstp->rq_vec[0].iov_base = (void*)p; 323 rqstp->rq_vec[0].iov_base = (void*)p;