All of lore.kernel.org
 help / color / mirror / Atom feed
From: KaiGai Kohei <kaigai@ak.jp.nec.com>
To: method@manicmethod.com
Cc: jmorris@namei.org, Eric Paris <eparis@parisplace.org>,
	Stephen Smalley <sds@tycho.nsa.gov>,
	Eamon Walsh <ewalsh@tycho.nsa.gov>,
	selinux <selinux@tycho.nsa.gov>
Subject: Re: [PATCH] Permissive domain in userspace object manager
Date: Wed, 01 Apr 2009 10:41:07 +0900	[thread overview]
Message-ID: <49D2C633.3000406@ak.jp.nec.com> (raw)
In-Reply-To: <49D2BE6D.4030708@ak.jp.nec.com>

[-- Attachment #1: Type: text/plain, Size: 4840 bytes --]

The attached patch is for libselinux.
Most of part is unchanged from the previous one, expect for manpage.

KaiGai Kohei wrote:
> This patch enables applications to handle permissive domain correctly.
> 
> Since the v2.6.26 kernel, SELinux has supported an idea of permissive
> domain which allows certain processes to work as if permissive mode,
> even if the global setting is enforcing mode.
> However, we don't have an application program interface to inform
> what domains are permissive one, and what domains are not.
> It means applications focuses on SELinux (XACE/SELinux, SE-PostgreSQL
> and so on) cannot handle permissive domain correctly.
> 
> This patch add the sixth field (flags) on the reply of the /selinux/access
> interface which is used to make an access control decision from userspace.
> If the first bit of the flags field is positive, it means the required
> access control decision is on permissive domain, so application should
> allow any required actions, as the kernel doing.
> 
> This patch also has a side benefit. The av_decision.flags is set at
> context_struct_compute_av(). It enables to check required permissions
> without read_lock(&policy_rwlock).
> 
>  Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
> --
>  security/selinux/avc.c              |    2 +-
>  security/selinux/include/security.h |    4 +++-
>  security/selinux/selinuxfs.c        |    4 ++--
>  security/selinux/ss/services.c      |   30 +++++-------------------------
>  4 files changed, 11 insertions(+), 29 deletions(-)
> 
> diff --git a/security/selinux/avc.c b/security/selinux/avc.c
> index 7f9b5fa..b2ab608 100644
> --- a/security/selinux/avc.c
> +++ b/security/selinux/avc.c
> @@ -927,7 +927,7 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
>  	if (denied) {
>  		if (flags & AVC_STRICT)
>  			rc = -EACCES;
> -		else if (!selinux_enforcing || security_permissive_sid(ssid))
> +		else if (!selinux_enforcing || (avd->flags & AVD_FLAGS_PERMISSIVE))
>  			avc_update_node(AVC_CALLBACK_GRANT, requested, ssid,
>  					tsid, tclass, avd->seqno);
>  		else
> diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
> index 5c3434f..a7be3f0 100644
> --- a/security/selinux/include/security.h
> +++ b/security/selinux/include/security.h
> @@ -91,9 +91,11 @@ struct av_decision {
>  	u32 auditallow;
>  	u32 auditdeny;
>  	u32 seqno;
> +	u32 flags;
>  };
> 
> -int security_permissive_sid(u32 sid);
> +/* definitions of av_decision.flags */
> +#define AVD_FLAGS_PERMISSIVE	0x0001
> 
>  int security_compute_av(u32 ssid, u32 tsid,
>  	u16 tclass, u32 requested,
> diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
> index d3c8b98..4d56ab1 100644
> --- a/security/selinux/selinuxfs.c
> +++ b/security/selinux/selinuxfs.c
> @@ -594,10 +594,10 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
>  		goto out2;
> 
>  	length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT,
> -			  "%x %x %x %x %u",
> +			  "%x %x %x %x %u %x",
>  			  avd.allowed, 0xffffffff,
>  			  avd.auditallow, avd.auditdeny,
> -			  avd.seqno);
> +			  avd.seqno, avd.flags);
>  out2:
>  	kfree(tcon);
>  out:
> diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
> index deeec6c..500e6f7 100644
> --- a/security/selinux/ss/services.c
> +++ b/security/selinux/ss/services.c
> @@ -410,6 +410,7 @@ static int context_struct_compute_av(struct context *scontext,
>  	avd->auditallow = 0;
>  	avd->auditdeny = 0xffffffff;
>  	avd->seqno = latest_granting;
> +	avd->flags = 0;
> 
>  	/*
>  	 * Check for all the invalid cases.
> @@ -528,31 +529,6 @@ inval_class:
>  	return 0;
>  }
> 
> -/*
> - * Given a sid find if the type has the permissive flag set
> - */
> -int security_permissive_sid(u32 sid)
> -{
> -	struct context *context;
> -	u32 type;
> -	int rc;
> -
> -	read_lock(&policy_rwlock);
> -
> -	context = sidtab_search(&sidtab, sid);
> -	BUG_ON(!context);
> -
> -	type = context->type;
> -	/*
> -	 * we are intentionally using type here, not type-1, the 0th bit may
> -	 * someday indicate that we are globally setting permissive in policy.
> -	 */
> -	rc = ebitmap_get_bit(&policydb.permissive_map, type);
> -
> -	read_unlock(&policy_rwlock);
> -	return rc;
> -}
> -
>  static int security_validtrans_handle_fail(struct context *ocontext,
>  					   struct context *ncontext,
>  					   struct context *tcontext,
> @@ -767,6 +743,10 @@ int security_compute_av(u32 ssid,
> 
>  	rc = context_struct_compute_av(scontext, tcontext, tclass,
>  				       requested, avd);
> +
> +	/* permissive domain? */
> +	if (ebitmap_get_bit(&policydb.permissive_map, scontext->type))
> +	    avd->flags |= AVD_FLAGS_PERMISSIVE;
>  out:
>  	read_unlock(&policy_rwlock);
>  	return rc;
> 
> 


-- 
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>

[-- Attachment #2: libselinux-userspace-permissive-domain.2.patch --]
[-- Type: text/x-patch, Size: 10147 bytes --]

 Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
--
 libselinux/include/selinux/selinux.h            |   15 ++++
 libselinux/man/man3/security_compute_av.3       |   23 ++++++-
 libselinux/man/man3/security_compute_av_flags.3 |    1 +
 libselinux/src/avc.c                            |   22 +++--
 libselinux/src/compute_av.c                     |   90 +++++++++++++++++++----
 libselinux/src/selinux_internal.h               |    2 +
 6 files changed, 128 insertions(+), 25 deletions(-)

diff --git a/libselinux/include/selinux/selinux.h b/libselinux/include/selinux/selinux.h
index fab083e..7030f38 100644
--- a/libselinux/include/selinux/selinux.h
+++ b/libselinux/include/selinux/selinux.h
@@ -130,8 +130,12 @@ struct av_decision {
 	access_vector_t auditallow;
 	access_vector_t auditdeny;
 	unsigned int seqno;
+	unsigned int flags;
 };
 
+/* Definitions of av_decision.flags */
+#define SELINUX_AVD_FLAGS_PERMISSIVE	0x0001
+
 /* Structure for passing options, used by AVC and label subsystems */
 struct selinux_opt {
 	int type;
@@ -180,6 +184,17 @@ extern int security_compute_av_raw(security_context_t scon,
 				   access_vector_t requested,
 				   struct av_decision *avd);
 
+extern int security_compute_av_flags(security_context_t scon,
+				     security_context_t tcon,
+				     security_class_t tclass,
+				     access_vector_t requested,
+				     struct av_decision *avd);
+extern int security_compute_av_flags_raw(security_context_t scon,
+					 security_context_t tcon,
+					 security_class_t tclass,
+					 access_vector_t requested,
+					 struct av_decision *avd);
+
 /* Compute a labeling decision and set *newcon to refer to it.
    Caller must free via freecon. */
 extern int security_compute_create(security_context_t scon,
diff --git a/libselinux/man/man3/security_compute_av.3 b/libselinux/man/man3/security_compute_av.3
index 885719f..e759c4b 100644
--- a/libselinux/man/man3/security_compute_av.3
+++ b/libselinux/man/man3/security_compute_av.3
@@ -1,6 +1,6 @@
 .TH "security_compute_av" "3" "1 January 2004" "russell@coker.com.au" "SELinux API documentation"
 .SH "NAME"
-security_compute_av, security_compute_create, security_compute_relabel,
+security_compute_av, security_compute_av_flags, security_compute_create, security_compute_relabel,
 security_compute_member, security_compute_user, security_get_initial_context \- query
 the SELinux policy database in the kernel.
 
@@ -11,6 +11,8 @@ the SELinux policy database in the kernel.
 .sp
 .BI "int security_compute_av(security_context_t "scon ", security_context_t "tcon ", security_class_t "tclass ", access_vector_t "requested ", struct av_decision *" avd );
 .sp
+.BI "int security_compute_av_flags(security_context_t "scon ", security_context_t "tcon ", security_class_t "tclass ", access_vector_t "requested ", struct av_decision *" avd );
+.sp
 .BI "int security_compute_create(security_context_t "scon ", security_context_t "tcon ", security_class_t "tclass ", security_context_t *" newcon );
 .sp
 .BI "int security_compute_relabel(security_context_t "scon ", security_context_t "tcon ", security_class_t "tclass ", security_context_t *" newcon );
@@ -35,6 +37,25 @@ via class
 with the
 .B requested
 access vector. See the cron source for a usage example.
+Please note that it does not set up the
+.B flags
+of
+.B av_decision
+because of binary compatibility.
+
+.B security_compute_av_flags
+provides identical functionality with
+.B security_compute_av
+expect for the
+.B flags
+of
+.B av_decision
+to be set correctly.
+Now we have only a flag:
+.B SELINUX_AVD_FLAGS_PERMISSIVE
+which means the returned
+.B av_decision
+is computed on permissive domain.
 
 .B security_compute_create
 is used to compute a context to use for labeling a new object in a particular
diff --git a/libselinux/man/man3/security_compute_av_flags.3 b/libselinux/man/man3/security_compute_av_flags.3
index e69de29..a60bca4 100644
--- a/libselinux/man/man3/security_compute_av_flags.3
+++ b/libselinux/man/man3/security_compute_av_flags.3
@@ -0,0 +1 @@
+.so man3/security_compute_av.3
diff --git a/libselinux/src/avc.c b/libselinux/src/avc.c
index 1545dd3..f0e2d33 100644
--- a/libselinux/src/avc.c
+++ b/libselinux/src/avc.c
@@ -849,9 +849,9 @@ int avc_has_perm_noaudit(security_id_t ssid,
 				rc = -1;
 				goto out;
 			}
-			rc = security_compute_av_raw(ssid->ctx, tsid->ctx,
-						     tclass, requested,
-						     &entry.avd);
+			rc = security_compute_av_flags_raw(ssid->ctx, tsid->ctx,
+							   tclass, requested,
+							   &entry.avd);
 			if (rc)
 				goto out;
 			rc = avc_insert(ssid, tsid, tclass, &entry, aeref);
@@ -867,11 +867,13 @@ int avc_has_perm_noaudit(security_id_t ssid,
 	denied = requested & ~(ae->avd.allowed);
 
 	if (!requested || denied) {
-		if (avc_enforcing) {
+		if (!avc_enforcing ||
+		    (ae->avd.flags & SELINUX_AVD_FLAGS_PERMISSIVE))
+			ae->avd.allowed |= requested;
+		else {
 			errno = EACCES;
 			rc = -1;
-		} else
-			ae->avd.allowed |= requested;
+		}
 	}
 
       out:
@@ -885,9 +887,11 @@ int avc_has_perm(security_id_t ssid, security_id_t tsid,
 		 security_class_t tclass, access_vector_t requested,
 		 struct avc_entry_ref *aeref, void *auditdata)
 {
-	struct av_decision avd = { 0, 0, 0, 0, 0 };
+	struct av_decision avd;
 	int errsave, rc;
 
+	memset(&avd, 0, sizeof(avd));
+
 	rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, aeref, &avd);
 	errsave = errno;
 	avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata);
@@ -917,8 +921,8 @@ int avc_compute_create(security_id_t ssid,  security_id_t tsid,
 	rc = avc_lookup(ssid, tsid, tclass, 0, &aeref);
 	if (rc) {
 		/* need to make a cache entry for this tuple */
-		rc = security_compute_av_raw(ssid->ctx, tsid->ctx,
-					     tclass, 0, &entry.avd);
+		rc = security_compute_av_flags_raw(ssid->ctx, tsid->ctx,
+						   tclass, 0, &entry.avd);
 		if (rc)
 			goto out;
 		rc = avc_insert(ssid, tsid, tclass, &entry, &aeref);
diff --git a/libselinux/src/compute_av.c b/libselinux/src/compute_av.c
index 45cd0db..a821d17 100644
--- a/libselinux/src/compute_av.c
+++ b/libselinux/src/compute_av.c
@@ -10,10 +10,11 @@
 #include "policy.h"
 #include "mapping.h"
 
-int security_compute_av_raw(security_context_t scon,
-			    security_context_t tcon,
-			    security_class_t tclass,
-			    access_vector_t requested, struct av_decision *avd)
+int security_compute_av_flags_raw(security_context_t scon,
+				  security_context_t tcon,
+				  security_class_t tclass,
+				  access_vector_t requested,
+				  struct av_decision *avd)
 {
 	char path[PATH_MAX];
 	char *buf;
@@ -49,12 +50,15 @@ int security_compute_av_raw(security_context_t scon,
 	if (ret < 0)
 		goto out2;
 
-	if (sscanf(buf, "%x %x %x %x %u", &avd->allowed,
-		   &avd->decided, &avd->auditallow, &avd->auditdeny,
-		   &avd->seqno) != 5) {
+	ret = sscanf(buf, "%x %x %x %x %u %x",
+		     &avd->allowed, &avd->decided,
+		     &avd->auditallow, &avd->auditdeny,
+		     &avd->seqno, &avd->flags);
+	if (ret < 5) {
 		ret = -1;
 		goto out2;
-	}
+	} else if (ret < 6)
+		avd->flags = 0;
 
 	map_decision(tclass, avd);
 
@@ -66,16 +70,44 @@ int security_compute_av_raw(security_context_t scon,
 	return ret;
 }
 
-hidden_def(security_compute_av_raw)
+hidden_def(security_compute_av_flags_raw)
 
-int security_compute_av(security_context_t scon,
-			security_context_t tcon,
-			security_class_t tclass,
-			access_vector_t requested, struct av_decision *avd)
+int security_compute_av_raw(security_context_t scon,
+			    security_context_t tcon,
+			    security_class_t tclass,
+			    access_vector_t requested,
+			    struct av_decision *avd)
 {
+	struct av_decision lavd;
 	int ret;
+
+	ret = security_compute_av_flags_raw(scon, tcon, tclass,
+					    requested, &lavd);
+	if (ret == 0) {
+		avd->allowed = lavd.allowed;
+		avd->decided = lavd.decided;
+		avd->auditallow = lavd.auditallow;
+		avd->auditdeny = lavd.auditdeny;
+		avd->seqno = lavd.seqno;
+		/* NOTE:
+		 * We should not return avd->flags via the interface
+		 * due to the binary compatibility.
+		 */
+	}
+	return ret;
+}
+
+hidden_def(security_compute_av_raw)
+
+int security_compute_av_flags(security_context_t scon,
+			      security_context_t tcon,
+			      security_class_t tclass,
+			      access_vector_t requested,
+			      struct av_decision *avd)
+{
 	security_context_t rscon = scon;
 	security_context_t rtcon = tcon;
+	int ret;
 
 	if (selinux_trans_to_raw_context(scon, &rscon))
 		return -1;
@@ -83,8 +115,8 @@ int security_compute_av(security_context_t scon,
 		freecon(rscon);
 		return -1;
 	}
-
-	ret = security_compute_av_raw(rscon, rtcon, tclass, requested, avd);
+	ret = security_compute_av_flags_raw(rscon, rtcon, tclass,
+					    requested, avd);
 
 	freecon(rscon);
 	freecon(rtcon);
@@ -92,4 +124,32 @@ int security_compute_av(security_context_t scon,
 	return ret;
 }
 
+hidden_def(security_compute_av_flags)
+
+int security_compute_av(security_context_t scon,
+			security_context_t tcon,
+			security_class_t tclass,
+			access_vector_t requested, struct av_decision *avd)
+{
+	struct av_decision lavd;
+	int ret;
+
+	ret = security_compute_av_flags(scon, tcon, tclass,
+					requested, &lavd);
+	if (ret == 0)
+	{
+		avd->allowed = lavd.allowed;
+		avd->decided = lavd.decided;
+		avd->auditallow = lavd.auditallow;
+		avd->auditdeny = lavd.auditdeny;
+		avd->seqno = lavd.seqno;
+		/* NOTE:
+		 * We should not return avd->flags via the interface
+		 * due to the binary compatibility.
+		 */
+	}
+
+	return ret;
+}
+
 hidden_def(security_compute_av)
diff --git a/libselinux/src/selinux_internal.h b/libselinux/src/selinux_internal.h
index 8b4c6d4..cfb18a5 100644
--- a/libselinux/src/selinux_internal.h
+++ b/libselinux/src/selinux_internal.h
@@ -16,6 +16,8 @@ hidden_proto(selinux_mkload_policy)
     hidden_proto(security_canonicalize_context_raw)
     hidden_proto(security_compute_av)
     hidden_proto(security_compute_av_raw)
+    hidden_proto(security_compute_av_flags)
+    hidden_proto(security_compute_av_flags_raw)
     hidden_proto(security_compute_user)
     hidden_proto(security_compute_user_raw)
     hidden_proto(security_compute_create)

  reply	other threads:[~2009-04-01  1:41 UTC|newest]

Thread overview: 75+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-23 10:37 The status of SE-PostgreSQL KaiGai Kohei
2009-03-23 10:37 ` [refpolicy] " KaiGai Kohei
2009-03-23 14:56 ` Shaz
2009-03-23 14:57   ` Shaz
2009-03-23 15:19 ` Andy Warner
2009-03-24  2:14   ` KaiGai Kohei
2009-03-24  2:14     ` [refpolicy] " KaiGai Kohei
2009-03-25  6:54     ` Some ideas in SE-PostgreSQL enhancement (Re: The status of SE-PostgreSQL) KaiGai Kohei
2009-03-25  6:54       ` [refpolicy] " KaiGai Kohei
2009-03-25  7:45       ` Andy Warner
2009-03-25  8:20         ` KaiGai Kohei
2009-03-25  8:59           ` Andy Warner
2009-03-25 12:00             ` KaiGai Kohei
2009-03-25 17:02               ` Andy Warner
2009-03-26  0:13                 ` KaiGai Kohei
2009-03-25 17:43         ` Joshua Brindle
2009-03-25 19:42           ` Andy Warner
2009-03-27 15:43             ` Joshua Brindle
2009-03-27 16:25               ` Andy Warner
2009-03-27 17:15                 ` Joshua Brindle
2009-03-27 17:54                   ` Andy Warner
2009-03-27 18:12                     ` Joshua Brindle
2009-03-27 18:48                       ` Andy Warner
2009-03-27 19:53                         ` Joshua Brindle
2009-03-27 20:04                           ` Andy Warner
2009-03-27 23:59                           ` KaiGai Kohei
2009-03-28  7:17                             ` Andy Warner
2009-03-30  0:56                               ` KaiGai Kohei
2009-03-30  8:21                                 ` KaiGai Kohei
2009-03-30  9:58                                   ` Andy Warner
2009-03-30 13:22                                     ` KaiGai Kohei
2009-04-22  0:08                                   ` Eamon Walsh
2009-04-22  3:59                                     ` KaiGai Kohei
2009-05-01  4:54                                       ` Eamon Walsh
2009-05-07  1:34                                         ` KaiGai Kohei
2009-05-07  7:24                                           ` KaiGai Kohei
2009-03-30  9:49                                 ` Andy Warner
2009-03-26  5:50       ` [PATCH] Expose avc_netlink_loop() for applications (Re: Some ideas in SE-PostgreSQL enhancement) KaiGai Kohei
2009-03-26 23:28         ` Eamon Walsh
2009-03-26 23:41         ` Eamon Walsh
2009-03-27  0:35           ` KaiGai Kohei
2009-03-28  0:54             ` Eamon Walsh
2009-03-28  2:00               ` KaiGai Kohei
2009-03-30  4:56                 ` KaiGai Kohei
2009-03-26  6:11       ` [PATCH] database audit integration " KaiGai Kohei
2009-03-26  6:11         ` KaiGai Kohei
2009-03-26 21:45         ` John Dennis
     [not found]         ` <49CB313B.7020507@redhat.com>
2009-03-27  2:34           ` KaiGai Kohei
2009-03-27  2:34             ` KaiGai Kohei
2009-03-26  8:29       ` [PATCH] Permissive domain in userspace " KaiGai Kohei
2009-03-28  2:41         ` Eamon Walsh
2009-03-30  2:55           ` KaiGai Kohei
2009-03-31  1:45             ` KaiGai Kohei
2009-03-31 16:46               ` Stephen Smalley
2009-04-01  1:07                 ` [PATCH] Permissive domain in userspace object manager KaiGai Kohei
2009-04-01  1:41                   ` KaiGai Kohei [this message]
2009-04-01 12:34                   ` Stephen Smalley
2009-04-01 20:07                     ` Eric Paris
2009-04-01 22:53                   ` James Morris
2009-03-27  8:18       ` [PATCH] Policy rework for SE-PostgreSQL (Re: Some ideas in SE-PostgreSQL enhancement) KaiGai Kohei
2009-03-27  8:18         ` [refpolicy] " KaiGai Kohei
2009-03-27  9:44         ` Andy Warner
2009-03-27 11:20           ` KaiGai Kohei
2009-03-27 11:20             ` [refpolicy] " KaiGai Kohei
2009-03-27 11:45             ` Andy Warner
2009-03-27 11:45               ` [refpolicy] " Andy Warner
2009-03-27 12:17               ` KaiGai Kohei
2009-03-27 12:17                 ` [refpolicy] " KaiGai Kohei
2009-04-01  7:26       ` Correct manner to handler undefined classes/permissions? " KaiGai Kohei
2009-04-01 12:45         ` Stephen Smalley
2009-04-02  0:28           ` KaiGai Kohei
2009-03-23 15:25 ` The status of SE-PostgreSQL Stephen Smalley
2009-03-23 15:25   ` [refpolicy] " Stephen Smalley
2009-03-24  1:13   ` KaiGai Kohei
2009-03-24  1:13     ` [refpolicy] " KaiGai Kohei

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=49D2C633.3000406@ak.jp.nec.com \
    --to=kaigai@ak.jp.nec.com \
    --cc=eparis@parisplace.org \
    --cc=ewalsh@tycho.nsa.gov \
    --cc=jmorris@namei.org \
    --cc=method@manicmethod.com \
    --cc=sds@tycho.nsa.gov \
    --cc=selinux@tycho.nsa.gov \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.