diff options
author | allanjude <allanjude@FreeBSD.org> | 2017-06-11 02:04:39 +0000 |
---|---|---|
committer | allanjude <allanjude@FreeBSD.org> | 2017-06-11 02:04:39 +0000 |
commit | add5f3e1312c298d03bbd73a3ff11a1cb7d381f4 (patch) | |
tree | 2910e97c23abe263755e806b8c4c93f796481173 | |
parent | a792c4a78cc396cbe2e4eb2d13bb2d7a541a9185 (diff) | |
download | FreeBSD-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.2 | 8 | ||||
-rw-r--r-- | share/man/man4/capsicum.4 | 12 | ||||
-rw-r--r-- | sys/compat/freebsd32/capabilities.conf | 4 | ||||
-rw-r--r-- | sys/compat/freebsd32/freebsd32_sysent.c | 4 | ||||
-rw-r--r-- | sys/kern/capabilities.conf | 7 | ||||
-rw-r--r-- | sys/kern/init_sysent.c | 4 | ||||
-rw-r--r-- | sys/kern/kern_cpuset.c | 20 |
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) |