summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjonathan <jonathan@FreeBSD.org>2011-06-30 10:56:02 +0000
committerjonathan <jonathan@FreeBSD.org>2011-06-30 10:56:02 +0000
commit8c932faae446ada0bed49a41fbb164c821227122 (patch)
tree4124774c8a367f5606513084c5f950e1a12d2ac0
parentced9bcf26f7e7107339e61b56b9ba7ceba6049ac (diff)
downloadFreeBSD-src-8c932faae446ada0bed49a41fbb164c821227122.zip
FreeBSD-src-8c932faae446ada0bed49a41fbb164c821227122.tar.gz
Add some checks to ensure that Capsicum is behaving correctly, and add some
more explicit comments about what's going on and what future maintainers need to do when e.g. adding a new operation to a sys_machdep.c. Approved by: mentor(rwatson), re(bz)
-rw-r--r--sys/amd64/amd64/sys_machdep.c34
-rw-r--r--sys/arm/arm/sys_machdep.c20
-rw-r--r--sys/i386/i386/sys_machdep.c26
-rw-r--r--sys/kern/imgact_elf.c11
-rw-r--r--sys/kern/kern_exec.c24
-rw-r--r--sys/kern/uipc_shm.c11
-rw-r--r--sys/kern/uipc_syscalls.c7
-rw-r--r--sys/sparc64/sparc64/sys_machdep.c21
8 files changed, 117 insertions, 37 deletions
diff --git a/sys/amd64/amd64/sys_machdep.c b/sys/amd64/amd64/sys_machdep.c
index beb248c..17eada1 100644
--- a/sys/amd64/amd64/sys_machdep.c
+++ b/sys/amd64/amd64/sys_machdep.c
@@ -182,26 +182,28 @@ sysarch(td, uap)
#ifdef CAPABILITY_MODE
/*
- * Whitelist of operations which are safe enough for capability mode.
+ * When adding new operations, add a new case statement here to
+ * explicitly indicate whether or not the operation is safe to
+ * perform in capability mode.
*/
if (IN_CAPABILITY_MODE(td)) {
switch (uap->op) {
- case I386_GET_LDT:
- case I386_SET_LDT:
- case I386_GET_IOPERM:
- case I386_GET_FSBASE:
- case I386_SET_FSBASE:
- case I386_GET_GSBASE:
- case I386_SET_GSBASE:
- case AMD64_GET_FSBASE:
- case AMD64_SET_FSBASE:
- case AMD64_GET_GSBASE:
- case AMD64_SET_GSBASE:
- break;
+ case I386_GET_LDT:
+ case I386_SET_LDT:
+ case I386_GET_IOPERM:
+ case I386_GET_FSBASE:
+ case I386_SET_FSBASE:
+ case I386_GET_GSBASE:
+ case I386_SET_GSBASE:
+ case AMD64_GET_FSBASE:
+ case AMD64_SET_FSBASE:
+ case AMD64_GET_GSBASE:
+ case AMD64_SET_GSBASE:
+ break;
- case I386_SET_IOPERM:
- default:
- return (ECAPMODE);
+ case I386_SET_IOPERM:
+ default:
+ return (ECAPMODE);
}
}
#endif
diff --git a/sys/arm/arm/sys_machdep.c b/sys/arm/arm/sys_machdep.c
index 52545d8..4c3e350 100644
--- a/sys/arm/arm/sys_machdep.c
+++ b/sys/arm/arm/sys_machdep.c
@@ -109,18 +109,20 @@ sysarch(td, uap)
#ifdef CAPABILITY_MODE
/*
- * Whitelist of operations which are safe enough for capability mode.
+ * When adding new operations, add a new case statement here to
+ * explicitly indicate whether or not the operation is safe to
+ * perform in capability mode.
*/
if (IN_CAPABILITY_MODE(td)) {
switch (uap->op) {
- case ARM_SYNC_ICACHE:
- case ARM_DRAIN_WRITEBUF:
- case ARM_SET_TP:
- case ARM_GET_TP:
- break;
-
- default:
- return (ECAPMODE);
+ case ARM_SYNC_ICACHE:
+ case ARM_DRAIN_WRITEBUF:
+ case ARM_SET_TP:
+ case ARM_GET_TP:
+ break;
+
+ default:
+ return (ECAPMODE);
}
}
#endif
diff --git a/sys/i386/i386/sys_machdep.c b/sys/i386/i386/sys_machdep.c
index e7b0828..8370516 100644
--- a/sys/i386/i386/sys_machdep.c
+++ b/sys/i386/i386/sys_machdep.c
@@ -113,22 +113,24 @@ sysarch(td, uap)
#ifdef CAPABILITY_MODE
/*
- * Whitelist of operations which are safe enough for capability mode.
+ * When adding new operations, add a new case statement here to
+ * explicitly indicate whether or not the operation is safe to
+ * perform in capability mode.
*/
if (IN_CAPABILITY_MODE(td)) {
switch (uap->op) {
- case I386_GET_LDT:
- case I386_SET_LDT:
- case I386_GET_IOPERM:
- case I386_GET_FSBASE:
- case I386_SET_FSBASE:
- case I386_GET_GSBASE:
- case I386_SET_GSBASE:
- break;
+ case I386_GET_LDT:
+ case I386_SET_LDT:
+ case I386_GET_IOPERM:
+ case I386_GET_FSBASE:
+ case I386_SET_FSBASE:
+ case I386_GET_GSBASE:
+ case I386_SET_GSBASE:
+ break;
- case I386_SET_IOPERM:
- default:
- return (ECAPMODE);
+ case I386_SET_IOPERM:
+ default:
+ return (ECAPMODE);
}
}
#endif
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index b41741a..ad79360 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -31,10 +31,12 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_capsicum.h"
#include "opt_compat.h"
#include "opt_core.h"
#include <sys/param.h>
+#include <sys/capability.h>
#include <sys/exec.h>
#include <sys/fcntl.h>
#include <sys/imgact.h>
@@ -578,6 +580,15 @@ __elfN(load_file)(struct proc *p, const char *file, u_long *addr,
u_long base_addr = 0;
int vfslocked, error, i, numsegs;
+#ifdef CAPABILITY_MODE
+ /*
+ * XXXJA: This check can go away once we are sufficiently confident
+ * that the checks in namei() are correct.
+ */
+ if (IN_CAPABILITY_MODE(curthread))
+ return (ECAPMODE);
+#endif
+
tempdata = malloc(sizeof(*tempdata), M_TEMP, M_WAITOK);
nd = &tempdata->nd;
attr = &tempdata->attr;
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index c51cc39..f30f89a 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -27,12 +27,14 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_capsicum.h"
#include "opt_hwpmc_hooks.h"
#include "opt_kdtrace.h"
#include "opt_ktrace.h"
#include "opt_vm.h"
#include <sys/param.h>
+#include <sys/capability.h>
#include <sys/systm.h>
#include <sys/eventhandler.h>
#include <sys/lock.h>
@@ -415,6 +417,18 @@ do_execve(td, args, mac_p)
interpret:
if (args->fname != NULL) {
+#ifdef CAPABILITY_MODE
+ /*
+ * While capability mode can't reach this point via direct
+ * path arguments to execve(), we also don't allow
+ * interpreters to be used in capability mode (for now).
+ * Catch indirect lookups and return a permissions error.
+ */
+ if (IN_CAPABILITY_MODE(td)) {
+ error = ECAPMODE;
+ goto exec_fail;
+ }
+#endif
error = namei(&nd);
if (error)
goto exec_fail;
@@ -631,6 +645,13 @@ interpret:
* Don't honor setuid/setgid if the filesystem prohibits it or if
* the process is being traced.
*
+ * We disable setuid/setgid/etc in compatibility mode on the basis
+ * that most setugid applications are not written with that
+ * environment in mind, and will therefore almost certainly operate
+ * incorrectly. In principle there's no reason that setugid
+ * applications might not be useful in capability mode, so we may want
+ * to reconsider this conservative design choice in the future.
+ *
* XXXMAC: For the time being, use NOSUID to also prohibit
* transitions on the file system.
*/
@@ -646,6 +667,9 @@ interpret:
#endif
if (credential_changing &&
+#ifdef CAPABILITY_MODE
+ ((oldcred->cr_flags & CRED_FLAG_CAPMODE) == 0) &&
+#endif
(imgp->vp->v_mount->mnt_flag & MNT_NOSUID) == 0 &&
(p->p_flag & P_TRACED) == 0) {
/*
diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c
index cea70c7..0414f12 100644
--- a/sys/kern/uipc_shm.c
+++ b/sys/kern/uipc_shm.c
@@ -55,7 +55,10 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_capsicum.h"
+
#include <sys/param.h>
+#include <sys/capability.h>
#include <sys/fcntl.h>
#include <sys/file.h>
#include <sys/filedesc.h>
@@ -486,6 +489,14 @@ shm_open(struct thread *td, struct shm_open_args *uap)
mode_t cmode;
int fd, error;
+#ifdef CAPABILITY_MODE
+ /*
+ * shm_open(2) is only allowed for anonymous objects.
+ */
+ if (IN_CAPABILITY_MODE(td) && (uap->path != SHM_ANON))
+ return (ECAPMODE);
+#endif
+
if ((uap->flags & O_ACCMODE) != O_RDONLY &&
(uap->flags & O_ACCMODE) != O_RDWR)
return (EINVAL);
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index 19aaee0..c434973 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -35,6 +35,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_capsicum.h"
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_sctp.h"
@@ -43,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/capability.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
@@ -675,6 +677,11 @@ sendit(td, s, mp, flags)
struct sockaddr *to;
int error;
+#ifdef CAPABILITY_MODE
+ if (IN_CAPABILITY_MODE(td) && (mp->msg_name != NULL))
+ return (ECAPMODE);
+#endif
+
if (mp->msg_name != NULL) {
error = getsockaddr(&to, mp->msg_name, mp->msg_namelen);
if (error) {
diff --git a/sys/sparc64/sparc64/sys_machdep.c b/sys/sparc64/sparc64/sys_machdep.c
index 9ac5fbc..530ff95 100644
--- a/sys/sparc64/sparc64/sys_machdep.c
+++ b/sys/sparc64/sparc64/sys_machdep.c
@@ -26,8 +26,11 @@
* $FreeBSD$
*/
+#include "opt_capsicum.h"
+
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/capability.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
@@ -53,6 +56,24 @@ sysarch(struct thread *td, struct sysarch_args *uap)
{
int error;
+#ifdef CAPABILITY_MODE
+ /*
+ * When adding new operations, add a new case statement here to
+ * explicitly indicate whether or not the operation is safe to
+ * perform in capability mode.
+ */
+ if (IN_CAPABILITY_MODE(td)) {
+ switch (uap->op) {
+ case SPARC_SIGTRAMP_INSTALL:
+ case SPARC_UTRAP_INSTALL:
+ break;
+
+ default:
+ return (ECAPMODE);
+ }
+ }
+#endif
+
mtx_lock(&Giant);
switch (uap->op) {
case SPARC_SIGTRAMP_INSTALL:
OpenPOWER on IntegriCloud