changeset 10808:a45deaebc104

6851335 CAPI.os/files/realpath/T.realpath{5,6} failed in VSU'03
author Milan Cermak <Milan.Cermak@Sun.COM>
date Fri, 16 Oct 2009 14:29:31 +0200
parents 297ce6bece32
children c7cff361425e
files usr/src/uts/common/fs/lookup.c
diffstat 1 files changed, 27 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/fs/lookup.c	Fri Oct 16 09:39:19 2009 +0100
+++ b/usr/src/uts/common/fs/lookup.c	Fri Oct 16 14:29:31 2009 +0200
@@ -1009,12 +1009,13 @@
  * (or vfs_vnode_path is not set).
  */
 static int
-dirtopath(vnode_t *vrootp, vnode_t *vp, char *buf, size_t buflen, cred_t *cr)
+dirtopath(vnode_t *vrootp, vnode_t *vp, char *buf, size_t buflen, int flags,
+    cred_t *cr)
 {
 	pathname_t pn, rpn, emptypn;
 	vnode_t *cmpvp, *pvp = NULL;
 	vnode_t *startvp = vp;
-	int err = 0;
+	int err = 0, vprivs;
 	size_t complen;
 	char *dbuf;
 	dirent64_t *dp;
@@ -1086,7 +1087,7 @@
 				VN_HOLD(vrootp);
 				if (vrootp != rootdir)
 					VN_HOLD(vrootp);
-				if (lookuppnvp(&pn, &rpn, 0, NULL,
+				if (lookuppnvp(&pn, &rpn, flags, NULL,
 				    &cmpvp, vrootp, vrootp, cr) == 0) {
 
 					if (VN_CMP(vp, cmpvp)) {
@@ -1127,7 +1128,7 @@
 				VN_HOLD(vrootp);
 				if (vrootp != rootdir)
 					VN_HOLD(vrootp);
-				if (lookuppnvp(&pn, &rpn, 0, NULL,
+				if (lookuppnvp(&pn, &rpn, flags, NULL,
 				    &cmpvp, vrootp, vrootp, cr) == 0) {
 
 					if (VN_CMP(vp, cmpvp)) {
@@ -1183,6 +1184,15 @@
 		}
 
 		/*
+		 * Check if we have read and search privilege so, that
+		 * we can lookup the path in the directory
+		 */
+		vprivs = (flags & LOOKUP_CHECKREAD) ? VREAD | VEXEC : VEXEC;
+		if ((err = VOP_ACCESS(pvp, vprivs, 0, cr, NULL)) != 0) {
+			goto out;
+		}
+
+		/*
 		 * Try to obtain the path component from dnlc cache
 		 * before searching through the directory.
 		 */
@@ -1441,7 +1451,18 @@
 		 * directory search to find the full path.
 		 */
 		if ((pvp = dnlc_reverse_lookup(vp, path, MAXNAMELEN)) != NULL) {
-			ret = dirtopath(vrootp, pvp, buf, buflen, cr);
+			/*
+			 * Check if we have read privilege so, that
+			 * we can lookup the path in the directory
+			 */
+			ret = 0;
+			if ((flags & LOOKUP_CHECKREAD)) {
+				ret = VOP_ACCESS(pvp, VREAD, 0, cr, NULL);
+			}
+			if (ret == 0) {
+				ret = dirtopath(vrootp, pvp, buf, buflen,
+				    flags, cr);
+			}
 			if (ret == 0) {
 				len = strlen(buf);
 				if (len + strlen(path) + 1 >= buflen) {
@@ -1458,7 +1479,7 @@
 		} else
 			ret = ENOENT;
 	} else
-		ret = dirtopath(vrootp, vp, buf, buflen, cr);
+		ret = dirtopath(vrootp, vp, buf, buflen, flags, cr);
 
 	VN_RELE(vrootp);
 	if (doclose) {