svn commit: r223692 - in head/sys: amd64/amd64 arm/arm i386/i386 kern sparc64/sparc64

Jonathan Anderson jonathan at FreeBSD.org
Thu Jun 30 10:56:02 UTC 2011


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:


More information about the svn-src-all mailing list