lookup(): ensure that openat("/", "..", O_RESOLVE_BENEATH) fails

PR:	269780
Reported by:	Dan Gohman <dev@sunfishcode.online>
Reviewed by:	emaste, markj
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D39773
This commit is contained in:
Konstantin Belousov 2023-04-24 02:21:42 +03:00
parent 77d2a2d065
commit a718431c30

View File

@ -1083,12 +1083,16 @@ vfs_lookup(struct nameidata *ndp)
pr = pr->pr_parent)
if (dp == pr->pr_root)
break;
if (dp == ndp->ni_rootdir ||
dp == ndp->ni_topdir ||
dp == rootvnode ||
pr != NULL ||
((dp->v_vflag & VV_ROOT) != 0 &&
(cnp->cn_flags & NOCROSSMOUNT) != 0)) {
bool isroot = dp == ndp->ni_rootdir ||
dp == ndp->ni_topdir || dp == rootvnode ||
pr != NULL;
if (isroot && (ndp->ni_lcf &
NI_LCF_STRICTRELATIVE) != 0) {
error = ENOTCAPABLE;
goto capdotdot;
}
if (isroot || ((dp->v_vflag & VV_ROOT) != 0 &&
(cnp->cn_flags & NOCROSSMOUNT) != 0)) {
ndp->ni_dvp = dp;
ndp->ni_vp = dp;
VREF(dp);
@ -1109,6 +1113,7 @@ vfs_lookup(struct nameidata *ndp)
LK_RETRY, ISDOTDOT));
error = nameicap_check_dotdot(ndp, dp);
if (error != 0) {
capdotdot:
#ifdef KTRACE
if (KTRPOINT(curthread, KTR_CAPFAIL))
ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL);