summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorMilan Cermak <Milan.Cermak@Sun.COM>2009-10-16 14:29:31 +0200
committerMilan Cermak <Milan.Cermak@Sun.COM>2009-10-16 14:29:31 +0200
commit7b2df5ebde6d44f72fc0d1a8370f1134c8a539f3 (patch)
tree2b111f140b05a30f88d6bd680f41070b1cd5bdc6 /usr/src
parent0f1d7ad6f691d02be262fe5a16f0edd3762a68e8 (diff)
downloadillumos-gate-7b2df5ebde6d44f72fc0d1a8370f1134c8a539f3.tar.gz
6851335 CAPI.os/files/realpath/T.realpath{5,6} failed in VSU'03
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/fs/lookup.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/usr/src/uts/common/fs/lookup.c b/usr/src/uts/common/fs/lookup.c
index ee87647398..ed76b40b6d 100644
--- a/usr/src/uts/common/fs/lookup.c
+++ b/usr/src/uts/common/fs/lookup.c
@@ -1009,12 +1009,13 @@ localpath(char *path, struct vnode *vrootp, cred_t *cr)
* (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 @@ dirtopath(vnode_t *vrootp, vnode_t *vp, char *buf, size_t buflen, cred_t *cr)
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 @@ dirtopath(vnode_t *vrootp, vnode_t *vp, char *buf, size_t buflen, cred_t *cr)
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 @@ dirtopath(vnode_t *vrootp, vnode_t *vp, char *buf, size_t buflen, cred_t *cr)
}
/*
+ * 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 @@ notcached:
* 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 @@ notcached:
} else
ret = ENOENT;
} else
- ret = dirtopath(vrootp, vp, buf, buflen, cr);
+ ret = dirtopath(vrootp, vp, buf, buflen, flags, cr);
VN_RELE(vrootp);
if (doclose) {