changeset 7857:a50b497f89fe

Basic process security context transition support Implement basic process security context transition support, leveraging the prior patch for file security contexts on executables. With this support and a suitable labeled filesystem and policy, processes will automatically transition into an appropriate security context when they execute a program based on the program file's security context, and a process may explicitly transition to a given security context if authorized via the already existing setexeccon() interface. This only implements the core logic for a transition; a number of other checks will be added later, such as a check to decide whether the linker security flag needs to be set on the transition, ptrace-related checking, checks on the inheritance of state such as open file descriptors, the normal file execute check applied via VOP_ACCESS, mmap/mprotect PROT_EXEC checks, etc. The checks applied here are: - If not transitioning, may the process execute the file without transitioning to a new security context (:file execute_no_trans)? - If transitioning, may the process transition to the new security context (:process transition) and may the new process security context be entered via a program with this file security context (:file entrypoint)? Changes since the prior version of this patch include: - setsecid changed from int to boolean_t, with B_TRUE and B_FALSE as values. Webrev available at: http://cr.opensolaris.org/~sds/exec/
author Stephen Smalley <sds@tycho.nsa.gov>
date Tue, 09 Sep 2008 16:09:39 -0400
parents d58705eb5b58
children 8367f05f6752
files usr/src/uts/common/fmac/fmac.c usr/src/uts/common/os/exec.c usr/src/uts/common/sys/fmac/fmac.h
diffstat 3 files changed, 65 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/fmac/fmac.c	Tue Sep 09 16:09:39 2008 -0400
+++ b/usr/src/uts/common/fmac/fmac.c	Tue Sep 09 16:09:39 2008 -0400
@@ -319,3 +319,46 @@
 	vp->v_secid = secid;
 	mutex_exit(&(vp->v_lock));
 }
+
+int
+fmac_exec(cred_t *cr, vnode_t *vp, boolean_t *setsecid,
+    security_id_t *prev_secidp, security_id_t *secidp)
+{
+	security_id_t prev_secid, secid;
+	int error;
+
+	if (!fmac_enabled)
+		return (0);
+
+	prev_secid = crgetsecid(cr);
+	secid = crgetexecsecid(cr);
+	if (!secid) {
+		error = security_transition_sid(prev_secid, vp->v_secid,
+		    SECCLASS_PROCESS, &secid);
+		if (error)
+			return (error);
+	}
+
+	if (prev_secid == secid) {
+		error = avc_has_perm(prev_secid, vp->v_secid, SECCLASS_FILE,
+		    FILE__EXECUTE_NO_TRANS);
+		if (error)
+			return (error);
+		*setsecid = B_FALSE;
+		return (0);
+	}
+
+	error = avc_has_perm(prev_secid, secid, SECCLASS_PROCESS,
+	    PROCESS__TRANSITION);
+	if (error)
+		return (error);
+
+	error = avc_has_perm(secid, vp->v_secid, SECCLASS_FILE,
+	    FILE__ENTRYPOINT);
+	if (error)
+		return (error);
+	*setsecid = B_TRUE;
+	*prev_secidp = prev_secid;
+	*secidp = secid;
+	return (0);
+}
--- a/usr/src/uts/common/os/exec.c	Tue Sep 09 16:09:39 2008 -0400
+++ b/usr/src/uts/common/os/exec.c	Tue Sep 09 16:09:39 2008 -0400
@@ -68,6 +68,7 @@
 #include <sys/pool.h>
 #include <sys/sdt.h>
 #include <sys/brand.h>
+#include <sys/fmac/fmac.h>
 
 #include <c2/audit.h>
 
@@ -522,6 +523,8 @@
 	int suidflags = 0;
 	ssize_t resid;
 	uid_t uid, gid;
+	security_id_t prev_secid, secid;
+	boolean_t setsecid = B_FALSE;
 	struct vattr vattr;
 	char magbuf[MAGIC_BYTES];
 	int setid;
@@ -562,11 +565,26 @@
 	if ((eswp = findexec_by_hdr(magbuf)) == NULL)
 		goto bad;
 
-	if (level == 0 &&
-	    (privflags = execsetid(vp, &vattr, &uid, &gid)) != 0) {
+	if (level == 0) {
+		privflags = execsetid(vp, &vattr, &uid, &gid);
+
+		error = fmac_exec(CRED(), vp, &setsecid, &prev_secid, &secid);
+		if (error)
+			goto bad;
 
+		if (setsecid)
+			privflags |= PRIV_SETUGID;
+	}
+
+	if (level == 0 && privflags != 0) {
 		newcred = cred = crdup(cred);
 
+		if (setsecid) {
+			cred->cr_prev_secid = prev_secid;
+			cred->cr_secid = secid;
+			cred->cr_exec_secid = SECSID_NULL;
+		}
+
 		/* If we can, drop the PA bit */
 		if ((privflags & PRIV_RESET) != 0)
 			priv_adjust_PA(cred);
--- a/usr/src/uts/common/sys/fmac/fmac.h	Tue Sep 09 16:09:39 2008 -0400
+++ b/usr/src/uts/common/sys/fmac/fmac.h	Tue Sep 09 16:09:39 2008 -0400
@@ -89,6 +89,8 @@
 int fmac_vnode_create(vnode_t *, char *, xvattr_t *, vattr_t **, cred_t *,
     security_id_t *);
 void fmac_vnode_post_create(vnode_t *, security_id_t);
+int fmac_exec(cred_t *cr, vnode_t *vp, boolean_t *setsecid,
+    security_id_t *prev_secidp, security_id_t *secidp);
 #endif /* _KERNEL */
 
 #ifdef __cplusplus