svn commit: r366937 - in stable/12: lib/libc/sys sys/cddl/compat/opensolaris/sys sys/compat/cloudabi sys/compat/linux sys/kern sys/sys sys/ufs/ffs
Konstantin Belousov
kib at FreeBSD.org
Thu Oct 22 15:23:45 UTC 2020
Author: kib
Date: Thu Oct 22 15:23:41 2020
New Revision: 366937
URL: https://svnweb.freebsd.org/changeset/base/366937
Log:
MFC r339748, r340343, r340347, r341256, r366015-r366023, r366549:
O_BENEATH and related features.
Sponsored by: The FreeBSD Foundation
Tested by: pho
Modified:
stable/12/lib/libc/sys/access.2
stable/12/lib/libc/sys/chflags.2
stable/12/lib/libc/sys/chmod.2
stable/12/lib/libc/sys/chown.2
stable/12/lib/libc/sys/fhlink.2
stable/12/lib/libc/sys/getfh.2
stable/12/lib/libc/sys/link.2
stable/12/lib/libc/sys/open.2
stable/12/lib/libc/sys/stat.2
stable/12/lib/libc/sys/unlink.2
stable/12/lib/libc/sys/utimensat.2
stable/12/sys/cddl/compat/opensolaris/sys/vnode.h
stable/12/sys/compat/cloudabi/cloudabi_file.c
stable/12/sys/compat/linux/linux_file.c
stable/12/sys/kern/vfs_lookup.c
stable/12/sys/kern/vfs_mountroot.c
stable/12/sys/kern/vfs_syscalls.c
stable/12/sys/kern/vfs_vnops.c
stable/12/sys/sys/fcntl.h
stable/12/sys/sys/namei.h
stable/12/sys/sys/syscallsubr.h
stable/12/sys/ufs/ffs/ffs_alloc.c
Directory Properties:
stable/12/ (props changed)
Modified: stable/12/lib/libc/sys/access.2
==============================================================================
--- stable/12/lib/libc/sys/access.2 Thu Oct 22 12:22:08 2020 (r366936)
+++ stable/12/lib/libc/sys/access.2 Thu Oct 22 15:23:41 2020 (r366937)
@@ -28,7 +28,7 @@
.\" @(#)access.2 8.2 (Berkeley) 4/1/94
.\" $FreeBSD$
.\"
-.Dd March 30, 2020
+.Dd September 23, 2020
.Dt ACCESS 2
.Os
.Sh NAME
@@ -120,6 +120,20 @@ 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.
+See the description of the
+.Dv O_RESOLVE_BENEATH
+flag in the
+.Xr open 2
+manual page.
.El
.Pp
Even if a process's real or effective user has appropriate privileges
@@ -197,6 +211,24 @@ argument is not an absolute path and
is neither
.Dv AT_FDCWD
nor a file descriptor associated with a directory.
+.It Bq Er ENOTCAPABLE
+.Fa path
+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 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 ,
Modified: stable/12/lib/libc/sys/chflags.2
==============================================================================
--- stable/12/lib/libc/sys/chflags.2 Thu Oct 22 12:22:08 2020 (r366936)
+++ stable/12/lib/libc/sys/chflags.2 Thu Oct 22 15:23:41 2020 (r366937)
@@ -28,7 +28,7 @@
.\" @(#)chflags.2 8.3 (Berkeley) 5/2/95
.\" $FreeBSD$
.\"
-.Dd March 30, 2020
+.Dd September 23, 2020
.Dt CHFLAGS 2
.Os
.Sh NAME
@@ -94,6 +94,21 @@ 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.
+See the description of the
+.Dv O_RESOLVE_BENEATH
+flag in the
+.Xr open 2
+manual page.
.El
.Pp
If
@@ -306,6 +321,24 @@ Corrupted data was detected while reading from the fil
The underlying file system does not support file flags, or
does not support all of the flags set in
.Fa flags .
+.It Bq Er ENOTCAPABLE
+.Fa path
+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.
.El
.Sh SEE ALSO
.Xr chflags 1 ,
Modified: stable/12/lib/libc/sys/chmod.2
==============================================================================
--- stable/12/lib/libc/sys/chmod.2 Thu Oct 22 12:22:08 2020 (r366936)
+++ stable/12/lib/libc/sys/chmod.2 Thu Oct 22 15:23:41 2020 (r366937)
@@ -28,7 +28,7 @@
.\" @(#)chmod.2 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd March 30, 2020
+.Dd September 23, 2020
.Dt CHMOD 2
.Os
.Sh NAME
@@ -101,6 +101,21 @@ 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.
+See the description of the
+.Dv O_RESOLVE_BENEATH
+flag in the
+.Xr open 2
+manual page.
.El
.Pp
If
@@ -289,6 +304,24 @@ argument is not an absolute path and
is neither
.Dv AT_FDCWD
nor a file descriptor associated with a directory.
+.It Bq Er ENOTCAPABLE
+.Fa path
+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.
.El
.Sh SEE ALSO
.Xr chmod 1 ,
Modified: stable/12/lib/libc/sys/chown.2
==============================================================================
--- stable/12/lib/libc/sys/chown.2 Thu Oct 22 12:22:08 2020 (r366936)
+++ stable/12/lib/libc/sys/chown.2 Thu Oct 22 15:23:41 2020 (r366937)
@@ -28,7 +28,7 @@
.\" @(#)chown.2 8.4 (Berkeley) 4/19/94
.\" $FreeBSD$
.\"
-.Dd March 30, 2020
+.Dd September 23, 2020
.Dt CHOWN 2
.Os
.Sh NAME
@@ -118,6 +118,21 @@ 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.
+See the description of the
+.Dv O_RESOLVE_BENEATH
+flag in the
+.Xr open 2
+manual page.
.El
.Pp
If
@@ -231,6 +246,24 @@ argument is not an absolute path and
is neither
.Dv AT_FDCWD
nor a file descriptor associated with a directory.
+.It Bq Er ENOTCAPABLE
+.Fa path
+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.
.El
.Sh SEE ALSO
.Xr chgrp 1 ,
Modified: stable/12/lib/libc/sys/fhlink.2
==============================================================================
--- stable/12/lib/libc/sys/fhlink.2 Thu Oct 22 12:22:08 2020 (r366936)
+++ stable/12/lib/libc/sys/fhlink.2 Thu Oct 22 15:23:41 2020 (r366937)
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd March 30, 2020
+.Dd September 23, 2020
.Dt FHLINK 2
.Os
.Sh NAME
@@ -110,6 +110,13 @@ created.
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.
Modified: stable/12/lib/libc/sys/getfh.2
==============================================================================
--- stable/12/lib/libc/sys/getfh.2 Thu Oct 22 12:22:08 2020 (r366936)
+++ stable/12/lib/libc/sys/getfh.2 Thu Oct 22 15:23:41 2020 (r366937)
@@ -29,7 +29,7 @@
.\" @(#)getfh.2 8.1 (Berkeley) 6/9/93
.\" $FreeBSD$
.\"
-.Dd March 30, 2020
+.Dd September 23, 2020
.Dt GETFH 2
.Os
.Sh NAME
@@ -109,6 +109,13 @@ names a symbolic link, the status of the symbolic link
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
+.Dv O_RESOLVE_BENEATH
flag in the
.Xr open 2
manual page.
Modified: stable/12/lib/libc/sys/link.2
==============================================================================
--- stable/12/lib/libc/sys/link.2 Thu Oct 22 12:22:08 2020 (r366936)
+++ stable/12/lib/libc/sys/link.2 Thu Oct 22 15:23:41 2020 (r366937)
@@ -28,7 +28,7 @@
.\" @(#)link.2 8.3 (Berkeley) 1/12/94
.\" $FreeBSD$
.\"
-.Dd March 30, 2020
+.Dd September 23, 2020
.Dt LINK 2
.Os
.Sh NAME
@@ -115,6 +115,20 @@ 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.
+See the description of the
+.Dv O_RESOLVE_BENEATH
+flag in the
+.Xr open 2
+manual page.
.El
.Pp
If
@@ -259,6 +273,26 @@ or
respectively, is neither
.Dv AT_FDCWD
nor a file descriptor associated with a directory.
+.It Bq Er ENOTCAPABLE
+.Fa name1
+is not strictly relative to the starting directory.
+For example,
+.Fa name1
+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.
.El
.Sh SEE ALSO
.Xr chflags 2 ,
Modified: stable/12/lib/libc/sys/open.2
==============================================================================
--- stable/12/lib/libc/sys/open.2 Thu Oct 22 12:22:08 2020 (r366936)
+++ stable/12/lib/libc/sys/open.2 Thu Oct 22 15:23:41 2020 (r366937)
@@ -28,7 +28,7 @@
.\" @(#)open.2 8.2 (Berkeley) 11/16/93
.\" $FreeBSD$
.\"
-.Dd March 30, 2020
+.Dd September 23, 2020
.Dt OPEN 2
.Os
.Sh NAME
@@ -75,8 +75,14 @@ function is equivalent to the
.Fn open
function except in the case where the
.Fa path
-specifies a relative path.
-In this case the file to be opened is determined relative to the directory
+specifies a relative path, or the
+.Dv O_BENEATH
+flag is provided.
+For
+.Fn openat
+and relative
+.Fa path ,
+the file to be opened is determined relative to the directory
associated with the file descriptor
.Fa fd
instead of the current working directory.
@@ -95,6 +101,32 @@ parameter, the current working directory is used
and the behavior is identical to a call to
.Fn open .
.Pp
+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
+.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.
+.Pp
In
.Xr capsicum 4
capability mode,
@@ -109,14 +141,28 @@ must be strictly relative to a file descriptor
as defined in
.Pa sys/kern/vfs_lookup.c .
.Fa path
-must not be an absolute path and must not contain ".." components.
+must not be an absolute path and must not contain ".." components
+which cause the path resolution to escape the directory hierarchy
+starting at
+.Fa fd .
Additionally, no symbolic link in
.Fa path
-may contain ".." components either.
+may target absolute path or contain escaping ".." components.
.Fa fd
must not be
.Dv AT_FDCWD .
.Pp
+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.
+If the
+.Dv vfs.lookup_cap_dotdot_nonlocal
+MIB is set to zero, ".." is not allowed if found on non-local filesystem.
+.Pp
The flags specified are formed by
.Em or Ns 'ing
the following values
@@ -143,6 +189,8 @@ 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
.Ed
.Pp
Opening a file with
@@ -266,7 +314,34 @@ The details of what
means is implementation specific.
The run-time linker (rtld) uses this flag to ensure shared objects have
been verified before operating on them.
+.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
+directory is not allowed.
+.Pp
When
.Fa fd
is opened with
@@ -280,6 +355,7 @@ The primary use for this descriptor will be as the loo
.Fn *at
family of functions.
.Pp
+.Pp
If successful,
.Fn open
returns a non-negative integer, termed a file descriptor.
@@ -480,6 +556,12 @@ and
.Dv O_EXEC
or
.Dv O_SEARCH .
+.It Bq Er EINVAL
+The
+.Dv O_RESOLVE_BENEATH
+flag is specified and
+.Dv path
+is absolute.
.It Bq Er EBADF
The
.Fa path
@@ -508,9 +590,26 @@ is specified and the process is in capability mode.
was called and the process is in capability mode.
.It Bq Er ENOTCAPABLE
.Fa path
-is an absolute path or contained a ".." component leading to a
+is an absolute path,
+or contained a ".." component leading to a
directory outside of the directory hierarchy specified by
-.Fa fd .
+.Fa fd ,
+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.
.El
.Sh SEE ALSO
.Xr chmod 2 ,
Modified: stable/12/lib/libc/sys/stat.2
==============================================================================
--- stable/12/lib/libc/sys/stat.2 Thu Oct 22 12:22:08 2020 (r366936)
+++ stable/12/lib/libc/sys/stat.2 Thu Oct 22 15:23:41 2020 (r366937)
@@ -28,7 +28,7 @@
.\" @(#)stat.2 8.4 (Berkeley) 5/1/95
.\" $FreeBSD$
.\"
-.Dd March 30, 2020
+.Dd September 23, 2020
.Dt STAT 2
.Os
.Sh NAME
@@ -84,11 +84,24 @@ and
.Fn lstat
except when the
.Fa path
-specifies a relative path.
-In this case the status is retrieved from a file relative to
+specifies a relative path, or the
+.Dv AT_BENEATH
+flag is provided.
+For
+.Fn fstatat
+and relative
+.Fa path ,
+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
@@ -100,6 +113,20 @@ 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.
+See the description of the
+.Dv O_RESOLVE_BENEATH
+flag in the
+.Xr open 2
+manual page.
.El
.Pp
If
@@ -118,6 +145,23 @@ respectively, depending on whether or not the
bit is set in
.Fa flag .
.Pp
+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
+.Fa fd
+argument is used as the topping point for the resolution.
+.Pp
The
.Fa sb
argument is a pointer to a
@@ -409,6 +453,24 @@ argument is not an absolute path and
is neither
.Dv AT_FDCWD
nor a file descriptor associated with a directory.
+.It Bq Er ENOTCAPABLE
+.Fa path
+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.
.El
.Sh SEE ALSO
.Xr access 2 ,
Modified: stable/12/lib/libc/sys/unlink.2
==============================================================================
--- stable/12/lib/libc/sys/unlink.2 Thu Oct 22 12:22:08 2020 (r366936)
+++ stable/12/lib/libc/sys/unlink.2 Thu Oct 22 15:23:41 2020 (r366937)
@@ -28,7 +28,7 @@
.\" @(#)unlink.2 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd March 30, 2020
+.Dd September 23, 2020
.Dt UNLINK 2
.Os
.Sh NAME
@@ -89,6 +89,21 @@ 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.
+See the description of the
+.Dv O_RESOLVE_BENEATH
+flag in the
+.Xr open 2
+manual page.
.El
.Pp
If
@@ -202,6 +217,24 @@ argument is not an absolute path and
is neither
.Dv AT_FDCWD
nor a file descriptor associated with a directory.
+.It Bq Er ENOTCAPABLE
+.Fa path
+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.
.El
.Sh SEE ALSO
.Xr chflags 2 ,
Modified: stable/12/lib/libc/sys/utimensat.2
==============================================================================
--- stable/12/lib/libc/sys/utimensat.2 Thu Oct 22 12:22:08 2020 (r366936)
+++ stable/12/lib/libc/sys/utimensat.2 Thu Oct 22 15:23:41 2020 (r366937)
@@ -31,7 +31,7 @@
.\" @(#)utimes.2 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd March 30, 2020
+.Dd September 23, 2020
.Dt UTIMENSAT 2
.Os
.Sh NAME
@@ -146,6 +146,21 @@ names a symbolic link, the symbolic link's times are c
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.
+See the description of the
+.Dv O_RESOLVE_BENEATH
+flag in the
+.Xr open 2
+manual page.
.El
.Sh RETURN VALUES
.Rv -std
@@ -269,6 +284,24 @@ argument is not an absolute path and
is neither
.Dv AT_FDCWD
nor a file descriptor associated with a directory.
+.It Bq Er ENOTCAPABLE
+.Fa path
+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.
.El
.Sh SEE ALSO
.Xr chflags 2 ,
Modified: stable/12/sys/cddl/compat/opensolaris/sys/vnode.h
==============================================================================
--- stable/12/sys/cddl/compat/opensolaris/sys/vnode.h Thu Oct 22 12:22:08 2020 (r366936)
+++ stable/12/sys/cddl/compat/opensolaris/sys/vnode.h Thu Oct 22 15:23:41 2020 (r366937)
@@ -278,7 +278,7 @@ vn_remove(char *fnamep, enum uio_seg seg, enum rm dirf
ASSERT(seg == UIO_SYSSPACE);
ASSERT(dirflag == RMFILE);
- return (kern_unlinkat(curthread, AT_FDCWD, fnamep, seg, 0));
+ return (kern_unlinkat(curthread, AT_FDCWD, fnamep, seg, 0, 0));
}
#endif /* _KERNEL */
Modified: stable/12/sys/compat/cloudabi/cloudabi_file.c
==============================================================================
--- stable/12/sys/compat/cloudabi/cloudabi_file.c Thu Oct 22 12:22:08 2020 (r366936)
+++ stable/12/sys/compat/cloudabi/cloudabi_file.c Thu Oct 22 15:23:41 2020 (r366937)
@@ -752,9 +752,9 @@ cloudabi_sys_file_unlink(struct thread *td,
return (error);
if (uap->flags & CLOUDABI_UNLINK_REMOVEDIR)
- error = kern_rmdirat(td, uap->fd, path, UIO_SYSSPACE);
+ error = kern_rmdirat(td, uap->fd, path, UIO_SYSSPACE, 0);
else
- error = kern_unlinkat(td, uap->fd, path, UIO_SYSSPACE, 0);
+ error = kern_unlinkat(td, uap->fd, path, UIO_SYSSPACE, 0, 0);
cloudabi_freestr(path);
return (error);
}
Modified: stable/12/sys/compat/linux/linux_file.c
==============================================================================
--- stable/12/sys/compat/linux/linux_file.c Thu Oct 22 12:22:08 2020 (r366936)
+++ stable/12/sys/compat/linux/linux_file.c Thu Oct 22 15:23:41 2020 (r366937)
@@ -540,7 +540,7 @@ linux_unlink(struct thread *td, struct linux_unlink_ar
LCONVPATHEXIST(td, args->path, &path);
- error = kern_unlinkat(td, AT_FDCWD, path, UIO_SYSSPACE, 0);
+ error = kern_unlinkat(td, AT_FDCWD, path, UIO_SYSSPACE, 0, 0);
if (error == EPERM) {
/* Introduce POSIX noncompliant behaviour of Linux */
if (kern_statat(td, 0, AT_FDCWD, path, UIO_SYSSPACE, &st,
@@ -568,9 +568,9 @@ linux_unlinkat(struct thread *td, struct linux_unlinka
LCONVPATHEXIST_AT(td, args->pathname, &path, dfd);
if (args->flag & LINUX_AT_REMOVEDIR)
- error = kern_rmdirat(td, dfd, path, UIO_SYSSPACE);
+ error = kern_rmdirat(td, dfd, path, UIO_SYSSPACE, 0);
else
- error = kern_unlinkat(td, dfd, path, UIO_SYSSPACE, 0);
+ error = kern_unlinkat(td, dfd, path, UIO_SYSSPACE, 0, 0);
if (error == EPERM && !(args->flag & LINUX_AT_REMOVEDIR)) {
/* Introduce POSIX noncompliant behaviour of Linux */
if (kern_statat(td, AT_SYMLINK_NOFOLLOW, dfd, path,
@@ -661,7 +661,7 @@ linux_rmdir(struct thread *td, struct linux_rmdir_args
LCONVPATHEXIST(td, args->path, &path);
- error = kern_rmdirat(td, AT_FDCWD, path, UIO_SYSSPACE);
+ error = kern_rmdirat(td, AT_FDCWD, path, UIO_SYSSPACE, 0);
LFREEPATH(path);
return (error);
}
Modified: stable/12/sys/kern/vfs_lookup.c
==============================================================================
--- stable/12/sys/kern/vfs_lookup.c Thu Oct 22 12:22:08 2020 (r366936)
+++ stable/12/sys/kern/vfs_lookup.c Thu Oct 22 15:23:41 2020 (r366937)
@@ -174,9 +174,18 @@ static void
nameicap_tracker_add(struct nameidata *ndp, struct vnode *dp)
{
struct nameicap_tracker *nt;
+ struct componentname *cnp;
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;
@@ -184,7 +193,7 @@ nameicap_tracker_add(struct nameidata *ndp, struct vno
}
static void
-nameicap_cleanup(struct nameidata *ndp)
+nameicap_cleanup(struct nameidata *ndp, bool clean_latch)
{
struct nameicap_tracker *nt, *nt1;
@@ -195,12 +204,20 @@ nameicap_cleanup(struct nameidata *ndp)
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);
+ }
}
/*
* For dotdot lookups in capability mode, only allow the component
* lookup to succeed if the resulting directory was already traversed
- * during the operation. Also fail dotdot lookups for non-local
+ * during the operation. This catches situations where already
+ * traversed directory is moved to different parent, and then we walk
+ * over it with dotdots.
+ *
+ * Also allow to force failure of dotdot lookups for non-local
* filesystems, where external agents might assist local lookups to
* escape the compartment.
*/
@@ -219,6 +236,12 @@ nameicap_check_dotdot(struct nameidata *ndp, struct vn
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);
}
@@ -249,6 +272,11 @@ namei_handle_root(struct nameidata *ndp, struct vnode
#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--;
@@ -290,6 +318,7 @@ 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;
@@ -347,6 +376,7 @@ namei(struct nameidata *ndp)
if (error == 0 && IN_CAPABILITY_MODE(td) &&
(cnp->cn_flags & NOCAPCHECK) == 0) {
ndp->ni_lcf |= NI_LCF_STRICTRELATIVE;
+ ndp->ni_resflags |= NIRES_STRICTREL;
if (ndp->ni_dirfd == AT_FDCWD) {
#ifdef KTRACE
if (KTRPOINT(td, KTR_CAPFAIL))
@@ -441,13 +471,42 @@ namei(struct nameidata *ndp)
ndp->ni_filecaps.fc_fcntls != CAP_FCNTL_ALL ||
ndp->ni_filecaps.fc_nioctls != -1) {
ndp->ni_lcf |= NI_LCF_STRICTRELATIVE;
+ ndp->ni_resflags |= NIRES_STRICTREL;
}
#endif
}
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) {
+ error = EINVAL;
+ } else if ((ndp->ni_lcf & NI_LCF_STRICTRELATIVE) == 0) {
+ ndp->ni_lcf |= NI_LCF_STRICTRELATIVE |
+ NI_LCF_CAP_DOTDOT;
+ }
+ }
+
if (ndp->ni_startdir != NULL && !startdir_used)
vrele(ndp->ni_startdir);
if (error != 0) {
@@ -455,16 +514,29 @@ namei(struct nameidata *ndp)
vrele(dp);
goto out;
}
- if ((ndp->ni_lcf & NI_LCF_STRICTRELATIVE) != 0 &&
- lookup_cap_dotdot != 0)
+ 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))
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)
+ 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;
goto out;
+ }
+
/*
* If not a symbolic link, we're done.
*/
@@ -474,9 +546,15 @@ namei(struct nameidata *ndp)
namei_cleanup_cnp(cnp);
} else
cnp->cn_flags |= HASBUF;
- nameicap_cleanup(ndp);
- SDT_PROBE2(vfs, namei, lookup, return, 0, ndp->ni_vp);
- return (0);
+ if ((ndp->ni_lcf & (NI_LCF_LATCH |
+ NI_LCF_BENEATH_LATCHED)) == NI_LCF_LATCH) {
+ NDFREE(ndp, 0);
+ error = ENOTCAPABLE;
+ }
+ nameicap_cleanup(ndp, true);
+ SDT_PROBE2(vfs, namei, lookup, return, error,
+ (error == 0 ? ndp->ni_vp : NULL));
+ return (error);
}
if (ndp->ni_loopcnt++ >= MAXSYMLINKS) {
error = ELOOP;
@@ -547,8 +625,9 @@ namei(struct nameidata *ndp)
vrele(ndp->ni_dvp);
out:
vrele(ndp->ni_rootdir);
+ MPASS(error != 0);
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-stable-12
mailing list