changeset 7873:e3677dd00778

Mediate some process operations Mediate process operations that presently call *hasprocperm() by extending the existing interfaces to pass an access vector and inserting a fmac_hasprocperm() hook into hasprocperm(). Sample AVC output from kill `cat /var/run/sshd.pid`: avc: denied { signal } for scontext=user_u:user_r:user_t:unclassified tcontext=system_u:system_r:sshd_t:unclassified tclass=process pid=100763 comm=bash If we wanted to augment the avc message with the target pid, we might extend the hasprocperm() interface to optionally convey the target pid if available; then prochasprocperm() could pass that information from the proc_t.
author Stephen Smalley <sds@tycho.nsa.gov>
date Fri, 19 Sep 2008 08:01:07 -0400
parents 6762da052ca5
children 3621a9b87ec5
files usr/src/common/fmac/policy/flask/access_vectors usr/src/uts/common/brand/lx/syscall/lx_kill.c usr/src/uts/common/contract/process.c usr/src/uts/common/disp/class.c usr/src/uts/common/disp/priocntl.c usr/src/uts/common/fmac/fmac.c usr/src/uts/common/os/cpu.c usr/src/uts/common/os/cred.c usr/src/uts/common/os/klpd.c usr/src/uts/common/os/policy.c usr/src/uts/common/os/pool_pset.c usr/src/uts/common/os/sig.c usr/src/uts/common/sys/cred.h usr/src/uts/common/sys/fmac/fmac.h usr/src/uts/common/syscall/corectl.c usr/src/uts/common/syscall/lgrpsys.c usr/src/uts/common/syscall/pset.c
diffstat 17 files changed, 86 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/common/fmac/policy/flask/access_vectors	Thu Sep 18 11:04:18 2008 -0400
+++ b/usr/src/common/fmac/policy/flask/access_vectors	Fri Sep 19 08:01:07 2008 -0400
@@ -245,6 +245,7 @@
 {
 	fork
 	transition
+	info
 	sigchld
 	sigkill
 	sigstop
@@ -252,6 +253,8 @@
 	ptrace
 	getsched
 	setsched
+	getcore
+	setcore
 	getsession
 	getpgid
 	setpgid
--- a/usr/src/uts/common/brand/lx/syscall/lx_kill.c	Thu Sep 18 11:04:18 2008 -0400
+++ b/usr/src/uts/common/brand/lx/syscall/lx_kill.c	Fri Sep 19 08:01:07 2008 -0400
@@ -35,6 +35,8 @@
 #include <sys/thread.h>
 #include <sys/signal.h>
 #include <sys/brand.h>
+#include <sys/fmac/av_permissions.h>
+#include <sys/fmac/fmac.h>
 #include <sys/lx_brand.h>
 #include <sys/lx_pid.h>
 #include <lx_signum.h>
@@ -126,7 +128,7 @@
 	 *	  to send the signal to the target pid
 	 */
 	if (((sig == SIGCONT) && (pp->p_sessp != curproc->p_sessp)) ||
-	    (!prochasprocperm(pp, curproc, CRED()))) {
+	    (!prochasprocperm(pp, curproc, CRED(), fmac_sigtoav(sig)))) {
 		mutex_exit(&pp->p_lock);
 		rv = set_errno(EPERM);
 		goto free_and_exit;
--- a/usr/src/uts/common/contract/process.c	Thu Sep 18 11:04:18 2008 -0400
+++ b/usr/src/uts/common/contract/process.c	Fri Sep 19 08:01:07 2008 -0400
@@ -43,6 +43,7 @@
 #include <sys/cmn_err.h>
 #include <sys/nvpair.h>
 #include <sys/policy.h>
+#include <sys/fmac/av_permissions.h>
 #include <sys/refstr.h>
 #include <sys/sunddi.h>
 
@@ -488,9 +489,10 @@
 	int cankill;
 
 	mutex_enter(&tp->p_crlock);
-	cankill = hasprocperm(tp->p_cred, ctp->conp_cred);
+	cankill = hasprocperm(tp->p_cred, ctp->conp_cred, PROCESS__SIGKILL);
 	mutex_exit(&tp->p_crlock);
-	if (cankill || (sp && prochasprocperm(tp, sp, CRED())))
+	if (cankill || (sp && prochasprocperm(tp, sp, CRED(),
+			    PROCESS__SIGKILL)))
 		return (1);
 
 	return (0);
--- a/usr/src/uts/common/disp/class.c	Thu Sep 18 11:04:18 2008 -0400
+++ b/usr/src/uts/common/disp/class.c	Fri Sep 19 08:01:07 2008 -0400
@@ -32,6 +32,7 @@
 #include <sys/class.h>
 #include <sys/kmem.h>
 #include <sys/cred.h>
+#include <sys/fmac/av_permissions.h>
 #include <sys/proc.h>
 #include <sys/procset.h>
 #include <sys/modctl.h>
@@ -259,7 +260,8 @@
 		/*
 		 * Check basic permissions.
 		 */
-		if (!prochasprocperm(targpp, reqpp, reqpcredp)) {
+		if (!prochasprocperm(targpp, reqpp, reqpcredp,
+			PROCESS__SETSCHED)) {
 			crfree(reqpcredp);
 			return (EPERM);
 		}
--- a/usr/src/uts/common/disp/priocntl.c	Thu Sep 18 11:04:18 2008 -0400
+++ b/usr/src/uts/common/disp/priocntl.c	Fri Sep 19 08:01:07 2008 -0400
@@ -52,6 +52,7 @@
 #include <sys/uadmin.h>
 #include <sys/cmn_err.h>
 #include <sys/policy.h>
+#include <sys/fmac/av_permissions.h>
 #include <sys/schedctl.h>
 
 /*
@@ -973,7 +974,7 @@
 	 * Check permissions before changing the nice value.
 	 */
 	if (pcnice->pc_op == PC_SETNICE) {
-		if (!prochasprocperm(pp, curproc, CRED())) {
+		if (!prochasprocperm(pp, curproc, CRED(), PROCESS__SETSCHED)) {
 			mutex_exit(&pp->p_lock);
 			return (EPERM);
 		}
@@ -1143,7 +1144,7 @@
 	 * Check permissions before changing the prio value.
 	 */
 	if (pcprio->pc_op == PC_SETPRIO) {
-		if (!prochasprocperm(pp, curproc, CRED())) {
+		if (!prochasprocperm(pp, curproc, CRED(), PROCESS__SETSCHED)) {
 			mutex_exit(&pp->p_lock);
 			return (EPERM);
 		}
--- a/usr/src/uts/common/fmac/fmac.c	Thu Sep 18 11:04:18 2008 -0400
+++ b/usr/src/uts/common/fmac/fmac.c	Fri Sep 19 08:01:07 2008 -0400
@@ -606,3 +606,31 @@
 	return (avc_has_perm(crgetsecid((cred_t *)scr), crgetsecid(tcr),
 		    SECCLASS_PROCESS, PROCESS__PTRACE));
 }
+
+access_vector_t
+fmac_sigtoav(int sig)
+{
+	switch (sig) {
+	case SIGCHLD:
+		return (PROCESS__SIGCHLD);
+	case SIGKILL:
+		return (PROCESS__SIGKILL);
+	case SIGSTOP:
+		return (PROCESS__SIGSTOP);
+	}
+	return (PROCESS__SIGNAL);
+}
+
+int
+fmac_hasprocperm(const cred_t *tcrp, const cred_t *scrp, access_vector_t perms)
+{
+	security_id_t tsecid;
+	security_id_t ssecid;
+
+	if (!fmac_enabled)
+		return (0);
+
+	tsecid = crgetsecid((cred_t *)tcrp);
+	ssecid = crgetsecid((cred_t *)scrp);
+	return (avc_has_perm(ssecid, tsecid, SECCLASS_PROCESS, perms));
+}
--- a/usr/src/uts/common/os/cpu.c	Thu Sep 18 11:04:18 2008 -0400
+++ b/usr/src/uts/common/os/cpu.c	Fri Sep 19 08:01:07 2008 -0400
@@ -55,6 +55,7 @@
 #include <sys/bitmap.h>
 #include <sys/nvpair.h>
 #include <sys/pool_pset.h>
+#include <sys/fmac/av_permissions.h>
 #include <sys/msacct.h>
 #include <sys/time.h>
 #include <sys/archsystm.h>
@@ -2503,7 +2504,8 @@
 	 * Binding will get EPERM if the thread is of system class
 	 * or hasprocperm() fails.
 	 */
-	if (tp->t_cid == 0 || !hasprocperm(tp->t_cred, CRED())) {
+	if (tp->t_cid == 0 || !hasprocperm(tp->t_cred, CRED(),
+		PROCESS__SETSCHED)) {
 		*error = EPERM;
 		thread_unlock(tp);
 		return (0);
--- a/usr/src/uts/common/os/cred.c	Thu Sep 18 11:04:18 2008 -0400
+++ b/usr/src/uts/common/os/cred.c	Fri Sep 19 08:01:07 2008 -0400
@@ -65,6 +65,7 @@
 #include <sys/klpd.h>
 #include <sys/varargs.h>
 #include <sys/fmac/flask.h>
+#include <sys/fmac/fmac.h>
 
 
 /* Ephemeral IDs Zones specific data */
@@ -553,7 +554,7 @@
  * (4) otherwise, the check fails
  */
 int
-hasprocperm(const cred_t *tcrp, const cred_t *scrp)
+hasprocperm(const cred_t *tcrp, const cred_t *scrp, access_vector_t perms)
 {
 	if (scrp == tcrp)
 		return (1);
@@ -561,6 +562,8 @@
 	    (scrp->cr_zone != global_zone ||
 	    secpolicy_proc_zone(scrp) != 0))
 		return (0);
+	if (fmac_hasprocperm(tcrp, scrp, perms))
+		return (0);
 	if (scrp->cr_uid == tcrp->cr_ruid ||
 	    scrp->cr_ruid == tcrp->cr_ruid ||
 	    scrp->cr_uid  == tcrp->cr_suid ||
@@ -578,7 +581,8 @@
  * be held.
  */
 int
-prochasprocperm(proc_t *tp, proc_t *sp, const cred_t *scrp)
+prochasprocperm(proc_t *tp, proc_t *sp, const cred_t *scrp,
+    access_vector_t perms)
 {
 	int rets;
 	cred_t *tcrp;
@@ -594,7 +598,7 @@
 	mutex_enter(&tp->p_crlock);
 	crhold(tcrp = tp->p_cred);
 	mutex_exit(&tp->p_crlock);
-	rets = hasprocperm(tcrp, scrp);
+	rets = hasprocperm(tcrp, scrp, perms);
 	crfree(tcrp);
 
 	return (rets);
--- a/usr/src/uts/common/os/klpd.c	Thu Sep 18 11:04:18 2008 -0400
+++ b/usr/src/uts/common/os/klpd.c	Fri Sep 19 08:01:07 2008 -0400
@@ -40,6 +40,7 @@
 #include <sys/sysmacros.h>
 #include <sys/pathname.h>
 #include <sys/varargs.h>
+#include <sys/fmac/av_permissions.h>
 #include <sys/zone.h>
 #include <netinet/in.h>
 
@@ -548,7 +549,8 @@
 		cred_t *pcr;
 		mutex_enter(&pidlock);
 		p = prfind(pid);
-		if (p == NULL || !prochasprocperm(p, curproc, CRED())) {
+		if (p == NULL || !prochasprocperm(p, curproc, CRED(),
+			PROCESS__PTRACE)) {
 			mutex_exit(&pidlock);
 			klpd_rele(kpd);
 			return (set_errno(p == NULL ? ESRCH : EPERM));
--- a/usr/src/uts/common/os/policy.c	Thu Sep 18 11:04:18 2008 -0400
+++ b/usr/src/uts/common/os/policy.c	Fri Sep 19 08:01:07 2008 -0400
@@ -55,6 +55,7 @@
 #include <inet/optcom.h>
 #include <sys/sdt.h>
 #include <sys/vfs.h>
+#include <sys/fmac/av_permissions.h>
 #include <sys/mntent.h>
 #include <sys/contract_impl.h>
 
@@ -1833,7 +1834,8 @@
 secpolicy_basic_procinfo(const cred_t *cr, proc_t *tp, proc_t *sp)
 {
 	if (tp == sp ||
-	    !HAS_PRIVILEGE(cr, PRIV_PROC_INFO) && prochasprocperm(tp, sp, cr)) {
+	    !HAS_PRIVILEGE(cr, PRIV_PROC_INFO) &&
+	    prochasprocperm(tp, sp, cr, PROCESS__INFO)) {
 		return (0);
 	} else {
 		return (PRIV_POLICY(cr, PRIV_PROC_INFO, B_FALSE, EPERM, NULL));
--- a/usr/src/uts/common/os/pool_pset.c	Thu Sep 18 11:04:18 2008 -0400
+++ b/usr/src/uts/common/os/pool_pset.c	Fri Sep 19 08:01:07 2008 -0400
@@ -39,6 +39,7 @@
 #include <sys/exacct.h>
 #include <sys/time.h>
 #include <sys/policy.h>
+#include <sys/fmac/av_permissions.h>
 #include <sys/class.h>
 #include <sys/list.h>
 #include <sys/cred.h>
@@ -645,7 +646,7 @@
 		/*
 		 * Check our basic permissions to control this process.
 		 */
-		if (!prochasprocperm(p, curproc, pcred)) {
+		if (!prochasprocperm(p, curproc, pcred, PROCESS__SETSCHED)) {
 			mutex_exit(&p->p_lock);
 			weakbinding_start();
 			mutex_exit(&cpu_lock);
--- a/usr/src/uts/common/os/sig.c	Thu Sep 18 11:04:18 2008 -0400
+++ b/usr/src/uts/common/os/sig.c	Fri Sep 19 08:01:07 2008 -0400
@@ -59,6 +59,8 @@
 #include <sys/core.h>
 #include <sys/schedctl.h>
 #include <sys/contract/process_impl.h>
+#include <sys/fmac/av_permissions.h>
+#include <sys/fmac/fmac.h>
 #include <sys/dtrace.h>
 #include <sys/sdt.h>
 
@@ -1839,7 +1841,7 @@
 
 	if (pv->checkperm == 0 ||
 	    (pv->sig == SIGCONT && p->p_sessp == myprocp->p_sessp) ||
-	    prochasprocperm(p, myprocp, cr)) {
+	    prochasprocperm(p, myprocp, cr, fmac_sigtoav(pv->sig))) {
 		pv->perm++;
 		if (pv->sig) {
 			/* Make sure we should be setting si_pid and friends */
--- a/usr/src/uts/common/sys/cred.h	Thu Sep 18 11:04:18 2008 -0400
+++ b/usr/src/uts/common/sys/cred.h	Fri Sep 19 08:01:07 2008 -0400
@@ -82,8 +82,9 @@
 extern void crset(struct proc *, cred_t *);
 extern int groupmember(gid_t, const cred_t *);
 extern int supgroupmember(gid_t, const cred_t *);
-extern int hasprocperm(const cred_t *, const cred_t *);
-extern int prochasprocperm(struct proc *, struct proc *, const cred_t *);
+extern int hasprocperm(const cred_t *, const cred_t *, access_vector_t perms);
+extern int prochasprocperm(struct proc *, struct proc *, const cred_t *,
+    access_vector_t perms);
 extern int crcmp(const cred_t *, const cred_t *);
 extern cred_t *zone_kcred(void);
 
--- a/usr/src/uts/common/sys/fmac/fmac.h	Thu Sep 18 11:04:18 2008 -0400
+++ b/usr/src/uts/common/sys/fmac/fmac.h	Fri Sep 19 08:01:07 2008 -0400
@@ -101,6 +101,9 @@
     boolean_t *execsetid, security_id_t *prev_secidp, security_id_t *secidp);
 int fmac_vnode_access(vnode_t *, int, int, cred_t *, boolean_t);
 int fmac_priv_proc_cred_perm(const cred_t *scr, cred_t *tcr, int mode);
+access_vector_t fmac_sigtoav(int sig);
+int fmac_hasprocperm(const cred_t *tcrp, const cred_t *scrp,
+    access_vector_t perms);
 #endif /* _KERNEL */
 
 #ifdef __cplusplus
--- a/usr/src/uts/common/syscall/corectl.c	Thu Sep 18 11:04:18 2008 -0400
+++ b/usr/src/uts/common/syscall/corectl.c	Fri Sep 19 08:01:07 2008 -0400
@@ -35,6 +35,7 @@
 #include <sys/corectl.h>
 #include <sys/zone.h>
 #include <sys/cmn_err.h>
+#include <sys/fmac/av_permissions.h>
 #include <sys/policy.h>
 
 /*
@@ -285,7 +286,8 @@
 				mutex_enter(&p->p_lock);
 				mutex_exit(&pidlock);
 				mutex_enter(&p->p_crlock);
-				if (!hasprocperm(p->p_cred, CRED()))
+				if (!hasprocperm(p->p_cred, CRED(),
+					PROCESS__GETCORE))
 					error = EPERM;
 				else if (p->p_corefile != NULL)
 					rp = corectl_path_value(p->p_corefile);
@@ -396,7 +398,7 @@
 		mutex_enter(&p->p_lock);
 		mutex_exit(&pidlock);
 		mutex_enter(&p->p_crlock);
-		if (!hasprocperm(p->p_cred, CRED()))
+		if (!hasprocperm(p->p_cred, CRED(), PROCESS__GETCORE))
 			error = EPERM;
 		else if (p->p_content == NULL)
 			content = CC_CONTENT_NONE;
@@ -434,7 +436,8 @@
 
 	mutex_enter(&p->p_crlock);
 
-	if (!(p->p_flag & SSYS) && hasprocperm(p->p_cred, CRED())) {
+	if (!(p->p_flag & SSYS) && hasprocperm(p->p_cred, CRED(),
+		PROCESS__SETCORE)) {
 		mutex_exit(&p->p_crlock);
 		counterp->cc_count++;
 		if (counterp->cc_path != NULL) {
--- a/usr/src/uts/common/syscall/lgrpsys.c	Thu Sep 18 11:04:18 2008 -0400
+++ b/usr/src/uts/common/syscall/lgrpsys.c	Fri Sep 19 08:01:07 2008 -0400
@@ -38,6 +38,7 @@
 #include <sys/cpupart.h>
 #include <sys/lgrp.h>
 #include <sys/lgrp_user.h>
+#include <sys/fmac/av_permissions.h>
 #include <sys/promif.h>		/* for prom_printf() */
 #include <sys/sysmacros.h>
 
@@ -343,7 +344,8 @@
 			 * Check to see whether caller has permission to set
 			 * affinity for LWP
 			 */
-			if (t->t_cid == 0 || !hasprocperm(t->t_cred, CRED())) {
+			if (t->t_cid == 0 || !hasprocperm(t->t_cred, CRED(),
+				PROCESS__SETSCHED)) {
 				thread_unlock(t);
 				return (set_errno(EPERM));
 			}
@@ -585,7 +587,8 @@
 	 * Check to see whether caller has permission to set affinity for
 	 * thread
 	 */
-	if (t->t_cid == 0 || !hasprocperm(t->t_cred, CRED())) {
+	if (t->t_cid == 0 || !hasprocperm(t->t_cred, CRED(),
+		PROCESS__SETSCHED)) {
 		thread_unlock(t);
 		return (set_errno(EPERM));
 	}
@@ -956,7 +959,8 @@
 	 * Check to see whether caller has permission to set affinity for
 	 * thread
 	 */
-	if (t->t_cid == 0 || !hasprocperm(t->t_cred, CRED())) {
+	if (t->t_cid == 0 || !hasprocperm(t->t_cred, CRED(),
+		PROCESS__SETSCHED)) {
 		thread_unlock(t);
 		return (set_errno(EPERM));
 	}
--- a/usr/src/uts/common/syscall/pset.c	Thu Sep 18 11:04:18 2008 -0400
+++ b/usr/src/uts/common/syscall/pset.c	Fri Sep 19 08:01:07 2008 -0400
@@ -44,6 +44,7 @@
 #include <sys/pool.h>
 #include <sys/pool_pset.h>
 #include <sys/policy.h>
+#include <sys/fmac/av_permissions.h>
 #include <sys/zone.h>
 #include <sys/contract/process_impl.h>
 
@@ -273,7 +274,7 @@
 		 * Must have the same UID as the target process or
 		 * have PRIV_PROC_OWNER privilege.
 		 */
-		if (!hasprocperm(tp->t_cred, CRED()))
+		if (!hasprocperm(tp->t_cred, CRED(), PROCESS__SETSCHED))
 			return (EPERM);
 		/*
 		 * Unbinding of an unbound thread should always succeed.