diff options
Diffstat (limited to 'sys/kern/vfs_lookup.c')
-rw-r--r-- | sys/kern/vfs_lookup.c | 78 |
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); } |