diff options
author | Milan Cermak <Milan.Cermak@Sun.COM> | 2009-10-16 14:29:31 +0200 |
---|---|---|
committer | Milan Cermak <Milan.Cermak@Sun.COM> | 2009-10-16 14:29:31 +0200 |
commit | 7b2df5ebde6d44f72fc0d1a8370f1134c8a539f3 (patch) | |
tree | 2b111f140b05a30f88d6bd680f41070b1cd5bdc6 /usr/src | |
parent | 0f1d7ad6f691d02be262fe5a16f0edd3762a68e8 (diff) | |
download | illumos-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.c | 33 |
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) { |