summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorsdussud <none@none>2005-09-08 02:10:22 -0700
committersdussud <none@none>2005-09-08 02:10:22 -0700
commitd76e27277980bfe882ce035e3401d083dabe0f3e (patch)
tree076128df17efa3222336a322bc5e448be9349ae3 /usr/src
parent660acd8147e63f8aa3756ff90d3d0b9c1f66e120 (diff)
downloadillumos-gate-d76e27277980bfe882ce035e3401d083dabe0f3e.tar.gz
6226092 getcwd() not consistent when dealing with NFS directories and setuid applications
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/fs/nfs/nfs3_vnops.c38
-rw-r--r--usr/src/uts/common/fs/nfs/nfs4_vnops.c41
-rw-r--r--usr/src/uts/common/fs/nfs/nfs_acl_vnops.c39
3 files changed, 78 insertions, 40 deletions
diff --git a/usr/src/uts/common/fs/nfs/nfs3_vnops.c b/usr/src/uts/common/fs/nfs/nfs3_vnops.c
index ba63134e43..5fee1fdc57 100644
--- a/usr/src/uts/common/fs/nfs/nfs3_vnops.c
+++ b/usr/src/uts/common/fs/nfs/nfs3_vnops.c
@@ -1421,7 +1421,7 @@ nfs3_access(vnode_t *vp, int mode, int flags, cred_t *cr)
int douprintf;
uint32 acc;
rnode_t *rp;
- cred_t *cred;
+ cred_t *cred, *ncr;
failinfo_t fi;
nfs_access_type_t cacc;
hrtime_t t;
@@ -1446,14 +1446,6 @@ nfs3_access(vnode_t *vp, int mode, int flags, cred_t *cr)
}
rp = VTOR(vp);
- if (rp->r_acache != NULL) {
- cacc = nfs_access_check(rp, acc, cr);
- if (cacc == NFS_ACCESS_ALLOWED)
- return (0);
- if (cacc == NFS_ACCESS_DENIED)
- return (EACCES);
- }
-
args.object = *VTOFH3(vp);
if (vp->v_type == VDIR) {
args.access = ACCESS3_READ | ACCESS3_DELETE | ACCESS3_MODIFY |
@@ -1469,7 +1461,26 @@ nfs3_access(vnode_t *vp, int mode, int flags, cred_t *cr)
fi.xattrdirproc = acl_getxattrdir3;
cred = cr;
+ ncr = crnetadjust(cred);
tryagain:
+ if (rp->r_acache != NULL) {
+ cacc = nfs_access_check(rp, acc, cred);
+ if (cacc == NFS_ACCESS_ALLOWED)
+ return (0);
+ if (cacc == NFS_ACCESS_DENIED) {
+ /*
+ * If the cred can be adjusted, try again
+ * with the new cred.
+ */
+ if (ncr != NULL) {
+ cred = ncr;
+ ncr = NULL;
+ goto tryagain;
+ }
+ return (EACCES);
+ }
+ }
+
douprintf = 1;
t = gethrtime();
@@ -1488,16 +1499,19 @@ tryagain:
error = geterrno3(res.status);
if (!error) {
nfs3_cache_post_op_attr(vp, &res.resok.obj_attributes, t, cr);
+ nfs_access_cache(rp, args.access, res.resok.access, cred);
if ((acc & res.resok.access) != acc) {
- cred_t *ncr = crnetadjust(cred);
-
+ /*
+ * If the cred can be adjusted, try again
+ * with the new cred.
+ */
if (ncr != NULL) {
cred = ncr;
+ ncr = NULL;
goto tryagain;
}
error = EACCES;
}
- nfs_access_cache(rp, args.access, res.resok.access, cr);
} else {
nfs3_cache_post_op_attr(vp, &res.resfail.obj_attributes, t, cr);
PURGE_STALE_FH(error, vp, cr);
diff --git a/usr/src/uts/common/fs/nfs/nfs4_vnops.c b/usr/src/uts/common/fs/nfs/nfs4_vnops.c
index e763c0bbfa..5e6cc0c575 100644
--- a/usr/src/uts/common/fs/nfs/nfs4_vnops.c
+++ b/usr/src/uts/common/fs/nfs/nfs4_vnops.c
@@ -4092,7 +4092,7 @@ nfs4_access(vnode_t *vp, int mode, int flags, cred_t *cr)
int doqueue;
uint32_t acc, resacc, argacc;
rnode4_t *rp;
- cred_t *cred;
+ cred_t *cred, *ncr;
nfs4_access_type_t cacc;
int num_ops;
nfs_argop4 argop[3];
@@ -4131,11 +4131,6 @@ nfs4_access(vnode_t *vp, int mode, int flags, cred_t *cr)
}
rp = VTOR4(vp);
- cacc = nfs4_access_check(rp, acc, cr);
- if (cacc == NFS4_ACCESS_ALLOWED)
- return (0);
- if (cacc == NFS4_ACCESS_DENIED)
- return (EACCES);
if (vp->v_type == VDIR) {
argacc = ACCESS4_READ | ACCESS4_DELETE | ACCESS4_MODIFY |
ACCESS4_EXTEND | ACCESS4_LOOKUP;
@@ -4147,8 +4142,25 @@ nfs4_access(vnode_t *vp, int mode, int flags, cred_t *cr)
recov_state.rs_num_retry_despite_err = 0;
cred = cr;
+ ncr = crnetadjust(cred);
tryagain:
+ cacc = nfs4_access_check(rp, acc, cred);
+ if (cacc == NFS4_ACCESS_ALLOWED)
+ return (0);
+ if (cacc == NFS4_ACCESS_DENIED) {
+ /*
+ * If the cred can be adjusted, try again
+ * with the new cred.
+ */
+ if (ncr != NULL) {
+ cred = ncr;
+ ncr = NULL;
+ goto tryagain;
+ }
+ return (EACCES);
+ }
+
recov_retry:
/*
* Don't take with r_statev4_lock here. r_deleg_type could
@@ -4233,6 +4245,7 @@ recov_retry:
}
if (!e.error) {
+ nfs4_access_cache(rp, argacc, resacc, cred);
/* XXX check the supported bits too? */
if ((acc & resacc) != acc) {
/*
@@ -4243,19 +4256,15 @@ recov_retry:
* of the implementation of this functionality.
*/
/* XXX-LP */
- if (crgetuid(cred) == 0 && crgetruid(cred) != 0) {
- cred_t *ncr = crnetadjust(cred);
-
- if (ncr != NULL) {
- (void) xdr_free(xdr_COMPOUND4res_clnt,
- (caddr_t)&res);
- cred = ncr;
- goto tryagain;
- }
+ if (ncr != NULL) {
+ (void) xdr_free(xdr_COMPOUND4res_clnt,
+ (caddr_t)&res);
+ cred = ncr;
+ ncr = NULL;
+ goto tryagain;
}
e.error = EACCES;
}
- nfs4_access_cache(rp, argacc, resacc, cr);
}
out:
diff --git a/usr/src/uts/common/fs/nfs/nfs_acl_vnops.c b/usr/src/uts/common/fs/nfs/nfs_acl_vnops.c
index 9adceb4a37..c1b129176c 100644
--- a/usr/src/uts/common/fs/nfs/nfs_acl_vnops.c
+++ b/usr/src/uts/common/fs/nfs/nfs_acl_vnops.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -283,7 +283,7 @@ acl_access2(vnode_t *vp, int mode, int flags, cred_t *cr)
int doqueue;
uint32 acc;
rnode_t *rp;
- cred_t *cred;
+ cred_t *cred, *ncr;
vattr_t va;
failinfo_t fi;
nfs_access_type_t cacc;
@@ -307,14 +307,6 @@ acl_access2(vnode_t *vp, int mode, int flags, cred_t *cr)
}
rp = VTOR(vp);
- if (rp->r_acache != NULL) {
- cacc = nfs_access_check(rp, acc, cr);
- if (cacc == NFS_ACCESS_ALLOWED)
- return (0);
- if (cacc == NFS_ACCESS_DENIED)
- return (EACCES);
- }
-
if (vp->v_type == VDIR) {
args.access = ACCESS2_READ | ACCESS2_DELETE | ACCESS2_MODIFY |
ACCESS2_EXTEND | ACCESS2_LOOKUP;
@@ -330,8 +322,27 @@ acl_access2(vnode_t *vp, int mode, int flags, cred_t *cr)
fi.xattrdirproc = acl_getxattrdir2;
cred = cr;
+ ncr = crnetadjust(cred);
tryagain:
+ if (rp->r_acache != NULL) {
+ cacc = nfs_access_check(rp, acc, cr);
+ if (cacc == NFS_ACCESS_ALLOWED)
+ return (0);
+ if (cacc == NFS_ACCESS_DENIED) {
+ /*
+ * If the cred can be adjusted, try again
+ * with the new cred.
+ */
+ if (ncr != NULL) {
+ cred = ncr;
+ ncr = NULL;
+ goto tryagain;
+ }
+ return (EACCES);
+ }
+ }
+
doqueue = 1;
t = gethrtime();
@@ -350,15 +361,19 @@ tryagain:
error = geterrno(res.status);
if (!error) {
(void) nfs_cache_fattr(vp, &res.resok.attr, &va, t, cr);
+ nfs_access_cache(rp, args.access, res.resok.access, cred);
if ((acc & res.resok.access) != acc) {
- cred_t *ncr = crnetadjust(cred);
+ /*
+ * If the cred can be adjusted, try again
+ * with the new cred.
+ */
if (ncr != NULL) {
cred = ncr;
+ ncr = NULL;
goto tryagain;
}
error = EACCES;
}
- nfs_access_cache(rp, args.access, res.resok.access, cr);
} else {
PURGE_STALE_FH(error, vp, cr);
}