aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/vfs_lookup.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/vfs_lookup.c')
-rw-r--r--sys/kern/vfs_lookup.c78
1 files changed, 11 insertions, 67 deletions
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
index f91eecfd26c6..23e8ac95669c 100644
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -179,13 +179,6 @@ nameicap_tracker_add(struct nameidata *ndp, struct vnode *dp)
if ((ndp->ni_lcf & NI_LCF_CAP_DOTDOT) == 0 || dp->v_type != VDIR)
return;
cnp = &ndp->ni_cnd;
- if ((cnp->cn_flags & BENEATH) != 0 &&
- (ndp->ni_lcf & NI_LCF_BENEATH_LATCHED) == 0) {
- MPASS((ndp->ni_lcf & NI_LCF_LATCH) != 0);
- if (dp != ndp->ni_beneath_latch)
- return;
- ndp->ni_lcf |= NI_LCF_BENEATH_LATCHED;
- }
nt = uma_zalloc(nt_zone, M_WAITOK);
vhold(dp);
nt->dp = dp;
@@ -193,7 +186,7 @@ nameicap_tracker_add(struct nameidata *ndp, struct vnode *dp)
}
static void
-nameicap_cleanup(struct nameidata *ndp, bool clean_latch)
+nameicap_cleanup(struct nameidata *ndp)
{
struct nameicap_tracker *nt, *nt1;
@@ -204,10 +197,6 @@ nameicap_cleanup(struct nameidata *ndp, bool clean_latch)
vdrop(nt->dp);
uma_zfree(nt_zone, nt);
}
- if (clean_latch && (ndp->ni_lcf & NI_LCF_LATCH) != 0) {
- ndp->ni_lcf &= ~NI_LCF_LATCH;
- vrele(ndp->ni_beneath_latch);
- }
}
/*
@@ -227,21 +216,17 @@ nameicap_check_dotdot(struct nameidata *ndp, struct vnode *dp)
struct nameicap_tracker *nt;
struct mount *mp;
- if ((ndp->ni_lcf & NI_LCF_CAP_DOTDOT) == 0 || dp == NULL ||
- dp->v_type != VDIR)
+ if (dp == NULL || dp->v_type != VDIR || (ndp->ni_lcf &
+ NI_LCF_STRICTRELATIVE) == 0)
return (0);
+ if ((ndp->ni_lcf & NI_LCF_CAP_DOTDOT) == 0)
+ return (ENOTCAPABLE);
mp = dp->v_mount;
if (lookup_cap_dotdot_nonlocal == 0 && mp != NULL &&
(mp->mnt_flag & MNT_LOCAL) == 0)
return (ENOTCAPABLE);
TAILQ_FOREACH_REVERSE(nt, &ndp->ni_cap_tracker, nameicap_tracker_head,
nm_link) {
- if ((ndp->ni_lcf & NI_LCF_LATCH) != 0 &&
- ndp->ni_beneath_latch == nt->dp) {
- ndp->ni_lcf &= ~NI_LCF_BENEATH_LATCHED;
- nameicap_cleanup(ndp, false);
- return (0);
- }
if (dp == nt->dp)
return (0);
}
@@ -272,11 +257,6 @@ namei_handle_root(struct nameidata *ndp, struct vnode **dpp)
#endif
return (ENOTCAPABLE);
}
- if ((cnp->cn_flags & BENEATH) != 0) {
- ndp->ni_lcf |= NI_LCF_BENEATH_ABS;
- ndp->ni_lcf &= ~NI_LCF_BENEATH_LATCHED;
- nameicap_cleanup(ndp, false);
- }
while (*(cnp->cn_nameptr) == '/') {
cnp->cn_nameptr++;
ndp->ni_pathlen--;
@@ -318,7 +298,6 @@ namei(struct nameidata *ndp)
struct thread *td;
struct proc *p;
cap_rights_t rights;
- struct filecaps dirfd_caps;
struct uio auio;
int error, linklen, startdir_used;
@@ -478,28 +457,10 @@ namei(struct nameidata *ndp)
if (error == 0 && dp->v_type != VDIR)
error = ENOTDIR;
}
- if (error == 0 && (cnp->cn_flags & BENEATH) != 0) {
- if (ndp->ni_dirfd == AT_FDCWD) {
- ndp->ni_beneath_latch = fdp->fd_cdir;
- vrefact(ndp->ni_beneath_latch);
- } else {
- rights = ndp->ni_rightsneeded;
- cap_rights_set(&rights, CAP_LOOKUP);
- error = fgetvp_rights(td, ndp->ni_dirfd, &rights,
- &dirfd_caps, &ndp->ni_beneath_latch);
- if (error == 0 && dp->v_type != VDIR) {
- vrele(ndp->ni_beneath_latch);
- error = ENOTDIR;
- }
- }
- if (error == 0)
- ndp->ni_lcf |= NI_LCF_LATCH;
- }
FILEDESC_SUNLOCK(fdp);
if (error == 0 && (cnp->cn_flags & RBENEATH) != 0) {
- if (cnp->cn_pnbuf[0] == '/' ||
- (ndp->ni_lcf & NI_LCF_BENEATH_ABS) != 0) {
+ if (cnp->cn_pnbuf[0] == '/') {
error = EINVAL;
} else if ((ndp->ni_lcf & NI_LCF_STRICTRELATIVE) == 0) {
ndp->ni_lcf |= NI_LCF_STRICTRELATIVE |
@@ -514,28 +475,16 @@ namei(struct nameidata *ndp)
vrele(dp);
goto out;
}
- MPASS((ndp->ni_lcf & (NI_LCF_BENEATH_ABS | NI_LCF_LATCH)) !=
- NI_LCF_BENEATH_ABS);
- if (((ndp->ni_lcf & NI_LCF_STRICTRELATIVE) != 0 &&
- lookup_cap_dotdot != 0) ||
- ((ndp->ni_lcf & NI_LCF_STRICTRELATIVE) == 0 &&
- (cnp->cn_flags & BENEATH) != 0))
+ if ((ndp->ni_lcf & NI_LCF_STRICTRELATIVE) != 0 &&
+ lookup_cap_dotdot != 0)
ndp->ni_lcf |= NI_LCF_CAP_DOTDOT;
SDT_PROBE3(vfs, namei, lookup, entry, dp, cnp->cn_pnbuf,
cnp->cn_flags);
for (;;) {
ndp->ni_startdir = dp;
error = lookup(ndp);
- if (error != 0) {
- /*
- * Override an error to not allow user to use
- * BENEATH as an oracle.
- */
- if ((ndp->ni_lcf & (NI_LCF_LATCH |
- NI_LCF_BENEATH_LATCHED)) == NI_LCF_LATCH)
- error = ENOTCAPABLE;
+ if (error != 0)
goto out;
- }
/*
* If not a symbolic link, we're done.
@@ -546,12 +495,7 @@ namei(struct nameidata *ndp)
namei_cleanup_cnp(cnp);
} else
cnp->cn_flags |= HASBUF;
- if ((ndp->ni_lcf & (NI_LCF_LATCH |
- NI_LCF_BENEATH_LATCHED)) == NI_LCF_LATCH) {
- NDFREE(ndp, 0);
- error = ENOTCAPABLE;
- }
- nameicap_cleanup(ndp, true);
+ nameicap_cleanup(ndp);
SDT_PROBE2(vfs, namei, lookup, return, error,
(error == 0 ? ndp->ni_vp : NULL));
return (error);
@@ -627,7 +571,7 @@ out:
vrele(ndp->ni_rootdir);
MPASS(error != 0);
namei_cleanup_cnp(cnp);
- nameicap_cleanup(ndp, true);
+ nameicap_cleanup(ndp);
SDT_PROBE2(vfs, namei, lookup, return, error, NULL);
return (error);
}