From 22c1852a04b0fec9d91a74cb13de8f2827800029 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 16 Feb 2021 05:31:40 +0200 Subject: [PATCH] open(2): Remove O_BENEATH and AT_BENEATH Approved by: re (gjb) (cherry picked from commit 20e91ca36a56b8db1e6677f577ad011b66dd6eb3) --- lib/libc/sys/access.2 | 24 +++---------- lib/libc/sys/chflags.2 | 29 ++++----------- lib/libc/sys/chmod.2 | 29 ++++----------- lib/libc/sys/chown.2 | 29 ++++----------- lib/libc/sys/getfh.2 | 37 ++++--------------- lib/libc/sys/link.2 | 28 ++++----------- lib/libc/sys/open.2 | 77 +++++++-------------------------------- lib/libc/sys/stat.2 | 50 +++++--------------------- lib/libc/sys/unlink.2 | 29 ++++----------- lib/libc/sys/utimensat.2 | 29 ++++----------- sys/kern/vfs_lookup.c | 78 ++++++---------------------------------- sys/kern/vfs_syscalls.c | 51 +++++++++++--------------- sys/kern/vfs_vnops.c | 2 -- sys/sys/fcntl.h | 14 ++++---- sys/sys/namei.h | 5 --- 15 files changed, 112 insertions(+), 399 deletions(-) diff --git a/lib/libc/sys/access.2 b/lib/libc/sys/access.2 index 1cd7eed1301..13bfd7e5a88 100644 --- a/lib/libc/sys/access.2 +++ b/lib/libc/sys/access.2 @@ -28,7 +28,7 @@ .\" @(#)access.2 8.2 (Berkeley) 4/1/94 .\" $FreeBSD$ .\" -.Dd September 23, 2020 +.Dd February 23, 2021 .Dt ACCESS 2 .Os .Sh NAME @@ -120,15 +120,10 @@ list, defined in The checks for accessibility are performed using the effective user and group IDs instead of the real user and group ID as required in a call to .Fn access . -.It Dv AT_BENEATH -Only operate on files and directories below the topping directory. -See the description of the -.Dv O_BENEATH -flag in the -.Xr open 2 -manual page. .It Dv AT_RESOLVE_BENEATH -Only walks paths below the topping directory. +Only walk paths below the directory specified by the +.Ar fd +descriptor. See the description of the .Dv O_RESOLVE_BENEATH flag in the @@ -218,17 +213,6 @@ or contained a ".." component leading to a directory outside of the directory hierarchy specified by .Fa fd , and the process is in capability mode. -.It Bq Er ENOTCAPABLE -The -.Dv AT_BENEATH -flag was provided to -.Fn faccessat , -and the absolute -.Fa path -does not have its tail fully contained under the topping directory, -or the relative -.Fa path -escapes it. .El .Sh SEE ALSO .Xr chmod 2 , diff --git a/lib/libc/sys/chflags.2 b/lib/libc/sys/chflags.2 index b6b0b43249c..a4471390459 100644 --- a/lib/libc/sys/chflags.2 +++ b/lib/libc/sys/chflags.2 @@ -28,7 +28,7 @@ .\" @(#)chflags.2 8.3 (Berkeley) 5/2/95 .\" $FreeBSD$ .\" -.Dd September 23, 2020 +.Dd February 23, 2021 .Dt CHFLAGS 2 .Os .Sh NAME @@ -94,16 +94,10 @@ defined in If .Fa path names a symbolic link, then the flags of the symbolic link are changed. -.It Dv AT_BENEATH -Only allow to change flags for a file which is beneath of -the topping directory. -See the description of the -.Dv O_BENEATH -flag in the -.Xr open 2 -manual page. .It Dv AT_RESOLVE_BENEATH -Only walks paths below the topping directory. +Only walk paths below the directory specified by the +.Ar fd +descriptor. See the description of the .Dv O_RESOLVE_BENEATH flag in the @@ -327,18 +321,9 @@ is an absolute path, or contained a ".." component leading to a directory outside of the directory hierarchy specified by .Fa fd , -and the process is in capability mode. -.It Bq Er ENOTCAPABLE -The -.Dv AT_BENEATH -flag was provided to -.Fn chflagsat , -and the absolute -.Fa path -does not have its tail fully contained under the topping directory, -or the relative -.Fa path -escapes it. +and the process is in capability mode or the +.Dv AT_RESOLVE_BENEATH +flag was specified. .El .Sh SEE ALSO .Xr chflags 1 , diff --git a/lib/libc/sys/chmod.2 b/lib/libc/sys/chmod.2 index 1d66408e389..0127a5b629e 100644 --- a/lib/libc/sys/chmod.2 +++ b/lib/libc/sys/chmod.2 @@ -28,7 +28,7 @@ .\" @(#)chmod.2 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd September 23, 2020 +.Dd February 23, 2021 .Dt CHMOD 2 .Os .Sh NAME @@ -101,16 +101,10 @@ in If .Fa path names a symbolic link, then the mode of the symbolic link is changed. -.It Dv AT_BENEATH -Only allow to change permissions of a file which is beneath of -the topping directory. -See the description of the -.Dv O_BENEATH -flag in the -.Xr open 2 -manual page. .It Dv AT_RESOLVE_BENEATH -Only walks paths below the topping directory. +Only walk paths below the directory specified by the +.Ar fd +descriptor. See the description of the .Dv O_RESOLVE_BENEATH flag in the @@ -310,18 +304,9 @@ is an absolute path, or contained a ".." component leading to a directory outside of the directory hierarchy specified by .Fa fd , -and the process is in capability mode. -.It Bq Er ENOTCAPABLE -The -.Dv AT_BENEATH -flag was provided to -.Fn fchmodat , -and the absolute -.Fa path -does not have its tail fully contained under the topping directory, -or the relative -.Fa path -escapes it. +and the process is in capability mode or the +.Dv AT_RESOLVE_BENEATH +flag was specified. .El .Sh SEE ALSO .Xr chmod 1 , diff --git a/lib/libc/sys/chown.2 b/lib/libc/sys/chown.2 index 64bfdeaa961..4c45ce9174b 100644 --- a/lib/libc/sys/chown.2 +++ b/lib/libc/sys/chown.2 @@ -28,7 +28,7 @@ .\" @(#)chown.2 8.4 (Berkeley) 4/19/94 .\" $FreeBSD$ .\" -.Dd September 23, 2020 +.Dd February 23, 2021 .Dt CHOWN 2 .Os .Sh NAME @@ -118,16 +118,10 @@ list, defined in If .Fa path names a symbolic link, ownership of the symbolic link is changed. -.It Dv AT_BENEATH -Only allow to change ownership of a file which is beneath of -the topping directory. -See the description of the -.Dv O_BENEATH -flag in the -.Xr open 2 -manual page. .It Dv AT_RESOLVE_BENEATH -Only walks paths below the topping directory. +Only walk paths below the directory specified by the +.Ar fd +descriptor. See the description of the .Dv O_RESOLVE_BENEATH flag in the @@ -252,18 +246,9 @@ is an absolute path, or contained a ".." component leading to a directory outside of the directory hierarchy specified by .Fa fd , -and the process is in capability mode. -.It Bq Er ENOTCAPABLE -The -.Dv AT_BENEATH -flag was provided to -.Fn fchownat , -and the absolute -.Fa path -does not have its tail fully contained under the topping directory, -or the relative -.Fa path -escapes it. +and the process is in capability mode or the +.Dv AT_RESOLVE_BENEATH +flag was specified. .El .Sh SEE ALSO .Xr chgrp 1 , diff --git a/lib/libc/sys/getfh.2 b/lib/libc/sys/getfh.2 index 5dc5896af6d..cd3d54f54d7 100644 --- a/lib/libc/sys/getfh.2 +++ b/lib/libc/sys/getfh.2 @@ -29,7 +29,7 @@ .\" @(#)getfh.2 8.1 (Berkeley) 6/9/93 .\" $FreeBSD$ .\" -.Dd September 23, 2020 +.Dd February 23, 2021 .Dt GETFH 2 .Os .Sh NAME @@ -76,9 +76,7 @@ and .Fn lgetfh except when the .Fa path -specifies a relative path, or the -.Dv AT_BENEATH -flag is provided. +specifies a relative path. For .Fn getfhat and relative @@ -87,13 +85,6 @@ the status is retrieved from a file relative to the directory associated with the file descriptor .Fa fd instead of the current working directory. -For -.Dv AT_BENEATH -and absolute -.Fa path , -the status is retrieved from a file specified by the -.Fa path , -but additional permission checks are performed, see below. .Pp The values for the .Fa flag @@ -105,15 +96,10 @@ defined in If .Fa path names a symbolic link, the status of the symbolic link is returned. -.It Dv AT_BENEATH -Only stat files and directories below the topping directory. -See the description of the -.Dv O_BENEATH -flag in the -.Xr open 2 -manual page. .It Dv AT_RESOLVE_BENEATH -Only walks paths below the topping directory. +Only walk paths below the directory specified by the +.Ar fd +descriptor. See the description of the .Dv O_RESOLVE_BENEATH flag in the @@ -140,19 +126,10 @@ bit is set in When .Fn getfhat is called with an absolute -.Fa path -without the -.Dv AT_BENEATH -flag, it ignores the -.Fa fd -argument. -When -.Dv AT_BENEATH -is specified with an absolute .Fa path , -a directory passed by the +it ignores the .Fa fd -argument is used as the topping point for the resolution. +argument. These system calls are restricted to the superuser. .Sh RETURN VALUES .Rv -std diff --git a/lib/libc/sys/link.2 b/lib/libc/sys/link.2 index c3451da1088..de0efd5e510 100644 --- a/lib/libc/sys/link.2 +++ b/lib/libc/sys/link.2 @@ -28,7 +28,7 @@ .\" @(#)link.2 8.3 (Berkeley) 1/12/94 .\" $FreeBSD$ .\" -.Dd September 23, 2020 +.Dd February 23, 2021 .Dt LINK 2 .Os .Sh NAME @@ -115,15 +115,10 @@ If .Fa name1 names a symbolic link, a new link for the target of the symbolic link is created. -.It Dv AT_BENEATH -Only allow to link to a file which is beneath of the topping directory. -See the description of the -.Dv O_BENEATH -flag in the -.Xr open 2 -manual page. .It Dv AT_RESOLVE_BENEATH -Only walks paths below the topping directory. +Only walk paths below the directory specified by the +.Ar fd +descriptor. See the description of the .Dv O_RESOLVE_BENEATH flag in the @@ -281,18 +276,9 @@ For example, is absolute or includes a ".." component that escapes the directory hierarchy specified by .Fa fd , -and the process is in capability mode. -.It Bq Er ENOTCAPABLE -The -.Dv AT_BENEATH -flag was provided to -.Fa linkat -and the absolute path -.Fa name1 -does not have its tail fully contained under the topping directory, -or the relative path -.Fa name1 -escapes it. +and the process is in capability mode or the +.Dv AT_RESOLVE_BENEATH +flag was specified. .El .Sh SEE ALSO .Xr chflags 2 , diff --git a/lib/libc/sys/open.2 b/lib/libc/sys/open.2 index e43d012770d..e24c823d039 100644 --- a/lib/libc/sys/open.2 +++ b/lib/libc/sys/open.2 @@ -28,7 +28,7 @@ .\" @(#)open.2 8.2 (Berkeley) 11/16/93 .\" $FreeBSD$ .\" -.Dd September 23, 2020 +.Dd February 23, 2021 .Dt OPEN 2 .Os .Sh NAME @@ -75,9 +75,7 @@ function is equivalent to the .Fn open function except in the case where the .Fa path -specifies a relative path, or the -.Dv O_BENEATH -flag is provided. +specifies a relative path. For .Fn openat and relative @@ -104,28 +102,10 @@ and the behavior is identical to a call to When .Fn openat is called with an absolute -.Fa path -without the -.Dv O_BENEATH -flag, it ignores the -.Fa fd -argument. -When -.Dv O_BENEATH -is specified with an absolute .Fa path , -a directory passed by the -.Fa fd -argument is used as the topping point for the resolution. -When -.Dv O_BENEATH -is specified with a relative path, the +it ignores the .Fa fd -argument is used both as the starting point, and as the topping point -for the resolution. -See the definition of the -.Dv O_BENEATH -flag below. +argument. .Pp In .Xr capsicum 4 @@ -137,9 +117,7 @@ The argument to .Fn openat must be strictly relative to a file descriptor -.Fa fd , -as defined in -.Pa sys/kern/vfs_lookup.c . +.Fa fd . .Fa path must not be an absolute path and must not contain ".." components which cause the path resolution to escape the directory hierarchy @@ -156,9 +134,8 @@ If the .Dv vfs.lookup_cap_dotdot .Xr sysctl 3 MIB is set to zero, ".." components in the paths, -used in capability mode, or with the -.Dv O_BENEATH -flag, are completely disabled. +used in capability mode, +are completely disabled. If the .Dv vfs.lookup_cap_dotdot_nonlocal MIB is set to zero, ".." is not allowed if found on non-local filesystem. @@ -190,8 +167,7 @@ O_TTY_INIT ignored O_DIRECTORY error if file is not a directory O_CLOEXEC set FD_CLOEXEC upon open O_VERIFY verify the contents of the file -O_BENEATH require resolved path to be strictly relative to topping directory -O_RESOLVE_BENEATH require walked path to be strictly relative to topping directory +O_RESOLVE_BENEATH path resolution must not cross the fd directory .Ed .Pp Opening a file with @@ -319,32 +295,12 @@ means is implementation specific. The run-time linker (rtld) uses this flag to ensure shared objects have been verified before operating on them. .Pp -.Dv O_BENEATH -returns -.Er ENOTCAPABLE -if the specified path, after resolving all symlinks and ".." -references, does not end up with tail residing in the directory hierarchy of -children beneath the topping directory. -Topping directory is the process current directory if relative -.Fa path -is used for -.Fn open , -and the directory referenced by the -.Fa fd -argument when using -.Fn openat . -.Dv O_BENEATH -allows arbitrary prefix that ends up at the topping directory, -after which all further resolved components must be under it. -.Pp .Dv O_RESOLVE_BENEATH returns .Er ENOTCAPABLE if any intermediate component of the specified relative path does not -reside in the directory hierarchy beneath the topping directory. -Comparing to -.Dv O_BENEATH , -absolute paths or even the temporal escape from beneath of the topping +reside in the directory hierarchy beneath the starting directory. +Absolute paths or even the temporal escape from beneath of the starting directory is not allowed. .Pp When @@ -601,19 +557,12 @@ directory outside of the directory hierarchy specified by and the process is in capability mode. .It Bq Er ENOTCAPABLE The -.Dv O_BENEATH -flag was provided, and the absolute -.Fa path -does not have its tail fully contained under the topping directory, -or the relative -.Fa path -escapes it. -.It Bq Er ENOTCAPABLE -The .Dv O_RESOLVE_BENEATH flag was provided, and the relative .Fa path -escapes topping directory. +escapes the +.Ar fd +directory. .El .Sh SEE ALSO .Xr chmod 2 , diff --git a/lib/libc/sys/stat.2 b/lib/libc/sys/stat.2 index 4759d297e8d..0ed70620af6 100644 --- a/lib/libc/sys/stat.2 +++ b/lib/libc/sys/stat.2 @@ -28,7 +28,7 @@ .\" @(#)stat.2 8.4 (Berkeley) 5/1/95 .\" $FreeBSD$ .\" -.Dd September 23, 2020 +.Dd February 23, 2021 .Dt STAT 2 .Os .Sh NAME @@ -84,9 +84,7 @@ and .Fn lstat except when the .Fa path -specifies a relative path, or the -.Dv AT_BENEATH -flag is provided. +specifies a relative path. For .Fn fstatat and relative @@ -95,13 +93,6 @@ the status is retrieved from a file relative to the directory associated with the file descriptor .Fa fd instead of the current working directory. -For -.Dv AT_BENEATH -and absolute -.Fa path , -the status is retrieved from a file specified by the -.Fa path , -but additional permission checks are performed, see below. .Pp The values for the .Fa flag @@ -113,15 +104,8 @@ defined in If .Fa path names a symbolic link, the status of the symbolic link is returned. -.It Dv AT_BENEATH -Only stat files and directories below the topping directory. -See the description of the -.Dv O_BENEATH -flag in the -.Xr open 2 -manual page. .It Dv AT_RESOLVE_BENEATH -Only walks paths below the topping directory. +Only walk paths below the starting directory. See the description of the .Dv O_RESOLVE_BENEATH flag in the @@ -148,19 +132,10 @@ bit is set in When .Fn fstatat is called with an absolute -.Fa path -without the -.Dv AT_BENEATH -flag, it ignores the -.Fa fd -argument. -When -.Dv AT_BENEATH -is specified with an absolute .Fa path , -a directory passed by the +it ignores the .Fa fd -argument is used as the topping point for the resolution. +argument. .Pp The .Fa sb @@ -459,18 +434,9 @@ is an absolute path, or contained a ".." component leading to a directory outside of the directory hierarchy specified by .Fa fd , -and the process is in capability mode. -.It Bq Er ENOTCAPABLE -The -.Dv AT_BENEATH -flag was provided to -.Fn fstatat , -and the absolute -.Fa path -does not have its tail fully contained under the topping directory, -or the relative -.Fa path -escapes it. +and the process is in capability mode or the +.Dv AT_RESOLVE_BENEATH +flag was specified. .El .Sh SEE ALSO .Xr access 2 , diff --git a/lib/libc/sys/unlink.2 b/lib/libc/sys/unlink.2 index 838d4da68af..11fff875aba 100644 --- a/lib/libc/sys/unlink.2 +++ b/lib/libc/sys/unlink.2 @@ -28,7 +28,7 @@ .\" @(#)unlink.2 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd September 23, 2020 +.Dd February 23, 2021 .Dt UNLINK 2 .Os .Sh NAME @@ -92,16 +92,10 @@ Remove the directory entry specified by and .Fa path as a directory, not a normal file. -.It Dv AT_BENEATH -Only unlink files and directories which are beneath of the topping -directory. -See the description of the -.Dv O_BENEATH -flag in the -.Xr open 2 -manual page. .It Dv AT_RESOLVE_BENEATH -Only walks paths below the topping directory. +Only walk paths below the directory specified by the +.Ar fd +descriptor. See the description of the .Dv O_RESOLVE_BENEATH flag in the @@ -246,18 +240,9 @@ is an absolute path, or contained a ".." component leading to a directory outside of the directory hierarchy specified by .Fa fd , -and the process is in capability mode. -.It Bq Er ENOTCAPABLE -The -.Dv AT_BENEATH -flag was provided to -.Fn unlinkat , -and the absolute -.Fa path -does not have its tail fully contained under the topping directory, -or the relative -.Fa path -escapes it. +and the process is in capability mode or the +.Dv AT_RESOLVE_BENEATH +flag was specified. .El .Pp In addition to the errors returned by diff --git a/lib/libc/sys/utimensat.2 b/lib/libc/sys/utimensat.2 index 3016d1af72a..d31ee1f1515 100644 --- a/lib/libc/sys/utimensat.2 +++ b/lib/libc/sys/utimensat.2 @@ -31,7 +31,7 @@ .\" @(#)utimes.2 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd September 23, 2020 +.Dd February 23, 2021 .Dt UTIMENSAT 2 .Os .Sh NAME @@ -146,16 +146,10 @@ names a symbolic link, the symbolic link's times are changed. By default, .Fn utimensat changes the times of the file referenced by the symbolic link. -.It Dv AT_BENEATH -Only allow to change the times of a file which is beneath of -the topping directory. -See the description of the -.Dv O_BENEATH -flag in the -.Xr open 2 -manual page. .It Dv AT_RESOLVE_BENEATH -Only walks paths below the topping directory. +Only walk paths below the directory specified by the +.Ar fd +descriptor. See the description of the .Dv O_RESOLVE_BENEATH flag in the @@ -290,18 +284,9 @@ is an absolute path, or contained a ".." component leading to a directory outside of the directory hierarchy specified by .Fa fd , -and the process is in capability mode. -.It Bq Er ENOTCAPABLE -The -.Dv AT_BENEATH -flag was provided to -.Fn utimensat , -and the absolute -.Fa path -does not have its tail fully contained under the topping directory, -or the relative -.Fa path -escapes it. +and the process is in capability mode or the +.Dv AT_RESOLVE_BENEATH +flag was specified. .El .Sh SEE ALSO .Xr chflags 2 , diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index ad65ab11bb1..4ddd7b63ce5 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -182,13 +182,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 = malloc(sizeof(*nt), M_NAMEITRACKER, M_WAITOK); vhold(dp); nt->dp = dp; @@ -196,7 +189,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; @@ -207,10 +200,6 @@ nameicap_cleanup(struct nameidata *ndp, bool clean_latch) vdrop(nt->dp); free(nt, M_NAMEITRACKER); } - if (clean_latch && (ndp->ni_lcf & NI_LCF_LATCH) != 0) { - ndp->ni_lcf &= ~NI_LCF_LATCH; - vrele(ndp->ni_beneath_latch); - } } /* @@ -230,21 +219,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); } @@ -275,11 +260,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--; @@ -297,7 +277,6 @@ namei_setup(struct nameidata *ndp, struct vnode **dpp, struct pwd **pwdp) struct thread *td; struct pwd *pwd; cap_rights_t rights; - struct filecaps dirfd_caps; int error; bool startdir_used; @@ -410,26 +389,8 @@ namei_setup(struct nameidata *ndp, struct vnode **dpp, struct pwd **pwdp) if (error == 0 && (*dpp)->v_type != VDIR) error = ENOTDIR; } - if (error == 0 && (cnp->cn_flags & BENEATH) != 0) { - if (ndp->ni_dirfd == AT_FDCWD) { - ndp->ni_beneath_latch = pwd->pwd_cdir; - vrefact(ndp->ni_beneath_latch); - } else { - rights = *ndp->ni_rightsneeded; - cap_rights_set_one(&rights, CAP_LOOKUP); - error = fgetvp_rights(td, ndp->ni_dirfd, &rights, - &dirfd_caps, &ndp->ni_beneath_latch); - if (error == 0 && (*dpp)->v_type != VDIR) { - vrele(ndp->ni_beneath_latch); - error = ENOTDIR; - } - } - if (error == 0) - ndp->ni_lcf |= NI_LCF_LATCH; - } 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 | @@ -452,12 +413,8 @@ namei_setup(struct nameidata *ndp, struct vnode **dpp, struct pwd **pwdp) pwd_drop(pwd); return (error); } - 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_PROBE4(vfs, namei, lookup, entry, *dpp, cnp->cn_pnbuf, cnp->cn_flags, false); @@ -636,16 +593,8 @@ namei(struct nameidata *ndp) 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. @@ -657,12 +606,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); pwd_drop(pwd); if (error == 0) NDVALIDATE(ndp); @@ -739,7 +683,7 @@ namei(struct nameidata *ndp) MPASS(error != 0); SDT_PROBE4(vfs, namei, lookup, return, error, NULL, false, ndp); namei_cleanup_cnp(cnp); - nameicap_cleanup(ndp, true); + nameicap_cleanup(ndp); pwd_drop(pwd); return (error); } diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index a51d693446e..52604d3da82 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -120,8 +120,6 @@ at2cnpflags(u_int at_flags, u_int mask) res = 0; at_flags &= mask; - if ((at_flags & AT_BENEATH) != 0) - res |= BENEATH; if ((at_flags & AT_RESOLVE_BENEATH) != 0) res |= RBENEATH; if ((at_flags & AT_SYMLINK_FOLLOW) != 0) @@ -1500,12 +1498,11 @@ sys_linkat(struct thread *td, struct linkat_args *uap) int flag; flag = uap->flag; - if ((flag & ~(AT_SYMLINK_FOLLOW | AT_BENEATH | - AT_RESOLVE_BENEATH)) != 0) + if ((flag & ~(AT_SYMLINK_FOLLOW | AT_RESOLVE_BENEATH)) != 0) return (EINVAL); return (kern_linkat(td, uap->fd1, uap->fd2, uap->path1, uap->path2, - UIO_USERSPACE, at2cnpflags(flag, AT_SYMLINK_FOLLOW | AT_BENEATH | + UIO_USERSPACE, at2cnpflags(flag, AT_SYMLINK_FOLLOW | AT_RESOLVE_BENEATH))); } @@ -1875,7 +1872,7 @@ kern_funlinkat(struct thread *td, int dfd, const char *path, int fd, restart: bwillwrite(); NDINIT_ATRIGHTS(&nd, DELETE, LOCKPARENT | LOCKLEAF | AUDITVNODE1 | - at2cnpflags(flag, AT_BENEATH | AT_RESOLVE_BENEATH), + at2cnpflags(flag, AT_RESOLVE_BENEATH), pathseg, path, dfd, &cap_unlinkat_rights, td); if ((error = namei(&nd)) != 0) { if (error == EINVAL) @@ -2080,7 +2077,7 @@ kern_accessat(struct thread *td, int fd, const char *path, struct nameidata nd; int error; - if ((flag & ~(AT_EACCESS | AT_BENEATH | AT_RESOLVE_BENEATH)) != 0) + if ((flag & ~(AT_EACCESS | AT_RESOLVE_BENEATH)) != 0) return (EINVAL); if (amode != F_OK && (amode & ~(R_OK | W_OK | X_OK)) != 0) return (EINVAL); @@ -2101,7 +2098,7 @@ kern_accessat(struct thread *td, int fd, const char *path, usecred = cred; AUDIT_ARG_VALUE(amode); NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | - AUDITVNODE1 | at2cnpflags(flag, AT_BENEATH | AT_RESOLVE_BENEATH), + AUDITVNODE1 | at2cnpflags(flag, AT_RESOLVE_BENEATH), pathseg, path, fd, &cap_fstat_rights, td); if ((error = namei(&nd)) != 0) goto out; @@ -2392,13 +2389,12 @@ kern_statat(struct thread *td, int flag, int fd, const char *path, struct nameidata nd; int error; - if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH | - AT_RESOLVE_BENEATH)) != 0) + if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_RESOLVE_BENEATH)) != 0) return (EINVAL); - NDINIT_ATRIGHTS(&nd, LOOKUP, at2cnpflags(flag, AT_BENEATH | - AT_RESOLVE_BENEATH | AT_SYMLINK_NOFOLLOW) | LOCKSHARED | LOCKLEAF | - AUDITVNODE1, pathseg, path, fd, &cap_fstat_rights, td); + NDINIT_ATRIGHTS(&nd, LOOKUP, at2cnpflags(flag, AT_RESOLVE_BENEATH | + AT_SYMLINK_NOFOLLOW) | LOCKSHARED | LOCKLEAF | AUDITVNODE1, + pathseg, path, fd, &cap_fstat_rights, td); if ((error = namei(&nd)) != 0) return (error); @@ -2716,8 +2712,7 @@ int sys_chflagsat(struct thread *td, struct chflagsat_args *uap) { - if ((uap->atflag & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH | - AT_RESOLVE_BENEATH)) != 0) + if ((uap->atflag & ~(AT_SYMLINK_NOFOLLOW | AT_RESOLVE_BENEATH)) != 0) return (EINVAL); return (kern_chflagsat(td, uap->fd, uap->path, UIO_USERSPACE, @@ -2750,7 +2745,7 @@ kern_chflagsat(struct thread *td, int fd, const char *path, AUDIT_ARG_FFLAGS(flags); NDINIT_ATRIGHTS(&nd, LOOKUP, at2cnpflags(atflag, AT_SYMLINK_NOFOLLOW | - AT_BENEATH | AT_RESOLVE_BENEATH) | AUDITVNODE1, pathseg, path, fd, + AT_RESOLVE_BENEATH) | AUDITVNODE1, pathseg, path, fd, &cap_fchflags_rights, td); if ((error = namei(&nd)) != 0) return (error); @@ -2845,8 +2840,7 @@ int sys_fchmodat(struct thread *td, struct fchmodat_args *uap) { - if ((uap->flag & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH | - AT_RESOLVE_BENEATH)) != 0) + if ((uap->flag & ~(AT_SYMLINK_NOFOLLOW | AT_RESOLVE_BENEATH)) != 0) return (EINVAL); return (kern_fchmodat(td, uap->fd, uap->path, UIO_USERSPACE, @@ -2879,7 +2873,7 @@ kern_fchmodat(struct thread *td, int fd, const char *path, AUDIT_ARG_MODE(mode); NDINIT_ATRIGHTS(&nd, LOOKUP, at2cnpflags(flag, AT_SYMLINK_NOFOLLOW | - AT_BENEATH | AT_RESOLVE_BENEATH) | AUDITVNODE1, pathseg, path, fd, + AT_RESOLVE_BENEATH) | AUDITVNODE1, pathseg, path, fd, &cap_fchmod_rights, td); if ((error = namei(&nd)) != 0) return (error); @@ -2974,8 +2968,7 @@ int sys_fchownat(struct thread *td, struct fchownat_args *uap) { - if ((uap->flag & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH | - AT_RESOLVE_BENEATH)) != 0) + if ((uap->flag & ~(AT_SYMLINK_NOFOLLOW | AT_RESOLVE_BENEATH)) != 0) return (EINVAL); return (kern_fchownat(td, uap->fd, uap->path, UIO_USERSPACE, uap->uid, @@ -2991,7 +2984,7 @@ kern_fchownat(struct thread *td, int fd, const char *path, AUDIT_ARG_OWNER(uid, gid); NDINIT_ATRIGHTS(&nd, LOOKUP, at2cnpflags(flag, AT_SYMLINK_NOFOLLOW | - AT_BENEATH | AT_RESOLVE_BENEATH) | AUDITVNODE1, pathseg, path, fd, + AT_RESOLVE_BENEATH) | AUDITVNODE1, pathseg, path, fd, &cap_fchown_rights, td); if ((error = namei(&nd)) != 0) @@ -3343,14 +3336,13 @@ kern_utimensat(struct thread *td, int fd, const char *path, struct timespec ts[2]; int error, flags; - if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH | - AT_RESOLVE_BENEATH)) != 0) + if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_RESOLVE_BENEATH)) != 0) return (EINVAL); if ((error = getutimens(tptr, tptrseg, ts, &flags)) != 0) return (error); NDINIT_ATRIGHTS(&nd, LOOKUP, at2cnpflags(flag, AT_SYMLINK_NOFOLLOW | - AT_BENEATH | AT_RESOLVE_BENEATH) | AUDITVNODE1, + AT_RESOLVE_BENEATH) | AUDITVNODE1, pathseg, path, fd, &cap_futimes_rights, td); if ((error = namei(&nd)) != 0) return (error); @@ -3837,7 +3829,7 @@ kern_frmdirat(struct thread *td, int dfd, const char *path, int fd, restart: bwillwrite(); NDINIT_ATRIGHTS(&nd, DELETE, LOCKPARENT | LOCKLEAF | AUDITVNODE1 | - at2cnpflags(flag, AT_BENEATH | AT_RESOLVE_BENEATH), + at2cnpflags(flag, AT_RESOLVE_BENEATH), pathseg, path, dfd, &cap_unlinkat_rights, td); if ((error = namei(&nd)) != 0) goto fdout; @@ -4324,8 +4316,7 @@ int sys_getfhat(struct thread *td, struct getfhat_args *uap) { - if ((uap->flags & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH | - AT_RESOLVE_BENEATH)) != 0) + if ((uap->flags & ~(AT_SYMLINK_NOFOLLOW | AT_RESOLVE_BENEATH)) != 0) return (EINVAL); return (kern_getfhat(td, uap->flags, uap->fd, uap->path, UIO_USERSPACE, uap->fhp, UIO_USERSPACE)); @@ -4344,8 +4335,8 @@ kern_getfhat(struct thread *td, int flags, int fd, const char *path, if (error != 0) return (error); NDINIT_AT(&nd, LOOKUP, at2cnpflags(flags, AT_SYMLINK_NOFOLLOW | - AT_BENEATH | AT_RESOLVE_BENEATH) | LOCKLEAF | AUDITVNODE1, - pathseg, path, fd, td); + AT_RESOLVE_BENEATH) | LOCKLEAF | AUDITVNODE1, pathseg, path, + fd, td); error = namei(&nd); if (error != 0) return (error); diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 9ea79283325..561fdbf5da7 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -199,8 +199,6 @@ open2nameif(int fmode, u_int vn_open_flags) uint64_t res; res = ISOPEN | LOCKLEAF; - if ((fmode & O_BENEATH) != 0) - res |= BENEATH; if ((fmode & O_RESOLVE_BENEATH) != 0) res |= RBENEATH; if ((vn_open_flags & VN_OPEN_NOAUDIT) == 0) diff --git a/sys/sys/fcntl.h b/sys/sys/fcntl.h index 3c29c04e46d..c9740ac2325 100644 --- a/sys/sys/fcntl.h +++ b/sys/sys/fcntl.h @@ -135,10 +135,9 @@ typedef __pid_t pid_t; #if __BSD_VISIBLE #define O_VERIFY 0x00200000 /* open only after verification */ -#define O_BENEATH 0x00400000 /* Fail if not under cwd */ -#define O_RESOLVE_BENEATH 0x00800000 /* As O_BENEATH, but do not allow - resolve to walk out of cwd even to - return back */ +/* #define O_UNUSED1 0x00400000 */ /* Was O_BENEATH */ +#define O_RESOLVE_BENEATH 0x00800000 /* Do not allow name resolution to walk + out of cwd */ #endif #define O_DSYNC 0x01000000 /* POSIX data sync */ @@ -220,10 +219,9 @@ typedef __pid_t pid_t; #define AT_SYMLINK_NOFOLLOW 0x0200 /* Do not follow symbolic links */ #define AT_SYMLINK_FOLLOW 0x0400 /* Follow symbolic link */ #define AT_REMOVEDIR 0x0800 /* Remove directory instead of file */ -#define AT_BENEATH 0x1000 /* Fail if not under dirfd */ -#define AT_RESOLVE_BENEATH 0x2000 /* As AT_BENEATH, but do not allow - resolve to walk out of dirfd even - to return back */ +/* #define AT_UNUSED1 0x1000 *//* Was AT_BENEATH */ +#define AT_RESOLVE_BENEATH 0x2000 /* Do not allow name resolution + to walk out of dirfd */ #endif /* diff --git a/sys/sys/namei.h b/sys/sys/namei.h index 1f9bae9e275..b6985f1fa6f 100644 --- a/sys/sys/namei.h +++ b/sys/sys/namei.h @@ -111,7 +111,6 @@ struct nameidata { */ struct componentname ni_cnd; struct nameicap_tracker_head ni_cap_tracker; - struct vnode *ni_beneath_latch; }; #ifdef _KERNEL @@ -145,7 +144,6 @@ int cache_fplookup(struct nameidata *ndp, enum cache_fpl_status *status, #define WANTPARENT 0x0010 /* want parent vnode returned unlocked */ #define FAILIFEXISTS 0x0020 /* return EEXIST if found */ #define FOLLOW 0x0040 /* follow symbolic links */ -#define BENEATH 0x0080 /* No escape from the start dir */ #define LOCKSHARED 0x0100 /* Shared lock leaf */ #define NOFOLLOW 0x0000 /* do not follow symbolic links (pseudo) */ #define RBENEATH 0x100000000ULL /* No escape, even tmp, from start dir */ @@ -206,9 +204,6 @@ int cache_fplookup(struct nameidata *ndp, enum cache_fpl_status *status, */ #define NI_LCF_STRICTRELATIVE 0x0001 /* relative lookup only */ #define NI_LCF_CAP_DOTDOT 0x0002 /* ".." in strictrelative case */ -#define NI_LCF_BENEATH_ABS 0x0004 /* BENEATH with absolute path */ -#define NI_LCF_BENEATH_LATCHED 0x0008 /* BENEATH_ABS traversed starting dir */ -#define NI_LCF_LATCH 0x0010 /* ni_beneath_latch valid */ /* * Initialization of a nameidata structure. -- 2.45.0