summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorallanjude <allanjude@FreeBSD.org>2017-06-11 02:04:39 +0000
committerallanjude <allanjude@FreeBSD.org>2017-06-11 02:04:39 +0000
commitadd5f3e1312c298d03bbd73a3ff11a1cb7d381f4 (patch)
tree2910e97c23abe263755e806b8c4c93f796481173
parenta792c4a78cc396cbe2e4eb2d13bb2d7a541a9185 (diff)
downloadFreeBSD-src-add5f3e1312c298d03bbd73a3ff11a1cb7d381f4.zip
FreeBSD-src-add5f3e1312c298d03bbd73a3ff11a1cb7d381f4.tar.gz
MFC r318765:
Allow cpuset_{get,set}affinity in capabilities mode Approved by: re (marius)
-rw-r--r--lib/libc/sys/cpuset_getaffinity.28
-rw-r--r--share/man/man4/capsicum.412
-rw-r--r--sys/compat/freebsd32/capabilities.conf4
-rw-r--r--sys/compat/freebsd32/freebsd32_sysent.c4
-rw-r--r--sys/kern/capabilities.conf7
-rw-r--r--sys/kern/init_sysent.c4
-rw-r--r--sys/kern/kern_cpuset.c20
7 files changed, 47 insertions, 12 deletions
diff --git a/lib/libc/sys/cpuset_getaffinity.2 b/lib/libc/sys/cpuset_getaffinity.2
index c379518..dbf27ad 100644
--- a/lib/libc/sys/cpuset_getaffinity.2
+++ b/lib/libc/sys/cpuset_getaffinity.2
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 2, 2016
+.Dd May 23, 2017
.Dt CPUSET_GETAFFINITY 2
.Os
.Sh NAME
@@ -148,8 +148,14 @@ was either preposterously large or smaller than the kernel set size.
.It Bq Er EPERM
The calling process did not have the credentials required to complete the
operation.
+.It Bq Er ECAPMODE
+The calling process attempted to act on a process other than itself, while
+in capability mode.
+See
+.Xr capsicum 4 .
.El
.Sh SEE ALSO
+.Xr capsicum 4 ,
.Xr cpuset 1 ,
.Xr cpuset 2 ,
.Xr cpuset_getid 2 ,
diff --git a/share/man/man4/capsicum.4 b/share/man/man4/capsicum.4
index 74cf281..0dbd306 100644
--- a/share/man/man4/capsicum.4
+++ b/share/man/man4/capsicum.4
@@ -26,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 5, 2016
+.Dd May 18, 2017
.Dt CAPSICUM 4
.Os
.Sh NAME
@@ -88,6 +88,16 @@ An extension to the POSIX shared memory API to support anonymous swap objects
associated with file descriptors; described in greater detail in
.Xr shm_open 2 .
.El
+.Pp
+In some cases,
+.Nm
+limits the valid values of some parameters to traditional APIs in order to
+restrict access to global namespaces:
+.Bl -tag -width indent
+.It process IDs
+Processes can only act upon their own process ID with syscalls such as
+.Xr cpuset_setaffinity 2 .
+.El
.Sh SEE ALSO
.Xr cap_enter 2 ,
.Xr cap_fcntls_limit 2 ,
diff --git a/sys/compat/freebsd32/capabilities.conf b/sys/compat/freebsd32/capabilities.conf
index e14ff2d..3acb6ad 100644
--- a/sys/compat/freebsd32/capabilities.conf
+++ b/sys/compat/freebsd32/capabilities.conf
@@ -76,9 +76,9 @@ close
closefrom
connectat
#cpuset
-#freebsd32_cpuset_getaffinity
+freebsd32_cpuset_getaffinity
#freebsd32_cpuset_getid
-#freebsd32_cpuset_setaffinity
+freebsd32_cpuset_setaffinity
#freebsd32_cpuset_setid
dup
dup2
diff --git a/sys/compat/freebsd32/freebsd32_sysent.c b/sys/compat/freebsd32/freebsd32_sysent.c
index f8cbdf5..d11c233 100644
--- a/sys/compat/freebsd32/freebsd32_sysent.c
+++ b/sys/compat/freebsd32/freebsd32_sysent.c
@@ -552,8 +552,8 @@ struct sysent freebsd32_sysent[] = {
{ AS(freebsd32_cpuset_setid_args), (sy_call_t *)freebsd32_cpuset_setid, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 485 = freebsd32_cpuset_setid */
#endif
{ AS(freebsd32_cpuset_getid_args), (sy_call_t *)freebsd32_cpuset_getid, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 486 = freebsd32_cpuset_getid */
- { AS(freebsd32_cpuset_getaffinity_args), (sy_call_t *)freebsd32_cpuset_getaffinity, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 487 = freebsd32_cpuset_getaffinity */
- { AS(freebsd32_cpuset_setaffinity_args), (sy_call_t *)freebsd32_cpuset_setaffinity, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 488 = freebsd32_cpuset_setaffinity */
+ { AS(freebsd32_cpuset_getaffinity_args), (sy_call_t *)freebsd32_cpuset_getaffinity, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 487 = freebsd32_cpuset_getaffinity */
+ { AS(freebsd32_cpuset_setaffinity_args), (sy_call_t *)freebsd32_cpuset_setaffinity, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 488 = freebsd32_cpuset_setaffinity */
{ AS(faccessat_args), (sy_call_t *)sys_faccessat, AUE_FACCESSAT, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 489 = faccessat */
{ AS(fchmodat_args), (sy_call_t *)sys_fchmodat, AUE_FCHMODAT, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 490 = fchmodat */
{ AS(fchownat_args), (sy_call_t *)sys_fchownat, AUE_FCHOWNAT, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 491 = fchownat */
diff --git a/sys/kern/capabilities.conf b/sys/kern/capabilities.conf
index 7678294..7c2523c 100644
--- a/sys/kern/capabilities.conf
+++ b/sys/kern/capabilities.conf
@@ -133,13 +133,12 @@ closefrom
connectat
##
-## cpuset(2) and related calls require scoping by process, but should
-## eventually be allowed, at least in the current process case.
+## cpuset(2) and related calls are limited to caller's own process/thread.
##
#cpuset
-#cpuset_getaffinity
+cpuset_getaffinity
#cpuset_getid
-#cpuset_setaffinity
+cpuset_setaffinity
#cpuset_setid
##
diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c
index a4b78ff..86802b4 100644
--- a/sys/kern/init_sysent.c
+++ b/sys/kern/init_sysent.c
@@ -532,8 +532,8 @@ struct sysent sysent[] = {
{ AS(cpuset_args), (sy_call_t *)sys_cpuset, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 484 = cpuset */
{ AS(cpuset_setid_args), (sy_call_t *)sys_cpuset_setid, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 485 = cpuset_setid */
{ AS(cpuset_getid_args), (sy_call_t *)sys_cpuset_getid, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 486 = cpuset_getid */
- { AS(cpuset_getaffinity_args), (sy_call_t *)sys_cpuset_getaffinity, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 487 = cpuset_getaffinity */
- { AS(cpuset_setaffinity_args), (sy_call_t *)sys_cpuset_setaffinity, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 488 = cpuset_setaffinity */
+ { AS(cpuset_getaffinity_args), (sy_call_t *)sys_cpuset_getaffinity, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 487 = cpuset_getaffinity */
+ { AS(cpuset_setaffinity_args), (sy_call_t *)sys_cpuset_setaffinity, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 488 = cpuset_setaffinity */
{ AS(faccessat_args), (sy_call_t *)sys_faccessat, AUE_FACCESSAT, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 489 = faccessat */
{ AS(fchmodat_args), (sy_call_t *)sys_fchmodat, AUE_FCHMODAT, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 490 = fchmodat */
{ AS(fchownat_args), (sy_call_t *)sys_fchownat, AUE_FCHOWNAT, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 491 = fchownat */
diff --git a/sys/kern/kern_cpuset.c b/sys/kern/kern_cpuset.c
index 409aeed..5caaab4 100644
--- a/sys/kern/kern_cpuset.c
+++ b/sys/kern/kern_cpuset.c
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sched.h>
#include <sys/smp.h>
#include <sys/syscallsubr.h>
+#include <sys/capsicum.h>
#include <sys/cpuset.h>
#include <sys/sx.h>
#include <sys/queue.h>
@@ -523,6 +524,7 @@ cpuset_setproc(pid_t pid, struct cpuset *set, cpuset_t *mask)
int threads;
int nfree;
int error;
+
/*
* The algorithm requires two passes due to locking considerations.
*
@@ -1097,6 +1099,15 @@ kern_cpuset_getaffinity(struct thread *td, cpulevel_t level, cpuwhich_t which,
if (cpusetsize < sizeof(cpuset_t) || cpusetsize > CPU_MAXSIZE / NBBY)
return (ERANGE);
+ /* In Capability mode, you can only get your own CPU set. */
+ if (IN_CAPABILITY_MODE(td)) {
+ if (level != CPU_LEVEL_WHICH)
+ return (ECAPMODE);
+ if (which != CPU_WHICH_TID && which != CPU_WHICH_PID)
+ return (ECAPMODE);
+ if (id != -1)
+ return (ECAPMODE);
+ }
size = cpusetsize;
mask = malloc(size, M_TEMP, M_WAITOK | M_ZERO);
error = cpuset_which(which, id, &p, &ttd, &set);
@@ -1201,6 +1212,15 @@ kern_cpuset_setaffinity(struct thread *td, cpulevel_t level, cpuwhich_t which,
if (cpusetsize < sizeof(cpuset_t) || cpusetsize > CPU_MAXSIZE / NBBY)
return (ERANGE);
+ /* In Capability mode, you can only set your own CPU set. */
+ if (IN_CAPABILITY_MODE(td)) {
+ if (level != CPU_LEVEL_WHICH)
+ return (ECAPMODE);
+ if (which != CPU_WHICH_TID && which != CPU_WHICH_PID)
+ return (ECAPMODE);
+ if (id != -1)
+ return (ECAPMODE);
+ }
mask = malloc(cpusetsize, M_TEMP, M_WAITOK | M_ZERO);
error = copyin(maskp, mask, cpusetsize);
if (error)
OpenPOWER on IntegriCloud