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:
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to