* [PATCH 000 of 14] knfsd: Introduction
@ 2006-06-27 7:19 NeilBrown
2006-06-27 7:19 ` [PATCH 001 of 14] knfsd: Improve the test for cross-device-rename in nfsd NeilBrown
` (13 more replies)
0 siblings, 14 replies; 15+ messages in thread
From: NeilBrown @ 2006-06-27 7:19 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs, linux-kernel
Following are 14 assorted patches for nfsd.
Patches are against 2.6.17-mm2 and are suitable for inclusion in 2.6.18.
Primarily minor bug fixes.
Last three patches are initial support for RPC privacy (i.e. decrypt
the RPC request and encrypt the reply). This code is sub-optimal in
several ways (memcopys ...) which will probably get tidied up once we
determine the best way to do so.
Thanks,
NeilBrown
[PATCH 001 of 14] knfsd: Improve the test for cross-device-rename in nfsd
[PATCH 002 of 14] knfsd: Fixing missing 'expkey' support for fsid type 3
[PATCH 003 of 14] knfsd: Remove noise about filehandle being uptodate.
[PATCH 004 of 14] knfsd: Ignore ref_fh when crossing a mountpoint.
[PATCH 005 of 14] knfsd: nfsd4: fix open_confirm locking
[PATCH 006 of 14] knfsd: nfsd: call nfsd_setuser() on fh_compose(), fix nfsd4 permissions problem
[PATCH 007 of 14] knfsd: nfsd4: remove superfluous grace period checks
[PATCH 008 of 14] knfsd: nfsd: fix misplaced fh_unlock() in nfsd_link()
[PATCH 009 of 14] knfsd: svcrpc: gss: simplify rsc_parse()
[PATCH 010 of 14] knfsd: nfsd4: fix some open argument tests
[PATCH 011 of 14] knfsd: nfsd4: fix open flag passing
[PATCH 012 of 14] knfsd: svcrpc: Simplify nfsd rpcsec_gss integrity code
[PATCH 013 of 14] knfsd: nfsd: mark rqstp to prevent use of sendfile in privacy case
[PATCH 014 of 14] knfsd: svcrpc: gss: server-side implementation of rpcsec_gss privacy.
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 001 of 14] knfsd: Improve the test for cross-device-rename in nfsd
2006-06-27 7:19 [PATCH 000 of 14] knfsd: Introduction NeilBrown
@ 2006-06-27 7:19 ` NeilBrown
2006-06-27 7:19 ` [PATCH 002 of 14] knfsd: Fixing missing 'expkey' support for fsid type 3 NeilBrown
` (12 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: NeilBrown @ 2006-06-27 7:19 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs, linux-kernel, Al Viro
Just testing the i_sb isn't really enough, at least
the vfsmnt must be the same. Thanks Al.
Cc: Al Viro <viro@ftp.linux.org.uk>
### Diffstat output
./fs/nfsd/vfs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff .prev/fs/nfsd/vfs.c ./fs/nfsd/vfs.c
--- .prev/fs/nfsd/vfs.c 2006-06-27 12:15:18.000000000 +1000
+++ ./fs/nfsd/vfs.c 2006-06-27 12:15:21.000000000 +1000
@@ -1556,7 +1556,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru
tdir = tdentry->d_inode;
err = (rqstp->rq_vers == 2) ? nfserr_acces : nfserr_xdev;
- if (fdir->i_sb != tdir->i_sb)
+ if (ffhp->fh_export != tfhp->fh_export)
goto out;
err = nfserr_perm;
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 002 of 14] knfsd: Fixing missing 'expkey' support for fsid type 3
2006-06-27 7:19 [PATCH 000 of 14] knfsd: Introduction NeilBrown
2006-06-27 7:19 ` [PATCH 001 of 14] knfsd: Improve the test for cross-device-rename in nfsd NeilBrown
@ 2006-06-27 7:19 ` NeilBrown
2006-06-27 7:19 ` [PATCH 003 of 14] knfsd: Remove noise about filehandle being uptodate NeilBrown
` (11 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: NeilBrown @ 2006-06-27 7:19 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs, linux-kernel, Frank Filz
From: Frank Filz <ffilzlnx@us.ibm.com>
Type '3' is used for the fsid in filehandles when the device number
of the device holding the filesystem has more than 8 bits in either
major or minor.
Unfortunately expkey_parse doesn't recognise type 3. Fix this.
(Slighty modified from Frank's original)
Signed-Off-By: Frank Filz <ffilzlnx@us.ibm.com>
Signed-off-by: Neil Brown <neilb@suse.de>
### Diffstat output
./fs/nfsd/export.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff .prev/fs/nfsd/export.c ./fs/nfsd/export.c
--- .prev/fs/nfsd/export.c 2006-06-27 12:15:18.000000000 +1000
+++ ./fs/nfsd/export.c 2006-06-27 12:15:55.000000000 +1000
@@ -126,7 +126,7 @@ static int expkey_parse(struct cache_det
if (*ep)
goto out;
dprintk("found fsidtype %d\n", fsidtype);
- if (fsidtype > 2)
+ if (key_len(fsidtype)==0) /* invalid type */
goto out;
if ((len=qword_get(&mesg, buf, PAGE_SIZE)) <= 0)
goto out;
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 003 of 14] knfsd: Remove noise about filehandle being uptodate.
2006-06-27 7:19 [PATCH 000 of 14] knfsd: Introduction NeilBrown
2006-06-27 7:19 ` [PATCH 001 of 14] knfsd: Improve the test for cross-device-rename in nfsd NeilBrown
2006-06-27 7:19 ` [PATCH 002 of 14] knfsd: Fixing missing 'expkey' support for fsid type 3 NeilBrown
@ 2006-06-27 7:19 ` NeilBrown
2006-06-27 7:19 ` [PATCH 004 of 14] knfsd: Ignore ref_fh when crossing a mountpoint NeilBrown
` (10 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: NeilBrown @ 2006-06-27 7:19 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs, linux-kernel
There is a perfectly valid situation where fh_update gets called on an
already uptodate filehandle - in nfsd_create_v3 where a
CREATE_UNCHECKED finds an existing file and wants to just set the
size.
We could possible optimise out the call in that case, but the only
harm involved is that fh_update prints a warning, so it is easier to
remove the warning.
Signed-off-by: Neil Brown <neilb@suse.de>
### Diffstat output
./fs/nfsd/nfsfh.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff .prev/fs/nfsd/nfsfh.c ./fs/nfsd/nfsfh.c
--- .prev/fs/nfsd/nfsfh.c 2006-06-27 12:15:18.000000000 +1000
+++ ./fs/nfsd/nfsfh.c 2006-06-27 12:16:05.000000000 +1000
@@ -461,7 +461,7 @@ fh_update(struct svc_fh *fhp)
} else {
int size;
if (fhp->fh_handle.fh_fileid_type != 0)
- goto out_uptodate;
+ goto out;
datap = fhp->fh_handle.fh_auth+
fhp->fh_handle.fh_size/4 -1;
size = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4;
@@ -481,10 +481,6 @@ out_negative:
printk(KERN_ERR "fh_update: %s/%s still negative!\n",
dentry->d_parent->d_name.name, dentry->d_name.name);
goto out;
-out_uptodate:
- printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n",
- dentry->d_parent->d_name.name, dentry->d_name.name);
- goto out;
}
/*
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 004 of 14] knfsd: Ignore ref_fh when crossing a mountpoint.
2006-06-27 7:19 [PATCH 000 of 14] knfsd: Introduction NeilBrown
` (2 preceding siblings ...)
2006-06-27 7:19 ` [PATCH 003 of 14] knfsd: Remove noise about filehandle being uptodate NeilBrown
@ 2006-06-27 7:19 ` NeilBrown
2006-06-27 7:20 ` [PATCH 005 of 14] knfsd: nfsd4: fix open_confirm locking NeilBrown
` (9 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: NeilBrown @ 2006-06-27 7:19 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs, linux-kernel
nfsd tries to return to a client the same sort of filehandle as was
used by the client. This removes some filehandle aliasing issues and
means that a server upgrade followed by a downgrade will not confused
clients not restarted during that time.
However when crossing a mountpoint, the filehandle used for one
filesystem doesn't provide any useful information on what sort of
filehandle should be used on the other, and can provide misleading
information. So if the reference filehandle is on a different
filesystem to the one being generated, ignore it.
Signed-off-by: Neil Brown <neilb@suse.de>
### Diffstat output
./fs/nfsd/nfsfh.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff .prev/fs/nfsd/nfsfh.c ./fs/nfsd/nfsfh.c
--- .prev/fs/nfsd/nfsfh.c 2006-06-27 12:16:05.000000000 +1000
+++ ./fs/nfsd/nfsfh.c 2006-06-27 12:16:27.000000000 +1000
@@ -312,8 +312,8 @@ int
fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, struct svc_fh *ref_fh)
{
/* ref_fh is a reference file handle.
- * if it is non-null, then we should compose a filehandle which is
- * of the same version, where possible.
+ * if it is non-null and for the same filesystem, then we should compose
+ * a filehandle which is of the same version, where possible.
* Currently, that means that if ref_fh->fh_handle.fh_version == 0xca
* Then create a 32byte filehandle using nfs_fhbase_old
*
@@ -332,7 +332,7 @@ fh_compose(struct svc_fh *fhp, struct sv
parent->d_name.name, dentry->d_name.name,
(inode ? inode->i_ino : 0));
- if (ref_fh) {
+ if (ref_fh && ref_fh->fh_export == exp) {
ref_fh_version = ref_fh->fh_handle.fh_version;
if (ref_fh_version == 0xca)
ref_fh_fsid_type = 0;
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 005 of 14] knfsd: nfsd4: fix open_confirm locking
2006-06-27 7:19 [PATCH 000 of 14] knfsd: Introduction NeilBrown
` (3 preceding siblings ...)
2006-06-27 7:19 ` [PATCH 004 of 14] knfsd: Ignore ref_fh when crossing a mountpoint NeilBrown
@ 2006-06-27 7:20 ` NeilBrown
2006-06-27 7:20 ` [PATCH 006 of 14] knfsd: nfsd: call nfsd_setuser() on fh_compose(), fix nfsd4 permissions problem NeilBrown
` (8 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: NeilBrown @ 2006-06-27 7:20 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs, linux-kernel
From: J. Bruce Fields <bfields@citi.umich.edu>
Fix an improper unlock in an error path.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
### Diffstat output
./fs/nfsd/nfs4state.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff .prev/fs/nfsd/nfs4state.c ./fs/nfsd/nfs4state.c
--- .prev/fs/nfsd/nfs4state.c 2006-06-27 14:36:03.000000000 +1000
+++ ./fs/nfsd/nfs4state.c 2006-06-27 14:36:03.000000000 +1000
@@ -2252,8 +2252,9 @@ nfsd4_open_confirm(struct svc_rqst *rqst
(int)current_fh->fh_dentry->d_name.len,
current_fh->fh_dentry->d_name.name);
- if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0)))
- goto out;
+ status = fh_verify(rqstp, current_fh, S_IFREG, 0);
+ if (status)
+ return status;
nfs4_lock_state();
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 006 of 14] knfsd: nfsd: call nfsd_setuser() on fh_compose(), fix nfsd4 permissions problem
2006-06-27 7:19 [PATCH 000 of 14] knfsd: Introduction NeilBrown
` (4 preceding siblings ...)
2006-06-27 7:20 ` [PATCH 005 of 14] knfsd: nfsd4: fix open_confirm locking NeilBrown
@ 2006-06-27 7:20 ` NeilBrown
2006-06-27 7:20 ` [PATCH 007 of 14] knfsd: nfsd4: remove superfluous grace period checks NeilBrown
` (7 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: NeilBrown @ 2006-06-27 7:20 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs, linux-kernel
From: J. Bruce Fields <bfields@citi.umich.edu>
In the typical v2/v3 case the only new filehandles used as arguments to
operations are filehandles taken directly off the wire, which don't get
dentries until fh_verify() is called.
But in v4 the filehandles that are arguments to operations were often
created by previous operations (putrootfh, lookup, etc.) using
fh_compose, which sets the dentry in the filehandle without calling
nfsd_setuser().
This also means that, for example, if filesystem B is mounted on filesystem
A, and filesystem A is exported without root-squashing, then a client can
bypass the rootsquashing on B using a compound that starts at a filehandle
in A, crosses into B using lookups, and then does stuff in B.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
### Diffstat output
./fs/nfsd/nfsfh.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff .prev/fs/nfsd/nfsfh.c ./fs/nfsd/nfsfh.c
--- .prev/fs/nfsd/nfsfh.c 2006-06-27 12:16:27.000000000 +1000
+++ ./fs/nfsd/nfsfh.c 2006-06-27 14:41:52.000000000 +1000
@@ -187,13 +187,6 @@ fh_verify(struct svc_rqst *rqstp, struct
goto out;
}
- /* Set user creds for this exportpoint */
- error = nfsd_setuser(rqstp, exp);
- if (error) {
- error = nfserrno(error);
- goto out;
- }
-
/*
* Look up the dentry using the NFS file handle.
*/
@@ -251,6 +244,14 @@ fh_verify(struct svc_rqst *rqstp, struct
}
cache_get(&exp->h);
+ /* Set user creds for this exportpoint; necessary even in the "just
+ * checking" case because this may be a filehandle that was created by
+ * fh_compose, and that is about to be used in another nfsv4 compound
+ * operation */
+ error = nfserrno(nfsd_setuser(rqstp, exp));
+ if (error)
+ goto out;
+
error = nfsd_mode_check(rqstp, dentry->d_inode->i_mode, type);
if (error)
goto out;
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 007 of 14] knfsd: nfsd4: remove superfluous grace period checks
2006-06-27 7:19 [PATCH 000 of 14] knfsd: Introduction NeilBrown
` (5 preceding siblings ...)
2006-06-27 7:20 ` [PATCH 006 of 14] knfsd: nfsd: call nfsd_setuser() on fh_compose(), fix nfsd4 permissions problem NeilBrown
@ 2006-06-27 7:20 ` NeilBrown
2006-06-27 7:20 ` [PATCH 008 of 14] knfsd: nfsd: fix misplaced fh_unlock() in nfsd_link() NeilBrown
` (6 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: NeilBrown @ 2006-06-27 7:20 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs, linux-kernel
From: J. Bruce Fields <bfields@citi.umich.edu>
We're checking nfs_in_grace here a few times when there isn't really any
reason to--bad_stateid is probably the more sensible return value anyway.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
### Diffstat output
./fs/nfsd/nfs4state.c | 4 ----
1 file changed, 4 deletions(-)
diff .prev/fs/nfsd/nfs4state.c ./fs/nfsd/nfs4state.c
--- .prev/fs/nfsd/nfs4state.c 2006-06-27 14:36:03.000000000 +1000
+++ ./fs/nfsd/nfs4state.c 2006-06-27 14:44:03.000000000 +1000
@@ -2070,16 +2070,12 @@ nfs4_preprocess_stateid_op(struct svc_fh
if (!stateid->si_fileid) { /* delegation stateid */
if(!(dp = find_delegation_stateid(ino, stateid))) {
dprintk("NFSD: delegation stateid not found\n");
- if (nfs4_in_grace())
- status = nfserr_grace;
goto out;
}
stidp = &dp->dl_stateid;
} else { /* open or lock stateid */
if (!(stp = find_stateid(stateid, flags))) {
dprintk("NFSD: open or lock stateid not found\n");
- if (nfs4_in_grace())
- status = nfserr_grace;
goto out;
}
if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp))
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 008 of 14] knfsd: nfsd: fix misplaced fh_unlock() in nfsd_link()
2006-06-27 7:19 [PATCH 000 of 14] knfsd: Introduction NeilBrown
` (6 preceding siblings ...)
2006-06-27 7:20 ` [PATCH 007 of 14] knfsd: nfsd4: remove superfluous grace period checks NeilBrown
@ 2006-06-27 7:20 ` NeilBrown
2006-06-27 7:20 ` [PATCH 009 of 14] knfsd: svcrpc: gss: simplify rsc_parse() NeilBrown
` (5 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: NeilBrown @ 2006-06-27 7:20 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs, linux-kernel
From: David M. Richter <richterd@citi.umich.edu>
In the event that lookup_one_len() fails in nfsd_link(), fh_unlock() is
skipped and locks are held overlong.
Patch was tested on 2.6.17-rc2 by causing lookup_one_len() to fail and
verifying that fh_unlock() gets called appropriately.
Signed-off-by: David M. Richter <richterd@citi.umich.edu>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
### Diffstat output
./fs/nfsd/vfs.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff .prev/fs/nfsd/vfs.c ./fs/nfsd/vfs.c
--- .prev/fs/nfsd/vfs.c 2006-06-27 12:15:21.000000000 +1000
+++ ./fs/nfsd/vfs.c 2006-06-27 14:44:27.000000000 +1000
@@ -1520,14 +1520,15 @@ nfsd_link(struct svc_rqst *rqstp, struct
err = nfserrno(err);
}
- fh_unlock(ffhp);
dput(dnew);
+out_unlock:
+ fh_unlock(ffhp);
out:
return err;
out_nfserr:
err = nfserrno(err);
- goto out;
+ goto out_unlock;
}
/*
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 009 of 14] knfsd: svcrpc: gss: simplify rsc_parse()
2006-06-27 7:19 [PATCH 000 of 14] knfsd: Introduction NeilBrown
` (7 preceding siblings ...)
2006-06-27 7:20 ` [PATCH 008 of 14] knfsd: nfsd: fix misplaced fh_unlock() in nfsd_link() NeilBrown
@ 2006-06-27 7:20 ` NeilBrown
2006-06-27 7:20 ` [PATCH 010 of 14] knfsd: nfsd4: fix some open argument tests NeilBrown
` (4 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: NeilBrown @ 2006-06-27 7:20 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs, linux-kernel
From: J. Bruce Fields <bfields@citi.umich.edu>
Adopt a simpler convention for gss_mech_put(), to simplify rsc_parse().
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
### Diffstat output
./net/sunrpc/auth_gss/gss_mech_switch.c | 6 +++---
./net/sunrpc/auth_gss/svcauth_gss.c | 12 ++++--------
2 files changed, 7 insertions(+), 11 deletions(-)
diff .prev/net/sunrpc/auth_gss/gss_mech_switch.c ./net/sunrpc/auth_gss/gss_mech_switch.c
--- .prev/net/sunrpc/auth_gss/gss_mech_switch.c 2006-06-27 14:59:44.000000000 +1000
+++ ./net/sunrpc/auth_gss/gss_mech_switch.c 2006-06-27 14:59:44.000000000 +1000
@@ -224,7 +224,8 @@ EXPORT_SYMBOL(gss_service_to_auth_domain
void
gss_mech_put(struct gss_api_mech * gm)
{
- module_put(gm->gm_owner);
+ if (gm)
+ module_put(gm->gm_owner);
}
EXPORT_SYMBOL(gss_mech_put);
@@ -307,8 +308,7 @@ gss_delete_sec_context(struct gss_ctx **
(*context_handle)->mech_type->gm_ops
->gss_delete_sec_context((*context_handle)
->internal_ctx_id);
- if ((*context_handle)->mech_type)
- gss_mech_put((*context_handle)->mech_type);
+ gss_mech_put((*context_handle)->mech_type);
kfree(*context_handle);
*context_handle=NULL;
return GSS_S_COMPLETE;
diff .prev/net/sunrpc/auth_gss/svcauth_gss.c ./net/sunrpc/auth_gss/svcauth_gss.c
--- .prev/net/sunrpc/auth_gss/svcauth_gss.c 2006-06-27 14:59:44.000000000 +1000
+++ ./net/sunrpc/auth_gss/svcauth_gss.c 2006-06-27 14:59:44.000000000 +1000
@@ -425,6 +425,7 @@ static int rsc_parse(struct cache_detail
struct rsc rsci, *rscp = NULL;
time_t expiry;
int status = -EINVAL;
+ struct gss_api_mech *gm = NULL;
memset(&rsci, 0, sizeof(rsci));
/* context handle */
@@ -453,7 +454,6 @@ static int rsc_parse(struct cache_detail
set_bit(CACHE_NEGATIVE, &rsci.h.flags);
else {
int N, i;
- struct gss_api_mech *gm;
/* gid */
if (get_int(&mesg, &rsci.cred.cr_gid))
@@ -488,21 +488,17 @@ static int rsc_parse(struct cache_detail
status = -EINVAL;
/* mech-specific data: */
len = qword_get(&mesg, buf, mlen);
- if (len < 0) {
- gss_mech_put(gm);
+ if (len < 0)
goto out;
- }
status = gss_import_sec_context(buf, len, gm, &rsci.mechctx);
- if (status) {
- gss_mech_put(gm);
+ if (status)
goto out;
- }
- gss_mech_put(gm);
}
rsci.h.expiry_time = expiry;
rscp = rsc_update(&rsci, rscp);
status = 0;
out:
+ gss_mech_put(gm);
rsc_free(&rsci);
if (rscp)
cache_put(&rscp->h, &rsc_cache);
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 010 of 14] knfsd: nfsd4: fix some open argument tests
2006-06-27 7:19 [PATCH 000 of 14] knfsd: Introduction NeilBrown
` (8 preceding siblings ...)
2006-06-27 7:20 ` [PATCH 009 of 14] knfsd: svcrpc: gss: simplify rsc_parse() NeilBrown
@ 2006-06-27 7:20 ` NeilBrown
2006-06-27 7:20 ` [PATCH 011 of 14] knfsd: nfsd4: fix open flag passing NeilBrown
` (3 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: NeilBrown @ 2006-06-27 7:20 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs, linux-kernel
From: J. Bruce Fields <bfields@citi.umich.edu>
These tests always returned true; clearly that wasn't what was intended.
In keeping with kernel style, make them functions instead of macros while
we're at it.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
### Diffstat output
./fs/nfsd/nfs4state.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff .prev/fs/nfsd/nfs4state.c ./fs/nfsd/nfs4state.c
--- .prev/fs/nfsd/nfs4state.c 2006-06-27 14:44:03.000000000 +1000
+++ ./fs/nfsd/nfs4state.c 2006-06-27 15:00:26.000000000 +1000
@@ -1237,8 +1237,15 @@ find_file(struct inode *ino)
return NULL;
}
-#define TEST_ACCESS(x) ((x > 0 || x < 4)?1:0)
-#define TEST_DENY(x) ((x >= 0 || x < 5)?1:0)
+static int access_valid(u32 x)
+{
+ return (x > 0 && x < 4);
+}
+
+static int deny_valid(u32 x)
+{
+ return (x >= 0 && x < 5);
+}
static void
set_access(unsigned int *access, unsigned long bmap) {
@@ -1745,7 +1752,8 @@ nfsd4_process_open2(struct svc_rqst *rqs
int status;
status = nfserr_inval;
- if (!TEST_ACCESS(open->op_share_access) || !TEST_DENY(open->op_share_deny))
+ if (!access_valid(open->op_share_access)
+ || !deny_valid(open->op_share_deny))
goto out;
/*
* Lookup file; if found, lookup stateid and check open request,
@@ -2317,7 +2325,8 @@ nfsd4_open_downgrade(struct svc_rqst *rq
(int)current_fh->fh_dentry->d_name.len,
current_fh->fh_dentry->d_name.name);
- if (!TEST_ACCESS(od->od_share_access) || !TEST_DENY(od->od_share_deny))
+ if (!access_valid(od->od_share_access)
+ || !deny_valid(od->od_share_deny))
return nfserr_inval;
nfs4_lock_state();
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 011 of 14] knfsd: nfsd4: fix open flag passing
2006-06-27 7:19 [PATCH 000 of 14] knfsd: Introduction NeilBrown
` (9 preceding siblings ...)
2006-06-27 7:20 ` [PATCH 010 of 14] knfsd: nfsd4: fix some open argument tests NeilBrown
@ 2006-06-27 7:20 ` NeilBrown
2006-06-27 7:20 ` [PATCH 012 of 14] knfsd: svcrpc: Simplify nfsd rpcsec_gss integrity code NeilBrown
` (2 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: NeilBrown @ 2006-06-27 7:20 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs, linux-kernel
From: J. Bruce Fields <bfields@citi.umich.edu>
Since nfsv4 actually keeps around the file descriptors it gets from open
(instead of just using them for a single read or write operation), we need
to make sure that we can do RDWR opens and not just RDONLY/WRONLY.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
### Diffstat output
./fs/nfsd/nfs4state.c | 6 +++---
./fs/nfsd/vfs.c | 5 ++++-
2 files changed, 7 insertions(+), 4 deletions(-)
diff .prev/fs/nfsd/nfs4state.c ./fs/nfsd/nfs4state.c
--- .prev/fs/nfsd/nfs4state.c 2006-06-27 15:00:26.000000000 +1000
+++ ./fs/nfsd/nfs4state.c 2006-06-27 15:04:03.000000000 +1000
@@ -1790,10 +1790,10 @@ nfsd4_process_open2(struct svc_rqst *rqs
} else {
/* Stateid was not found, this is a new OPEN */
int flags = 0;
+ if (open->op_share_access & NFS4_SHARE_ACCESS_READ)
+ flags |= MAY_READ;
if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
- flags = MAY_WRITE;
- else
- flags = MAY_READ;
+ flags |= MAY_WRITE;
status = nfs4_new_open(rqstp, &stp, dp, current_fh, flags);
if (status)
goto out;
diff .prev/fs/nfsd/vfs.c ./fs/nfsd/vfs.c
--- .prev/fs/nfsd/vfs.c 2006-06-27 14:59:40.000000000 +1000
+++ ./fs/nfsd/vfs.c 2006-06-27 15:04:03.000000000 +1000
@@ -673,7 +673,10 @@ nfsd_open(struct svc_rqst *rqstp, struct
goto out_nfserr;
if (access & MAY_WRITE) {
- flags = O_WRONLY|O_LARGEFILE;
+ if (access & MAY_READ)
+ flags = O_RDWR|O_LARGEFILE;
+ else
+ flags = O_WRONLY|O_LARGEFILE;
DQUOT_INIT(inode);
}
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 012 of 14] knfsd: svcrpc: Simplify nfsd rpcsec_gss integrity code
2006-06-27 7:19 [PATCH 000 of 14] knfsd: Introduction NeilBrown
` (10 preceding siblings ...)
2006-06-27 7:20 ` [PATCH 011 of 14] knfsd: nfsd4: fix open flag passing NeilBrown
@ 2006-06-27 7:20 ` NeilBrown
2006-06-27 7:20 ` [PATCH 013 of 14] knfsd: nfsd: mark rqstp to prevent use of sendfile in privacy case NeilBrown
2006-06-27 7:20 ` [PATCH 014 of 14] knfsd: svcrpc: gss: server-side implementation of rpcsec_gss privacy NeilBrown
13 siblings, 0 replies; 15+ messages in thread
From: NeilBrown @ 2006-06-27 7:20 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs, linux-kernel
From: J. Bruce Fields <bfields@citi.umich.edu>
Pull out some of the integrity code into its own function, otherwise
svcauth_gss_release() is going to become very ungainly after the addition
of privacy code.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
### Diffstat output
./net/sunrpc/auth_gss/svcauth_gss.c | 115 ++++++++++++++++++++----------------
1 file changed, 64 insertions(+), 51 deletions(-)
diff .prev/net/sunrpc/auth_gss/svcauth_gss.c ./net/sunrpc/auth_gss/svcauth_gss.c
--- .prev/net/sunrpc/auth_gss/svcauth_gss.c 2006-06-27 14:59:44.000000000 +1000
+++ ./net/sunrpc/auth_gss/svcauth_gss.c 2006-06-27 15:05:11.000000000 +1000
@@ -1072,8 +1072,8 @@ out:
return ret;
}
-static int
-svcauth_gss_release(struct svc_rqst *rqstp)
+static inline int
+svcauth_gss_wrap_resp_integ(struct svc_rqst *rqstp)
{
struct gss_svc_data *gsd = (struct gss_svc_data *)rqstp->rq_auth_data;
struct rpc_gss_wire_cred *gc = &gsd->clcred;
@@ -1085,6 +1085,67 @@ svcauth_gss_release(struct svc_rqst *rqs
int integ_offset, integ_len;
int stat = -EINVAL;
+ p = gsd->body_start;
+ gsd->body_start = NULL;
+ /* move accept_stat to right place: */
+ memcpy(p, p + 2, 4);
+ /* don't wrap in failure case: */
+ /* Note: counting on not getting here if call was not even
+ * accepted! */
+ if (*p != rpc_success) {
+ resbuf->head[0].iov_len -= 2 * 4;
+ goto out;
+ }
+ p++;
+ integ_offset = (u8 *)(p + 1) - (u8 *)resbuf->head[0].iov_base;
+ integ_len = resbuf->len - integ_offset;
+ BUG_ON(integ_len % 4);
+ *p++ = htonl(integ_len);
+ *p++ = htonl(gc->gc_seq);
+ if (xdr_buf_subsegment(resbuf, &integ_buf, integ_offset,
+ integ_len))
+ BUG();
+ if (resbuf->page_len == 0
+ && resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE
+ < PAGE_SIZE) {
+ BUG_ON(resbuf->tail[0].iov_len);
+ /* Use head for everything */
+ resv = &resbuf->head[0];
+ } else if (resbuf->tail[0].iov_base == NULL) {
+ if (resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE > PAGE_SIZE)
+ goto out_err;
+ resbuf->tail[0].iov_base = resbuf->head[0].iov_base
+ + resbuf->head[0].iov_len;
+ resbuf->tail[0].iov_len = 0;
+ rqstp->rq_restailpage = 0;
+ resv = &resbuf->tail[0];
+ } else {
+ resv = &resbuf->tail[0];
+ }
+ mic.data = (u8 *)resv->iov_base + resv->iov_len + 4;
+ if (gss_get_mic(gsd->rsci->mechctx, &integ_buf, &mic))
+ goto out_err;
+ svc_putu32(resv, htonl(mic.len));
+ memset(mic.data + mic.len, 0,
+ round_up_to_quad(mic.len) - mic.len);
+ resv->iov_len += XDR_QUADLEN(mic.len) << 2;
+ /* not strictly required: */
+ resbuf->len += XDR_QUADLEN(mic.len) << 2;
+ BUG_ON(resv->iov_len > PAGE_SIZE);
+out:
+ stat = 0;
+out_err:
+ return stat;
+}
+
+static int
+svcauth_gss_release(struct svc_rqst *rqstp)
+{
+ struct gss_svc_data *gsd = (struct gss_svc_data *)rqstp->rq_auth_data;
+ struct rpc_gss_wire_cred *gc = &gsd->clcred;
+ struct xdr_buf *resbuf = &rqstp->rq_res;
+ int stat = -EINVAL;
+
if (gc->gc_proc != RPC_GSS_PROC_DATA)
goto out;
/* Release can be called twice, but we only wrap once. */
@@ -1097,55 +1158,7 @@ svcauth_gss_release(struct svc_rqst *rqs
case RPC_GSS_SVC_NONE:
break;
case RPC_GSS_SVC_INTEGRITY:
- p = gsd->body_start;
- gsd->body_start = NULL;
- /* move accept_stat to right place: */
- memcpy(p, p + 2, 4);
- /* don't wrap in failure case: */
- /* Note: counting on not getting here if call was not even
- * accepted! */
- if (*p != rpc_success) {
- resbuf->head[0].iov_len -= 2 * 4;
- goto out;
- }
- p++;
- integ_offset = (u8 *)(p + 1) - (u8 *)resbuf->head[0].iov_base;
- integ_len = resbuf->len - integ_offset;
- BUG_ON(integ_len % 4);
- *p++ = htonl(integ_len);
- *p++ = htonl(gc->gc_seq);
- if (xdr_buf_subsegment(resbuf, &integ_buf, integ_offset,
- integ_len))
- BUG();
- if (resbuf->page_len == 0
- && resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE
- < PAGE_SIZE) {
- BUG_ON(resbuf->tail[0].iov_len);
- /* Use head for everything */
- resv = &resbuf->head[0];
- } else if (resbuf->tail[0].iov_base == NULL) {
- if (resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE
- > PAGE_SIZE)
- goto out_err;
- resbuf->tail[0].iov_base =
- resbuf->head[0].iov_base
- + resbuf->head[0].iov_len;
- resbuf->tail[0].iov_len = 0;
- rqstp->rq_restailpage = 0;
- resv = &resbuf->tail[0];
- } else {
- resv = &resbuf->tail[0];
- }
- mic.data = (u8 *)resv->iov_base + resv->iov_len + 4;
- if (gss_get_mic(gsd->rsci->mechctx, &integ_buf, &mic))
- goto out_err;
- svc_putu32(resv, htonl(mic.len));
- memset(mic.data + mic.len, 0,
- round_up_to_quad(mic.len) - mic.len);
- resv->iov_len += XDR_QUADLEN(mic.len) << 2;
- /* not strictly required: */
- resbuf->len += XDR_QUADLEN(mic.len) << 2;
- BUG_ON(resv->iov_len > PAGE_SIZE);
+ svcauth_gss_wrap_resp_integ(rqstp);
break;
case RPC_GSS_SVC_PRIVACY:
default:
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 013 of 14] knfsd: nfsd: mark rqstp to prevent use of sendfile in privacy case
2006-06-27 7:19 [PATCH 000 of 14] knfsd: Introduction NeilBrown
` (11 preceding siblings ...)
2006-06-27 7:20 ` [PATCH 012 of 14] knfsd: svcrpc: Simplify nfsd rpcsec_gss integrity code NeilBrown
@ 2006-06-27 7:20 ` NeilBrown
2006-06-27 7:20 ` [PATCH 014 of 14] knfsd: svcrpc: gss: server-side implementation of rpcsec_gss privacy NeilBrown
13 siblings, 0 replies; 15+ messages in thread
From: NeilBrown @ 2006-06-27 7:20 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs, linux-kernel
From: J. Bruce Fields <bfields@citi.umich.edu>
Add a rq_sendfile_ok flag to svc_rqst which will be cleared in the privacy
case so that the wrapping code will get copies of the read data instead of
real page cache pages. This makes life simpler when we encrypt the
response.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
### Diffstat output
./fs/nfsd/vfs.c | 2 +-
./include/linux/sunrpc/svc.h | 4 +++-
./net/sunrpc/svc.c | 2 ++
3 files changed, 6 insertions(+), 2 deletions(-)
diff .prev/fs/nfsd/vfs.c ./fs/nfsd/vfs.c
--- .prev/fs/nfsd/vfs.c 2006-06-27 15:04:03.000000000 +1000
+++ ./fs/nfsd/vfs.c 2006-06-27 15:07:01.000000000 +1000
@@ -840,7 +840,7 @@ nfsd_vfs_read(struct svc_rqst *rqstp, st
if (ra && ra->p_set)
file->f_ra = ra->p_ra;
- if (file->f_op->sendfile) {
+ if (file->f_op->sendfile && rqstp->rq_sendfile_ok) {
svc_pushback_unused_pages(rqstp);
err = file->f_op->sendfile(file, &offset, *count,
nfsd_read_actor, rqstp);
diff .prev/include/linux/sunrpc/svc.h ./include/linux/sunrpc/svc.h
--- .prev/include/linux/sunrpc/svc.h 2006-06-27 15:07:01.000000000 +1000
+++ ./include/linux/sunrpc/svc.h 2006-06-27 15:07:01.000000000 +1000
@@ -159,7 +159,9 @@ struct svc_rqst {
* determine what device number
* to report (real or virtual)
*/
-
+ int rq_sendfile_ok; /* turned off in gss privacy
+ * to prevent encrypting page
+ * cache pages */
wait_queue_head_t rq_wait; /* synchronization */
};
diff .prev/net/sunrpc/svc.c ./net/sunrpc/svc.c
--- .prev/net/sunrpc/svc.c 2006-06-27 15:07:01.000000000 +1000
+++ ./net/sunrpc/svc.c 2006-06-27 15:07:01.000000000 +1000
@@ -281,6 +281,8 @@ svc_process(struct svc_serv *serv, struc
rqstp->rq_res.page_len = 0;
rqstp->rq_res.buflen = PAGE_SIZE;
rqstp->rq_res.tail[0].iov_len = 0;
+ /* Will be turned off only in gss privacy case: */
+ rqstp->rq_sendfile_ok = 1;
/* tcp needs a space for the record length... */
if (rqstp->rq_prot == IPPROTO_TCP)
svc_putu32(resv, 0);
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 014 of 14] knfsd: svcrpc: gss: server-side implementation of rpcsec_gss privacy.
2006-06-27 7:19 [PATCH 000 of 14] knfsd: Introduction NeilBrown
` (12 preceding siblings ...)
2006-06-27 7:20 ` [PATCH 013 of 14] knfsd: nfsd: mark rqstp to prevent use of sendfile in privacy case NeilBrown
@ 2006-06-27 7:20 ` NeilBrown
13 siblings, 0 replies; 15+ messages in thread
From: NeilBrown @ 2006-06-27 7:20 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs, linux-kernel
From: J. Bruce Fields <bfields@citi.umich.edu>
Server-side implementation of rpcsec_gss privacy, which enables encryption
of the payload of every rpc request and response.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
### Diffstat output
./net/sunrpc/auth_gss/svcauth_gss.c | 154 ++++++++++++++++++++++++++++++++++--
./net/sunrpc/svc.c | 1
2 files changed, 148 insertions(+), 7 deletions(-)
diff .prev/net/sunrpc/auth_gss/svcauth_gss.c ./net/sunrpc/auth_gss/svcauth_gss.c
--- .prev/net/sunrpc/auth_gss/svcauth_gss.c 2006-06-27 15:05:11.000000000 +1000
+++ ./net/sunrpc/auth_gss/svcauth_gss.c 2006-06-27 15:07:54.000000000 +1000
@@ -832,6 +832,74 @@ out:
return stat;
}
+static inline int
+total_buf_len(struct xdr_buf *buf)
+{
+ return buf->head[0].iov_len + buf->page_len + buf->tail[0].iov_len;
+}
+
+static void
+fix_priv_head(struct xdr_buf *buf, int pad)
+{
+ if (buf->page_len == 0) {
+ /* We need to adjust head and buf->len in tandem in this
+ * case to make svc_defer() work--it finds the original
+ * buffer start using buf->len - buf->head[0].iov_len. */
+ buf->head[0].iov_len -= pad;
+ }
+}
+
+static int
+unwrap_priv_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx)
+{
+ u32 priv_len, maj_stat;
+ int pad, saved_len, remaining_len, offset;
+
+ rqstp->rq_sendfile_ok = 0;
+
+ priv_len = ntohl(svc_getu32(&buf->head[0]));
+ if (rqstp->rq_deferred) {
+ /* Already decrypted last time through! The sequence number
+ * check at out_seq is unnecessary but harmless: */
+ goto out_seq;
+ }
+ /* buf->len is the number of bytes from the original start of the
+ * request to the end, where head[0].iov_len is just the bytes
+ * not yet read from the head, so these two values are different: */
+ remaining_len = total_buf_len(buf);
+ if (priv_len > remaining_len)
+ return -EINVAL;
+ pad = remaining_len - priv_len;
+ buf->len -= pad;
+ fix_priv_head(buf, pad);
+
+ /* Maybe it would be better to give gss_unwrap a length parameter: */
+ saved_len = buf->len;
+ buf->len = priv_len;
+ maj_stat = gss_unwrap(ctx, 0, buf);
+ pad = priv_len - buf->len;
+ buf->len = saved_len;
+ buf->len -= pad;
+ /* The upper layers assume the buffer is aligned on 4-byte boundaries.
+ * In the krb5p case, at least, the data ends up offset, so we need to
+ * move it around. */
+ /* XXX: This is very inefficient. It would be better to either do
+ * this while we encrypt, or maybe in the receive code, if we can peak
+ * ahead and work out the service and mechanism there. */
+ offset = buf->head[0].iov_len % 4;
+ if (offset) {
+ buf->buflen = RPCSVC_MAXPAYLOAD;
+ xdr_shift_buf(buf, offset);
+ fix_priv_head(buf, pad);
+ }
+ if (maj_stat != GSS_S_COMPLETE)
+ return -EINVAL;
+out_seq:
+ if (ntohl(svc_getu32(&buf->head[0])) != seq)
+ return -EINVAL;
+ return 0;
+}
+
struct gss_svc_data {
/* decoded gss client cred: */
struct rpc_gss_wire_cred clcred;
@@ -1047,7 +1115,14 @@ svcauth_gss_accept(struct svc_rqst *rqst
svc_putu32(resv, 0);
break;
case RPC_GSS_SVC_PRIVACY:
- /* currently unsupported */
+ if (unwrap_priv_data(rqstp, &rqstp->rq_arg,
+ gc->gc_seq, rsci->mechctx))
+ goto auth_err;
+ /* placeholders for length and seq. number: */
+ svcdata->body_start = resv->iov_base + resv->iov_len;
+ svc_putu32(resv, 0);
+ svc_putu32(resv, 0);
+ break;
default:
goto auth_err;
}
@@ -1089,9 +1164,8 @@ svcauth_gss_wrap_resp_integ(struct svc_r
gsd->body_start = NULL;
/* move accept_stat to right place: */
memcpy(p, p + 2, 4);
- /* don't wrap in failure case: */
- /* Note: counting on not getting here if call was not even
- * accepted! */
+ /* Don't wrap in failure case: */
+ /* Counting on not getting here if call was not even accepted! */
if (*p != rpc_success) {
resbuf->head[0].iov_len -= 2 * 4;
goto out;
@@ -1138,6 +1212,65 @@ out_err:
return stat;
}
+static inline int
+svcauth_gss_wrap_resp_priv(struct svc_rqst *rqstp)
+{
+ struct gss_svc_data *gsd = (struct gss_svc_data *)rqstp->rq_auth_data;
+ struct rpc_gss_wire_cred *gc = &gsd->clcred;
+ struct xdr_buf *resbuf = &rqstp->rq_res;
+ struct page **inpages = NULL;
+ u32 *p;
+ int offset, *len;
+ int pad;
+
+ p = gsd->body_start;
+ gsd->body_start = NULL;
+ /* move accept_stat to right place: */
+ memcpy(p, p + 2, 4);
+ /* Don't wrap in failure case: */
+ /* Counting on not getting here if call was not even accepted! */
+ if (*p != rpc_success) {
+ resbuf->head[0].iov_len -= 2 * 4;
+ return 0;
+ }
+ p++;
+ len = p++;
+ offset = (u8 *)p - (u8 *)resbuf->head[0].iov_base;
+ *p++ = htonl(gc->gc_seq);
+ inpages = resbuf->pages;
+ /* XXX: Would be better to write some xdr helper functions for
+ * nfs{2,3,4}xdr.c that place the data right, instead of copying: */
+ if (resbuf->tail[0].iov_base && rqstp->rq_restailpage == 0) {
+ BUG_ON(resbuf->tail[0].iov_base >= resbuf->head[0].iov_base
+ + PAGE_SIZE);
+ BUG_ON(resbuf->tail[0].iov_base < resbuf->head[0].iov_base);
+ if (resbuf->tail[0].iov_len + resbuf->head[0].iov_len
+ + 2 * RPC_MAX_AUTH_SIZE > PAGE_SIZE)
+ return -ENOMEM;
+ memmove(resbuf->tail[0].iov_base + RPC_MAX_AUTH_SIZE,
+ resbuf->tail[0].iov_base,
+ resbuf->tail[0].iov_len);
+ resbuf->tail[0].iov_base += RPC_MAX_AUTH_SIZE;
+ }
+ if (resbuf->tail[0].iov_base == NULL) {
+ if (resbuf->head[0].iov_len + 2*RPC_MAX_AUTH_SIZE > PAGE_SIZE)
+ return -ENOMEM;
+ resbuf->tail[0].iov_base = resbuf->head[0].iov_base
+ + resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE;
+ resbuf->tail[0].iov_len = 0;
+ rqstp->rq_restailpage = 0;
+ }
+ if (gss_wrap(gsd->rsci->mechctx, offset, resbuf, inpages))
+ return -ENOMEM;
+ *len = htonl(resbuf->len - offset);
+ pad = 3 - ((resbuf->len - offset - 1)&3);
+ p = (u32 *)(resbuf->tail[0].iov_base + resbuf->tail[0].iov_len);
+ memset(p, 0, pad);
+ resbuf->tail[0].iov_len += pad;
+ resbuf->len += pad;
+ return 0;
+}
+
static int
svcauth_gss_release(struct svc_rqst *rqstp)
{
@@ -1152,15 +1285,22 @@ svcauth_gss_release(struct svc_rqst *rqs
if (gsd->body_start == NULL)
goto out;
/* normally not set till svc_send, but we need it here: */
- resbuf->len = resbuf->head[0].iov_len
- + resbuf->page_len + resbuf->tail[0].iov_len;
+ /* XXX: what for? Do we mess it up the moment we call svc_putu32
+ * or whatever? */
+ resbuf->len = total_buf_len(resbuf);
switch (gc->gc_svc) {
case RPC_GSS_SVC_NONE:
break;
case RPC_GSS_SVC_INTEGRITY:
- svcauth_gss_wrap_resp_integ(rqstp);
+ stat = svcauth_gss_wrap_resp_integ(rqstp);
+ if (stat)
+ goto out_err;
break;
case RPC_GSS_SVC_PRIVACY:
+ stat = svcauth_gss_wrap_resp_priv(rqstp);
+ if (stat)
+ goto out_err;
+ break;
default:
goto out_err;
}
diff .prev/net/sunrpc/svc.c ./net/sunrpc/svc.c
--- .prev/net/sunrpc/svc.c 2006-06-27 15:07:01.000000000 +1000
+++ ./net/sunrpc/svc.c 2006-06-27 15:07:54.000000000 +1000
@@ -280,6 +280,7 @@ svc_process(struct svc_serv *serv, struc
rqstp->rq_res.page_base = 0;
rqstp->rq_res.page_len = 0;
rqstp->rq_res.buflen = PAGE_SIZE;
+ rqstp->rq_res.tail[0].iov_base = NULL;
rqstp->rq_res.tail[0].iov_len = 0;
/* Will be turned off only in gss privacy case: */
rqstp->rq_sendfile_ok = 1;
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2006-06-27 7:24 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-06-27 7:19 [PATCH 000 of 14] knfsd: Introduction NeilBrown
2006-06-27 7:19 ` [PATCH 001 of 14] knfsd: Improve the test for cross-device-rename in nfsd NeilBrown
2006-06-27 7:19 ` [PATCH 002 of 14] knfsd: Fixing missing 'expkey' support for fsid type 3 NeilBrown
2006-06-27 7:19 ` [PATCH 003 of 14] knfsd: Remove noise about filehandle being uptodate NeilBrown
2006-06-27 7:19 ` [PATCH 004 of 14] knfsd: Ignore ref_fh when crossing a mountpoint NeilBrown
2006-06-27 7:20 ` [PATCH 005 of 14] knfsd: nfsd4: fix open_confirm locking NeilBrown
2006-06-27 7:20 ` [PATCH 006 of 14] knfsd: nfsd: call nfsd_setuser() on fh_compose(), fix nfsd4 permissions problem NeilBrown
2006-06-27 7:20 ` [PATCH 007 of 14] knfsd: nfsd4: remove superfluous grace period checks NeilBrown
2006-06-27 7:20 ` [PATCH 008 of 14] knfsd: nfsd: fix misplaced fh_unlock() in nfsd_link() NeilBrown
2006-06-27 7:20 ` [PATCH 009 of 14] knfsd: svcrpc: gss: simplify rsc_parse() NeilBrown
2006-06-27 7:20 ` [PATCH 010 of 14] knfsd: nfsd4: fix some open argument tests NeilBrown
2006-06-27 7:20 ` [PATCH 011 of 14] knfsd: nfsd4: fix open flag passing NeilBrown
2006-06-27 7:20 ` [PATCH 012 of 14] knfsd: svcrpc: Simplify nfsd rpcsec_gss integrity code NeilBrown
2006-06-27 7:20 ` [PATCH 013 of 14] knfsd: nfsd: mark rqstp to prevent use of sendfile in privacy case NeilBrown
2006-06-27 7:20 ` [PATCH 014 of 14] knfsd: svcrpc: gss: server-side implementation of rpcsec_gss privacy NeilBrown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox