Date: Thu, 30 Jun 2011 10:56:02 +0000 (UTC) From: Jonathan Anderson <jonathan@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r223692 - in head/sys: amd64/amd64 arm/arm i386/i386 kern sparc64/sparc64 Message-ID: <201106301056.p5UAu2Ze040992@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jonathan Date: Thu Jun 30 10:56:02 2011 New Revision: 223692 URL: http://svn.freebsd.org/changeset/base/223692 Log: 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) Modified: head/sys/amd64/amd64/sys_machdep.c head/sys/arm/arm/sys_machdep.c head/sys/i386/i386/sys_machdep.c head/sys/kern/imgact_elf.c head/sys/kern/kern_exec.c head/sys/kern/uipc_shm.c head/sys/kern/uipc_syscalls.c head/sys/sparc64/sparc64/sys_machdep.c Modified: head/sys/amd64/amd64/sys_machdep.c ============================================================================== --- head/sys/amd64/amd64/sys_machdep.c Thu Jun 30 10:19:43 2011 (r223691) +++ head/sys/amd64/amd64/sys_machdep.c Thu Jun 30 10:56:02 2011 (r223692) @@ -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 Modified: head/sys/arm/arm/sys_machdep.c ============================================================================== --- head/sys/arm/arm/sys_machdep.c Thu Jun 30 10:19:43 2011 (r223691) +++ head/sys/arm/arm/sys_machdep.c Thu Jun 30 10:56:02 2011 (r223692) @@ -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; + case ARM_SYNC_ICACHE: + case ARM_DRAIN_WRITEBUF: + case ARM_SET_TP: + case ARM_GET_TP: + break; - default: - return (ECAPMODE); + default: + return (ECAPMODE); } } #endif Modified: head/sys/i386/i386/sys_machdep.c ============================================================================== --- head/sys/i386/i386/sys_machdep.c Thu Jun 30 10:19:43 2011 (r223691) +++ head/sys/i386/i386/sys_machdep.c Thu Jun 30 10:56:02 2011 (r223692) @@ -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 Modified: head/sys/kern/imgact_elf.c ============================================================================== --- head/sys/kern/imgact_elf.c Thu Jun 30 10:19:43 2011 (r223691) +++ head/sys/kern/imgact_elf.c Thu Jun 30 10:56:02 2011 (r223692) @@ -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 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; Modified: head/sys/kern/kern_exec.c ============================================================================== --- head/sys/kern/kern_exec.c Thu Jun 30 10:19:43 2011 (r223691) +++ head/sys/kern/kern_exec.c Thu Jun 30 10:56:02 2011 (r223692) @@ -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) { /* Modified: head/sys/kern/uipc_shm.c ============================================================================== --- head/sys/kern/uipc_shm.c Thu Jun 30 10:19:43 2011 (r223691) +++ head/sys/kern/uipc_shm.c Thu Jun 30 10:56:02 2011 (r223692) @@ -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_o 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); Modified: head/sys/kern/uipc_syscalls.c ============================================================================== --- head/sys/kern/uipc_syscalls.c Thu Jun 30 10:19:43 2011 (r223691) +++ head/sys/kern/uipc_syscalls.c Thu Jun 30 10:56:02 2011 (r223692) @@ -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) { Modified: head/sys/sparc64/sparc64/sys_machdep.c ============================================================================== --- head/sys/sparc64/sparc64/sys_machdep.c Thu Jun 30 10:19:43 2011 (r223691) +++ head/sys/sparc64/sparc64/sys_machdep.c Thu Jun 30 10:56:02 2011 (r223692) @@ -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 sysarc { 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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201106301056.p5UAu2Ze040992>