svn commit: r287209 - in head: share/man/man4 sys/compat/cloudabi sys/kern sys/sys usr.bin/procstat
Ed Schouten
ed at FreeBSD.org
Thu Aug 27 15:16:43 UTC 2015
Author: ed
Date: Thu Aug 27 15:16:41 2015
New Revision: 287209
URL: https://svnweb.freebsd.org/changeset/base/287209
Log:
Decompose linkat()/renameat() rights to source and target.
To make it easier to understand how Capsicum interacts with linkat() and
renameat(), rename the rights to CAP_{LINK,RENAME}AT_{SOURCE,TARGET}.
This also addresses a shortcoming in Capsicum, where it isn't possible
to disable linking to files stored in a directory. Creating hardlinks
essentially makes it possible to access files with additional rights.
Reviewed by: rwatson, wblock
Differential Revision: https://reviews.freebsd.org/D3411
Modified:
head/share/man/man4/rights.4
head/sys/compat/cloudabi/cloudabi_fd.c
head/sys/kern/vfs_syscalls.c
head/sys/sys/capsicum.h
head/usr.bin/procstat/procstat_files.c
Modified: head/share/man/man4/rights.4
==============================================================================
--- head/share/man/man4/rights.4 Thu Aug 27 15:03:34 2015 (r287208)
+++ head/share/man/man4/rights.4 Thu Aug 27 15:16:41 2015 (r287209)
@@ -32,7 +32,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 23, 2015
+.Dd August 27, 2015
.Dt RIGHTS 4
.Os
.Sh NAME
@@ -71,7 +71,7 @@ The
family of functions should be used to manage the structure.
.Sh RIGHTS
The following rights may be specified in a rights mask:
-.Bl -tag -width CAP_EXTATTR_DELETE
+.Bl -tag -width CAP_RENAMEAT_SOURCE
.It Dv CAP_ACCEPT
Permit
.Xr accept 2
@@ -328,12 +328,28 @@ argument is non-NULL).
.Dv CAP_EVENT
is also required on file descriptors that will be monitored using
.Xr kevent 2 .
-.It Dv CAP_LINKAT
+.It Dv CAP_LINKAT_SOURCE
Permit
.Xr linkat 2
-and
-.Xr renameat 2
-on the destination directory descriptor.
+on the source directory descriptor.
+This right includes the
+.Dv CAP_LOOKUP
+right.
+.Pp
+Warning:
+.Dv CAP_LINKAT_SOURCE
+makes it possible to link files in a directory for which file
+descriptors exist that have additional rights.
+For example,
+a file stored in a directory that does not allow
+.Dv CAP_READ
+may be linked in another directory that does allow
+.Dv CAP_READ ,
+thereby granting read access to a file that is otherwise unreadable.
+.It Dv CAP_LINKAT_TARGET
+Permit
+.Xr linkat 2
+on the target directory descriptor.
This right includes the
.Dv CAP_LOOKUP
right.
@@ -474,10 +490,28 @@ is also required) and related system cal
.It Dv CAP_RECV
An alias to
.Dv CAP_READ .
-.It Dv CAP_RENAMEAT
+.It Dv CAP_RENAMEAT_SOURCE
Permit
-.Xr renameat 2 .
-This right is required on the source directory descriptor.
+.Xr renameat 2
+on the source directory descriptor.
+This right includes the
+.Dv CAP_LOOKUP
+right.
+.Pp
+Warning:
+.Dv CAP_RENAMEAT_SOURCE
+makes it possible to move files to a directory for which file
+descriptors exist that have additional rights.
+For example,
+a file stored in a directory that does not allow
+.Dv CAP_READ
+may be moved to another directory that does allow
+.Dv CAP_READ ,
+thereby granting read access to a file that is otherwise unreadable.
+.It Dv CAP_RENAMEAT_TARGET
+Permit
+.Xr renameat 2
+on the target directory descriptor.
This right includes the
.Dv CAP_LOOKUP
right.
Modified: head/sys/compat/cloudabi/cloudabi_fd.c
==============================================================================
--- head/sys/compat/cloudabi/cloudabi_fd.c Thu Aug 27 15:03:34 2015 (r287208)
+++ head/sys/compat/cloudabi/cloudabi_fd.c Thu Aug 27 15:16:41 2015 (r287209)
@@ -56,13 +56,13 @@ __FBSDID("$FreeBSD$");
MAPPING(CLOUDABI_RIGHT_FILE_CREATE_DIRECTORY, CAP_MKDIRAT) \
MAPPING(CLOUDABI_RIGHT_FILE_CREATE_FILE, CAP_CREATE) \
MAPPING(CLOUDABI_RIGHT_FILE_CREATE_FIFO, CAP_MKFIFOAT) \
- MAPPING(CLOUDABI_RIGHT_FILE_LINK_SOURCE, CAP_LOOKUP) \
- MAPPING(CLOUDABI_RIGHT_FILE_LINK_TARGET, CAP_LINKAT) \
+ MAPPING(CLOUDABI_RIGHT_FILE_LINK_SOURCE, CAP_LINKAT_SOURCE) \
+ MAPPING(CLOUDABI_RIGHT_FILE_LINK_TARGET, CAP_LINKAT_TARGET) \
MAPPING(CLOUDABI_RIGHT_FILE_OPEN, CAP_LOOKUP) \
MAPPING(CLOUDABI_RIGHT_FILE_READDIR, CAP_READ) \
MAPPING(CLOUDABI_RIGHT_FILE_READLINK, CAP_LOOKUP) \
- MAPPING(CLOUDABI_RIGHT_FILE_RENAME_SOURCE, CAP_RENAMEAT) \
- MAPPING(CLOUDABI_RIGHT_FILE_RENAME_TARGET, CAP_LINKAT) \
+ MAPPING(CLOUDABI_RIGHT_FILE_RENAME_SOURCE, CAP_RENAMEAT_SOURCE) \
+ MAPPING(CLOUDABI_RIGHT_FILE_RENAME_TARGET, CAP_RENAMEAT_TARGET) \
MAPPING(CLOUDABI_RIGHT_FILE_STAT_FGET, CAP_FSTAT) \
MAPPING(CLOUDABI_RIGHT_FILE_STAT_FPUT_SIZE, CAP_FTRUNCATE) \
MAPPING(CLOUDABI_RIGHT_FILE_STAT_FPUT_TIMES, CAP_FUTIMES) \
Modified: head/sys/kern/vfs_syscalls.c
==============================================================================
--- head/sys/kern/vfs_syscalls.c Thu Aug 27 15:03:34 2015 (r287208)
+++ head/sys/kern/vfs_syscalls.c Thu Aug 27 15:16:41 2015 (r287209)
@@ -1441,7 +1441,8 @@ kern_linkat(struct thread *td, int fd1,
again:
bwillwrite();
- NDINIT_AT(&nd, LOOKUP, follow | AUDITVNODE1, segflg, path1, fd1, td);
+ NDINIT_ATRIGHTS(&nd, LOOKUP, follow | AUDITVNODE1, segflg, path1, fd1,
+ cap_rights_init(&rights, CAP_LINKAT_SOURCE), td);
if ((error = namei(&nd)) != 0)
return (error);
@@ -1451,9 +1452,9 @@ again:
vrele(vp);
return (EPERM); /* POSIX */
}
- NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE2 |
- NOCACHE, segflg, path2, fd2, cap_rights_init(&rights, CAP_LINKAT),
- td);
+ NDINIT_ATRIGHTS(&nd, CREATE,
+ LOCKPARENT | SAVENAME | AUDITVNODE2 | NOCACHE, segflg, path2, fd2,
+ cap_rights_init(&rights, CAP_LINKAT_TARGET), td);
if ((error = namei(&nd)) == 0) {
if (nd.ni_vp != NULL) {
NDFREE(&nd, NDF_ONLY_PNBUF);
@@ -3461,10 +3462,11 @@ again:
#ifdef MAC
NDINIT_ATRIGHTS(&fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVESTART |
AUDITVNODE1, pathseg, old, oldfd,
- cap_rights_init(&rights, CAP_RENAMEAT), td);
+ cap_rights_init(&rights, CAP_RENAMEAT_SOURCE), td);
#else
NDINIT_ATRIGHTS(&fromnd, DELETE, WANTPARENT | SAVESTART | AUDITVNODE1,
- pathseg, old, oldfd, cap_rights_init(&rights, CAP_RENAMEAT), td);
+ pathseg, old, oldfd,
+ cap_rights_init(&rights, CAP_RENAMEAT_SOURCE), td);
#endif
if ((error = namei(&fromnd)) != 0)
@@ -3479,7 +3481,7 @@ again:
fvp = fromnd.ni_vp;
NDINIT_ATRIGHTS(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE |
SAVESTART | AUDITVNODE2, pathseg, new, newfd,
- cap_rights_init(&rights, CAP_LINKAT), td);
+ cap_rights_init(&rights, CAP_RENAMEAT_TARGET), td);
if (fromnd.ni_vp->v_type == VDIR)
tond.ni_cnd.cn_flags |= WILLBEDIR;
if ((error = namei(&tond)) != 0) {
Modified: head/sys/sys/capsicum.h
==============================================================================
--- head/sys/sys/capsicum.h Thu Aug 27 15:03:34 2015 (r287208)
+++ head/sys/sys/capsicum.h Thu Aug 27 15:16:41 2015 (r287209)
@@ -150,16 +150,16 @@
#define CAP_FUTIMES CAPRIGHT(0, 0x0000000000200000ULL)
/* Allows for futimens(2), futimes(2), futimesat(2) and utimensat(2). */
#define CAP_FUTIMESAT (CAP_FUTIMES | CAP_LOOKUP)
-/* Allows for linkat(2) and renameat(2) (destination directory descriptor). */
-#define CAP_LINKAT (CAP_LOOKUP | 0x0000000000400000ULL)
+/* Allows for linkat(2) (target directory descriptor). */
+#define CAP_LINKAT_TARGET (CAP_LOOKUP | 0x0000000000400000ULL)
/* Allows for mkdirat(2). */
#define CAP_MKDIRAT (CAP_LOOKUP | 0x0000000000800000ULL)
/* Allows for mkfifoat(2). */
#define CAP_MKFIFOAT (CAP_LOOKUP | 0x0000000001000000ULL)
/* Allows for mknodat(2). */
#define CAP_MKNODAT (CAP_LOOKUP | 0x0000000002000000ULL)
-/* Allows for renameat(2). */
-#define CAP_RENAMEAT (CAP_LOOKUP | 0x0000000004000000ULL)
+/* Allows for renameat(2) (source directory descriptor). */
+#define CAP_RENAMEAT_SOURCE (CAP_LOOKUP | 0x0000000004000000ULL)
/* Allows for symlinkat(2). */
#define CAP_SYMLINKAT (CAP_LOOKUP | 0x0000000008000000ULL)
/*
@@ -197,6 +197,11 @@
/* Allows for connectat(2) on a directory descriptor. */
#define CAP_CONNECTAT (CAP_LOOKUP | 0x0000010000000000ULL)
+/* Allows for linkat(2) (source directory descriptor). */
+#define CAP_LINKAT_SOURCE (CAP_LOOKUP | 0x0000020000000000ULL)
+/* Allows for renameat(2) (target directory descriptor). */
+#define CAP_RENAMEAT_TARGET (CAP_LOOKUP | 0x0000040000000000ULL)
+
#define CAP_SOCK_CLIENT \
(CAP_CONNECT | CAP_GETPEERNAME | CAP_GETSOCKNAME | CAP_GETSOCKOPT | \
CAP_PEELOFF | CAP_RECV | CAP_SEND | CAP_SETSOCKOPT | CAP_SHUTDOWN)
@@ -206,10 +211,10 @@
CAP_SETSOCKOPT | CAP_SHUTDOWN)
/* All used bits for index 0. */
-#define CAP_ALL0 CAPRIGHT(0, 0x000001FFFFFFFFFFULL)
+#define CAP_ALL0 CAPRIGHT(0, 0x000007FFFFFFFFFFULL)
/* Available bits for index 0. */
-#define CAP_UNUSED0_42 CAPRIGHT(0, 0x0000020000000000ULL)
+#define CAP_UNUSED0_44 CAPRIGHT(0, 0x0000080000000000ULL)
/* ... */
#define CAP_UNUSED0_57 CAPRIGHT(0, 0x0100000000000000ULL)
Modified: head/usr.bin/procstat/procstat_files.c
==============================================================================
--- head/usr.bin/procstat/procstat_files.c Thu Aug 27 15:03:34 2015 (r287208)
+++ head/usr.bin/procstat/procstat_files.c Thu Aug 27 15:16:41 2015 (r287209)
@@ -158,11 +158,13 @@ static struct cap_desc {
{ CAP_FSTAT, "fs" },
{ CAP_FSTATFS, "sf" },
{ CAP_FUTIMES, "fu" },
- { CAP_LINKAT, "li" },
+ { CAP_LINKAT_SOURCE, "ls" },
+ { CAP_LINKAT_TARGET, "lt" },
{ CAP_MKDIRAT, "md" },
{ CAP_MKFIFOAT, "mf" },
{ CAP_MKNODAT, "mn" },
- { CAP_RENAMEAT, "rn" },
+ { CAP_RENAMEAT_SOURCE, "rs" },
+ { CAP_RENAMEAT_TARGET, "rt" },
{ CAP_SYMLINKAT, "sl" },
{ CAP_UNLINKAT, "un" },
More information about the svn-src-all
mailing list