git: a718431c30a5 - main - lookup(): ensure that openat("/", "..", O_RESOLVE_BENEATH) fails
Date: Mon, 24 Apr 2023 21:32:29 UTC
The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=a718431c30a57226bc7c1a9181fc84bab00641a1 commit a718431c30a57226bc7c1a9181fc84bab00641a1 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2023-04-23 23:21:42 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2023-04-24 21:32:10 +0000 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 --- sys/kern/vfs_lookup.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index d9a9cabde177..66a8b267f346 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -1083,12 +1083,16 @@ dirloop: 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 @@ dirloop: 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);