Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F131561372
D28907.id84821.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
31 KB
Referenced Files
None
Subscribers
None
D28907.id84821.diff
View Options
diff --git a/lib/libc/sys/access.2 b/lib/libc/sys/access.2
--- 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 @@
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 walks 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 @@
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
--- 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 @@
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 walks 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 @@
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
--- 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 @@
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 walks paths below directory specified by the
+.Ar fd
+descriptor.
See the description of the
.Dv O_RESOLVE_BENEATH
flag in the
@@ -310,18 +304,9 @@
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
--- 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 @@
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 walks 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 @@
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/fhlink.2 b/lib/libc/sys/fhlink.2
--- a/lib/libc/sys/fhlink.2
+++ b/lib/libc/sys/fhlink.2
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 23, 2020
+.Dd February 23, 2021
.Dt FHLINK 2
.Os
.Sh NAME
@@ -95,33 +95,6 @@
.Fa tofd
instead of the current working directory.
.Pp
-Values for
-.Fa flag
-are constructed by a bitwise-inclusive OR of flags from the following
-list, defined in
-.In fcntl.h :
-.Bl -tag -width indent
-.It Dv AT_SYMLINK_FOLLOW
-If
-.Fa fhp
-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.
-See the description of the
-.Dv O_RESOLVE_BENEATH
-flag in the
-.Xr open 2
-manual page.
-.El
-.Pp
If
.Fn fhlinkat
is passed the special value
diff --git a/lib/libc/sys/getfh.2 b/lib/libc/sys/getfh.2
--- 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 @@
.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 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,13 +96,6 @@
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.
See the description of the
@@ -140,19 +124,10 @@
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
--- 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 @@
.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 walks 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 @@
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
--- 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 @@
.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 @@
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 @@
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 @@
.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_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 @@
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 @@
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
--- 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 @@
.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 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 @@
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 walks paths below the starting directory.
See the description of the
.Dv O_RESOLVE_BENEATH
flag in the
@@ -148,19 +132,10 @@
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 @@
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
--- 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 @@
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 walks 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 @@
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
--- 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 @@
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 walks 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 @@
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
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -182,13 +182,9 @@
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 = TAILQ_LAST(&ndp->ni_cap_tracker, nameicap_tracker_head);
+ if (nt != NULL && nt->dp == dp)
+ return;
nt = malloc(sizeof(*nt), M_NAMEITRACKER, M_WAITOK);
vhold(dp);
nt->dp = dp;
@@ -196,21 +192,24 @@
}
static void
-nameicap_cleanup(struct nameidata *ndp, bool clean_latch)
+nameicap_cleanup_from(struct nameidata *ndp, struct nameicap_tracker *first)
{
struct nameicap_tracker *nt, *nt1;
- KASSERT(TAILQ_EMPTY(&ndp->ni_cap_tracker) ||
- (ndp->ni_lcf & NI_LCF_CAP_DOTDOT) != 0, ("not strictrelative"));
- TAILQ_FOREACH_SAFE(nt, &ndp->ni_cap_tracker, nm_link, nt1) {
+ nt = first;
+ TAILQ_FOREACH_FROM_SAFE(nt, &ndp->ni_cap_tracker, nm_link, nt1) {
TAILQ_REMOVE(&ndp->ni_cap_tracker, nt, nm_link);
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);
- }
+}
+
+static void
+nameicap_cleanup(struct nameidata *ndp)
+{
+ KASSERT(TAILQ_EMPTY(&ndp->ni_cap_tracker) ||
+ (ndp->ni_lcf & NI_LCF_CAP_DOTDOT) != 0, ("not strictrelative"));
+ nameicap_cleanup_from(ndp, NULL);
}
/*
@@ -230,23 +229,23 @@
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);
+ if (dp == nt->dp) {
+ nt = TAILQ_NEXT(nt, nm_link);
+ if (nt != NULL)
+ nameicap_cleanup_from(ndp, nt);
return (0);
}
- if (dp == nt->dp)
- return (0);
}
return (ENOTCAPABLE);
}
@@ -275,11 +274,6 @@
#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 +291,6 @@
struct thread *td;
struct pwd *pwd;
cap_rights_t rights;
- struct filecaps dirfd_caps;
int error;
bool startdir_used;
@@ -410,26 +403,8 @@
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 +427,8 @@
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 +607,8 @@
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 +620,7 @@
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 +697,7 @@
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);
}
@@ -1314,7 +1272,8 @@
}
}
if (ndp->ni_vp != NULL) {
- nameicap_tracker_add(ndp, ndp->ni_vp);
+ if ((cnp->cn_flags & ISDOTDOT) == 0)
+ nameicap_tracker_add(ndp, ndp->ni_vp);
if ((cnp->cn_flags & (FAILIFEXISTS | ISSYMLINK)) == FAILIFEXISTS)
goto bad_eexist;
}
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -120,8 +120,6 @@
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)
@@ -1498,12 +1496,11 @@
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)));
}
@@ -1873,7 +1870,7 @@
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)
@@ -2078,7 +2075,7 @@
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);
@@ -2099,7 +2096,7 @@
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;
@@ -2390,13 +2387,12 @@
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);
@@ -2714,8 +2710,7 @@
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,
@@ -2748,7 +2743,7 @@
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);
@@ -2843,8 +2838,7 @@
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,
@@ -2877,7 +2871,7 @@
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);
@@ -2972,8 +2966,7 @@
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,
@@ -2989,7 +2982,7 @@
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)
@@ -3341,14 +3334,13 @@
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);
@@ -3835,7 +3827,7 @@
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;
@@ -4322,8 +4314,7 @@
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));
@@ -4342,8 +4333,8 @@
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
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -199,8 +199,6 @@
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
--- a/sys/sys/fcntl.h
+++ b/sys/sys/fcntl.h
@@ -135,10 +135,9 @@
#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 @@
#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
--- a/sys/sys/namei.h
+++ b/sys/sys/namei.h
@@ -111,7 +111,6 @@
*/
struct componentname ni_cnd;
struct nameicap_tracker_head ni_cap_tracker;
- struct vnode *ni_beneath_latch;
};
#ifdef _KERNEL
@@ -145,7 +144,6 @@
#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 @@
*/
#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.
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Oct 10, 6:52 AM (21 h, 33 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23522808
Default Alt Text
D28907.id84821.diff (31 KB)
Attached To
Mode
D28907: open(2): Remove O_BENEATH and AT_BENEATH
Attached
Detach File
Event Timeline
Log In to Comment