diff options
author | NeilBrown <neilb@suse.de> | 2008-01-11 17:06:52 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-01-13 12:57:57 -0500 |
commit | ba67a39efde8312e386c6f603054f8945433d91f (patch) | |
tree | a804a00351abf9f81f26f679f0cbaaedba2eb188 /fs/nfsd | |
parent | 84427eaef1fb91704c7112bdb598c810003b99f3 (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>
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/nfs3xdr.c | 5 | ||||
-rw-r--r-- | fs/nfsd/nfsxdr.c | 5 |
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; |