Skip to contentSkip to conversation

SELinux: introduce permissive types

PATCH In review Eric Paris 3 participants 5 messages Mar 7, 2008 SELinux security module

lore
Share & tools
lore

Eric Paris

author
#0 lore raw

PATCH 1/1 SELinux: introduce permissive types

Introduce the concept of a permissive type. A new ebitmap is introduced to the policy database which indicates is a given type has the permissive bit set or not. This bit is tested for the scontext of any policy denial. Thus the bit if meaningless on types which only appear as the target of a decision (such such as typically a file type). A domain running with a permissive type will be allowed to perform any action similarly to when the system is globally set permissive.

When going through the kernel to find out where the scontext is not that of a domain I found FILESYSTEM__ASSOCIATE and any number of networking permissions. Can Paul or anyone comment on if the permissive bit on the scontext of the access decisions make sense? My understanding is that ?most?all? of these sids will naturally flow from the executing domain (and if people use set_socket_con they know enough to fix it themselves). So the permissive bit makes sense and should be allowed.

The permissive bit on a type used for files would allow it to associate with any FS. Is this an issue? Should I not check permissive on such operations?

If we do want further restrictions on what operations should be affected by the permissive bit and what should I believe just about anything is possible, but it starts getting unmaintainable pretty quickly. Maybe we just want to enforce convention in the toolchain that all types which are labeled permissive must have the 'domain' attribute or something like that. If you can load a policy with random bits set you win anyway so is kernel enforcement of permissive bits on non-domains an issue?

---

Testing basically subsisted of adding a new policy module which turned an existing type into a permissive type. In my case I made ntpd_t permissive and then ran programs as runcon -t ntpd_t 'script' We would get a log message only one time just like is seen with the global non-enforcing. Removing that policy module would reset the AVC and would subsequently deny the decision.

Patches for libsepol and checkpolicy will be forthcoming as soon as I get them cleaned up to the point where they don't look like I just threw up in the code base and out popped permissive domains.

 security/selinux/avc.c              |    9 ++++++++-
 security/selinux/include/security.h |    5 ++++-
 security/selinux/ss/policydb.c      |   11 +++++++++++
 security/selinux/ss/policydb.h      |    2 ++
 security/selinux/ss/services.c      |   15 +++++++++++++++
 5 files changed, 40 insertions(+), 2 deletions(-)
security/selinux/avc.c +8 -1
index 187964e..3eb5d69 100644
@@ -891,8 +891,15 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
 	denied = requested & ~(p_ae->avd.allowed);
 
 	if (!requested || denied) {
-		if (selinux_enforcing || (flags & AVC_STRICT))
+		if (flags & AVC_STRICT)
 			rc = -EACCES;
+		else if (selinux_enforcing)
+			if (unlikely(security_permissive_sid(ssid) &&
+				     requested && node))
+				avc_update_node(AVC_CALLBACK_GRANT,requested,
+						ssid,tsid,tclass);
+			else
+				rc = -EACCES;
 		else
 			if (node)
 				avc_update_node(AVC_CALLBACK_GRANT,requested,
security/selinux/include/security.h +4 -1
index f7d2f03..fde8690 100644
@@ -26,13 +26,14 @@
 #define POLICYDB_VERSION_AVTAB		20
 #define POLICYDB_VERSION_RANGETRANS	21
 #define POLICYDB_VERSION_POLCAP		22
+#define POLICYDB_VERSION_PERMISSIVE	23
 
 /* Range of policy versions we understand*/
 #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
 #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
 #define POLICYDB_VERSION_MAX	CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
 #else
-#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_POLCAP
+#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_PERMISSIVE
 #endif
 
 #define CONTEXT_MNT	0x01
@@ -67,6 +68,8 @@ struct av_decision {
 	u32 seqno;
 };
 
+int security_permissive_sid(u32 sid);
+
 int security_compute_av(u32 ssid, u32 tsid,
 	u16 tclass, u32 requested,
 	struct av_decision *avd);
security/selinux/ss/policydb.c +11 -0
index bd7d6a0..84dbab9 100644
@@ -111,6 +111,11 @@ static struct policydb_compat_info policydb_compat[] = {
 		.version	= POLICYDB_VERSION_POLCAP,
 		.sym_num	= SYM_NUM,
 		.ocon_num	= OCON_NUM,
+	},
+	{
+		.version	= POLICYDB_VERSION_PERMISSIVE,
+		.sym_num	= SYM_NUM,
+		.ocon_num	= OCON_NUM,
 	}
 };
 
@@ -194,6 +199,7 @@ static int policydb_init(struct policydb *p)
 		goto out_free_symtab;
 
 	ebitmap_init(&p->policycaps);
+	ebitmap_init(&p->permissive_map);
 
 out:
 	return rc;
@@ -687,6 +693,7 @@ void policydb_destroy(struct policydb *p)
 	kfree(p->type_attr_map);
 	kfree(p->undefined_perms);
 	ebitmap_destroy(&p->policycaps);
+	ebitmap_destroy(&p->permissive_map);
 
 	return;
 }
@@ -1570,6 +1577,10 @@ int policydb_read(struct policydb *p, void *fp)
 	    ebitmap_read(&p->policycaps, fp) != 0)
 		goto bad;
 
+	if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE &&
+	    ebitmap_read(&p->permissive_map, fp) != 0)
+		goto bad;
+
 	info = policydb_lookup_compat(p->policyvers);
 	if (!info) {
 		printk(KERN_ERR "security:  unable to find policy compat info "
security/selinux/ss/policydb.h +2 -0
index c4ce996..ba593a3 100644
@@ -243,6 +243,8 @@ struct policydb {
 
 	struct ebitmap policycaps;
 
+	struct ebitmap permissive_map;
+
 	unsigned int policyvers;
 
 	unsigned int reject_unknown : 1;
security/selinux/ss/services.c +15 -0
index f374186..97b4453 100644
@@ -416,6 +416,21 @@ inval_class:
 	return -EINVAL;
 }
 
+/*
+ * Given a sid find if the type has the permissive flag set
+ */
+int security_permissive_sid(u32 sid)
+{
+	struct context *context;
+	u32 type;
+
+	context = sidtab_search(&sidtab, sid);
+	BUG_ON(!context);
+
+	type = context->type;
+	return ebitmap_get_bit(&policydb.permissive_map, type);
+}
+
 static int security_validtrans_handle_fail(struct context *ocontext,
                                            struct context *ncontext,
                                            struct context *tcontext,

--
This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.

#1 lore raw
Quoted 16 lines · Eric Paris

Introduce the concept of a permissive type. A new ebitmap is introduced to the policy database which indicates is a given type has the permissive bit set or not. This bit is tested for the scontext of any policy denial. Thus the bit if meaningless on types which only appear as the target of a decision (such such as typically a file type). A domain running with a permissive type will be allowed to perform any action similarly to when the system is globally set permissive.

When going through the kernel to find out where the scontext is not that of a domain I found FILESYSTEM__ASSOCIATE and any number of networking permissions. Can Paul or anyone comment on if the permissive bit on the scontext of the access decisions make sense? My understanding is that ?most?all? of these sids will naturally flow from the executing domain (and if people use set_socket_con they know enough to fix it themselves). So the permissive bit makes sense and should be allowed.

Quoted 3 lines

The permissive bit on a type used for files would allow it to associate with any FS. Is this an issue? Should I not check permissive on such operations?

I don't see that as an issue.

Quoted 7 lines

If we do want further restrictions on what operations should be affected by the permissive bit and what should I believe just about anything is possible, but it starts getting unmaintainable pretty quickly. Maybe we just want to enforce convention in the toolchain that all types which are labeled permissive must have the 'domain' attribute or something like that. If you can load a policy with random bits set you win anyway so is kernel enforcement of permissive bits on non-domains an issue?

I agree that we don't want to go down the road of distinguishing what operations can be affected by the permissive bit. If we find any check that is fundamentally unsafe in the presence of this bit, then I'd argue we should change the check.

Quoted 34 lines

---

Testing basically subsisted of adding a new policy module which turned an existing type into a permissive type. In my case I made ntpd_t permissive and then ran programs as runcon -t ntpd_t 'script' We would get a log message only one time just like is seen with the global non-enforcing. Removing that policy module would reset the AVC and would subsequently deny the decision.

Patches for libsepol and checkpolicy will be forthcoming as soon as I get them cleaned up to the point where they don't look like I just threw up in the code base and out popped permissive domains.

 security/selinux/avc.c              |    9 ++++++++-
 security/selinux/include/security.h |    5 ++++-
 security/selinux/ss/policydb.c      |   11 +++++++++++
 security/selinux/ss/policydb.h      |    2 ++
 security/selinux/ss/services.c      |   15 +++++++++++++++
 5 files changed, 40 insertions(+), 2 deletions(-)
security/selinux/avc.c +1 -1
index 187964e..3eb5d69 100644
@@ -891,8 +891,15 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
 	denied = requested & ~(p_ae->avd.allowed);
 
 	if (!requested || denied) {
-		if (selinux_enforcing || (flags & AVC_STRICT))
+		if (flags & AVC_STRICT)
 			rc = -EACCES;

security/selinux/avc.c int avc_has_perm_noaudit(u32 ssid, u32 tsid, · line 905

Quoted 10 lines
security/selinux/avc.c +7 -0
+		else if (selinux_enforcing)
+			if (unlikely(security_permissive_sid(ssid) &&
+				     requested && node))
+				avc_update_node(AVC_CALLBACK_GRANT,requested,
+						ssid,tsid,tclass);
+			else
+				rc = -EACCES;
 		else
 			if (node)
 				avc_update_node(AVC_CALLBACK_GRANT,requested,

Can you unify the branches above so only one avc_update_node() call is present?

Quoted 96 lines
security/selinux/include/security.h +4 -1
index f7d2f03..fde8690 100644
@@ -26,13 +26,14 @@
 #define POLICYDB_VERSION_AVTAB		20
 #define POLICYDB_VERSION_RANGETRANS	21
 #define POLICYDB_VERSION_POLCAP		22
+#define POLICYDB_VERSION_PERMISSIVE	23
 
 /* Range of policy versions we understand*/
 #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
 #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
 #define POLICYDB_VERSION_MAX	CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
 #else
-#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_POLCAP
+#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_PERMISSIVE
 #endif
 
 #define CONTEXT_MNT	0x01
@@ -67,6 +68,8 @@ struct av_decision {
 	u32 seqno;
 };
 
+int security_permissive_sid(u32 sid);
+
 int security_compute_av(u32 ssid, u32 tsid,
 	u16 tclass, u32 requested,
 	struct av_decision *avd);
security/selinux/ss/policydb.c +11 -0
index bd7d6a0..84dbab9 100644
@@ -111,6 +111,11 @@ static struct policydb_compat_info policydb_compat[] = {
 		.version	= POLICYDB_VERSION_POLCAP,
 		.sym_num	= SYM_NUM,
 		.ocon_num	= OCON_NUM,
+	},
+	{
+		.version	= POLICYDB_VERSION_PERMISSIVE,
+		.sym_num	= SYM_NUM,
+		.ocon_num	= OCON_NUM,
 	}
 };
 
@@ -194,6 +199,7 @@ static int policydb_init(struct policydb *p)
 		goto out_free_symtab;
 
 	ebitmap_init(&p->policycaps);
+	ebitmap_init(&p->permissive_map);
 
 out:
 	return rc;
@@ -687,6 +693,7 @@ void policydb_destroy(struct policydb *p)
 	kfree(p->type_attr_map);
 	kfree(p->undefined_perms);
 	ebitmap_destroy(&p->policycaps);
+	ebitmap_destroy(&p->permissive_map);
 
 	return;
 }
@@ -1570,6 +1577,10 @@ int policydb_read(struct policydb *p, void *fp)
 	    ebitmap_read(&p->policycaps, fp) != 0)
 		goto bad;
 
+	if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE &&
+	    ebitmap_read(&p->permissive_map, fp) != 0)
+		goto bad;
+
 	info = policydb_lookup_compat(p->policyvers);
 	if (!info) {
 		printk(KERN_ERR "security:  unable to find policy compat info "
security/selinux/ss/policydb.h +2 -0
index c4ce996..ba593a3 100644
@@ -243,6 +243,8 @@ struct policydb {
 
 	struct ebitmap policycaps;
 
+	struct ebitmap permissive_map;
+
 	unsigned int policyvers;
 
 	unsigned int reject_unknown : 1;
security/selinux/ss/services.c +3 -0
index f374186..97b4453 100644
@@ -416,6 +416,21 @@ inval_class:
 	return -EINVAL;
 }
 
+/*
+ * Given a sid find if the type has the permissive flag set
+ */

security/selinux/ss/services.c inval_class: · line 431

Quoted 10 lines
security/selinux/ss/services.c +10 -0
+int security_permissive_sid(u32 sid)
+{
+	struct context *context;
+	u32 type;
+
+	context = sidtab_search(&sidtab, sid);
+	BUG_ON(!context);
+
+	type = context->type;
+	return ebitmap_get_bit(&policydb.permissive_map, type);

This all needs to happen under policy rdlock - take it before looking up in the sidtab and release after ebitmap_get_bit (so you have to save result to temporary var and return that). Otherwise, it can get freed under you by policy reload.

Quoted 12 lines
security/selinux/ss/services.c +2 -1
+}
+
 static int security_validtrans_handle_fail(struct context *ocontext,
                                            struct context *ncontext,
                                            struct context *tcontext,
 
 
 
--

This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.

Signature · 8 lines
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to [email protected] with
the words "unsubscribe selinux" without quotes as the message.
author
#2 lore raw
Quoted 18 lines · Stephen Smalley
Quoted 16 lines · Eric Paris
security/selinux/avc.c +6 -1
index 187964e..3eb5d69 100644
@@ -891,8 +891,15 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
 	denied = requested & ~(p_ae->avd.allowed);
 
 	if (!requested || denied) {
-		if (selinux_enforcing || (flags & AVC_STRICT))
+		if (flags & AVC_STRICT)
 			rc = -EACCES;
+		else if (selinux_enforcing)
+			if (unlikely(security_permissive_sid(ssid) &&
+				     requested && node))
+				avc_update_node(AVC_CALLBACK_GRANT,requested,
+						ssid,tsid,tclass);
Quoted 8 lines

security/selinux/avc.c int avc_has_perm_noaudit(u32 ssid, u32 tsid, · line 905

Quoted 5 lines
security/selinux/avc.c +2 -0
+			else
+				rc = -EACCES;
 		else
 			if (node)
 				avc_update_node(AVC_CALLBACK_GRANT,requested,

Can you unify the branches above so only one avc_update_node() call is present?

Yeah, I'm sure I can come up with something.

else if (!selinux_enforcing ||

	 (unlikely(security_permissive_sid(ssid)) && requested && node))
	avc_update_node(AVC_CALLBACK_GRANT.....
else
	rc = -EACCES;
Quoted 2 lines

security/selinux/avc.c

Quoted 2 lines
security/selinux/avc.c +1 -1
-#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_POLCAP
+#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_PERMISSIVE

Will make a similar change in Kconfig

Quoted 18 lines
Quoted 18 lines
security/selinux/ss/services.c +10 -0
index f374186..97b4453 100644
@@ -416,6 +416,21 @@ inval_class:
 	return -EINVAL;
 }
 
+/*
+ * Given a sid find if the type has the permissive flag set
+ */
+int security_permissive_sid(u32 sid)
+{
+	struct context *context;
+	u32 type;
+
+	context = sidtab_search(&sidtab, sid);
+	BUG_ON(!context);
Quoted 8 lines

security/selinux/ss/services.c inval_class: · line 431

Quoted 3 lines
security/selinux/ss/services.c +3 -0
+
+	type = context->type;
+	return ebitmap_get_bit(&policydb.permissive_map, type);

This all needs to happen under policy rdlock - take it before looking up in the sidtab and release after ebitmap_get_bit (so you have to save result to temporary var and return that). Otherwise, it can get freed under you by policy reload.

Do I only need to worry about it freeing under me or should I also worry about atomicity from security_compute_av() ? Do I really have any guarantee that sid is still in the sidtab here? My BUG_ON() might be bogus, right? Should I move the permissive bit check into security_compute_av() and carry about the bit in the avd_decision? Is doing an ebitmap_get too high of a penalty to pay for all access as opposed to this way which only does it for denials? If we don't want the penalty on successful permission requests I can just drop the BUG_ON() and not worry about things changing under us....

-Eric

--
This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.

#3 lore raw
Quoted 70 lines · Eric Paris
Quoted 18 lines · Stephen Smalley
Quoted 16 lines · Eric Paris
security/selinux/avc.c +6 -1
index 187964e..3eb5d69 100644
@@ -891,8 +891,15 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
 	denied = requested & ~(p_ae->avd.allowed);
 
 	if (!requested || denied) {
-		if (selinux_enforcing || (flags & AVC_STRICT))
+		if (flags & AVC_STRICT)
 			rc = -EACCES;
+		else if (selinux_enforcing)
+			if (unlikely(security_permissive_sid(ssid) &&
+				     requested && node))
+				avc_update_node(AVC_CALLBACK_GRANT,requested,
+						ssid,tsid,tclass);
Quoted 8 lines

security/selinux/avc.c int avc_has_perm_noaudit(u32 ssid, u32 tsid, · line 905

Quoted 5 lines
security/selinux/avc.c +2 -0
+			else
+				rc = -EACCES;
 		else
 			if (node)
 				avc_update_node(AVC_CALLBACK_GRANT,requested,

Can you unify the branches above so only one avc_update_node() call is present?

Yeah, I'm sure I can come up with something.

else if (!selinux_enforcing ||

	 (unlikely(security_permissive_sid(ssid)) && requested && node))
	avc_update_node(AVC_CALLBACK_GRANT.....
else
	rc = -EACCES;
Quoted 2 lines

security/selinux/avc.c

Quoted 2 lines
security/selinux/avc.c +1 -1
-#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_POLCAP
+#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_PERMISSIVE

Will make a similar change in Kconfig

Quoted 18 lines
Quoted 18 lines
security/selinux/ss/services.c +10 -0
index f374186..97b4453 100644
@@ -416,6 +416,21 @@ inval_class:
 	return -EINVAL;
 }
 
+/*
+ * Given a sid find if the type has the permissive flag set
+ */
+int security_permissive_sid(u32 sid)
+{
+	struct context *context;
+	u32 type;
+
+	context = sidtab_search(&sidtab, sid);
+	BUG_ON(!context);
Quoted 8 lines

security/selinux/ss/services.c inval_class: · line 431

Quoted 3 lines
security/selinux/ss/services.c +3 -0
+
+	type = context->type;
+	return ebitmap_get_bit(&policydb.permissive_map, type);

This all needs to happen under policy rdlock - take it before looking up in the sidtab and release after ebitmap_get_bit (so you have to save result to temporary var and return that). Otherwise, it can get freed under you by policy reload.

Quoted 2 lines

Do I only need to worry about it freeing under me or should I also worry about atomicity from security_compute_av() ?

Well, that's a separate issue. Interesting to be sure, but separate.

Quoted 3 lines

Do I really have any
guarantee that sid is still in the sidtab here? My BUG_ON() might be bogus, right?

Not really. sidtab_search was changed long ago to remap undefined SIDs to the unlabeled SID.

Quoted 2 lines

Should I move the permissive bit check into
security_compute_av() and carry about the bit in the avd_decision?

Yuck.

Quoted 3 lines

Is
doing an ebitmap_get too high of a penalty to pay for all access as opposed to this way which only does it for denials?

Not too heavy for compute_av (happens in constraint eval), but too heavy for the AVC. But I'm not sure we need it.

Quoted 3 lines

If we don't want
the penalty on successful permission requests I can just drop the BUG_ON() and not worry about things changing under us....

Signature · 8 lines
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to [email protected] with
the words "unsubscribe selinux" without quotes as the message.
#4 lore raw
In reply to Eric Paris
Quoted 9 lines · Eric Paris

Introduce the concept of a permissive type. A new ebitmap is introduced to the policy database which indicates is a given type has the permissive bit set or not. This bit is tested for the scontext of any policy denial. Thus the bit if meaningless on types which only appear as the target of a decision (such such as typically a file type). A domain running with a permissive type will be allowed to perform any action similarly to when the system is globally set permissive.

Quoted 8 lines

When going through the kernel to find out where the scontext is not that of a domain I found FILESYSTEM__ASSOCIATE and any number of networking permissions. Can Paul or anyone comment on if the permissive bit on the scontext of the access decisions make sense? My understanding is that ?most?all? of these sids will naturally flow from the executing domain (and if people use set_socket_con they know enough to fix it themselves). So the permissive bit makes sense and should be allowed.

You should only see domains used as objects in some of the networking controls and not types used as subjects (is a packet an object or no?) so I think you are okay here.

Quoted 24 lines

The permissive bit on a type used for files would allow it to associate with any FS. Is this an issue? Should I not check permissive on such operations?

If we do want further restrictions on what operations should be affected by the permissive bit and what should I believe just about anything is possible, but it starts getting unmaintainable pretty quickly. Maybe we just want to enforce convention in the toolchain that all types which are labeled permissive must have the 'domain' attribute or something like that. If you can load a policy with random bits set you win anyway so is kernel enforcement of permissive bits on non-domains an issue?

---

Testing basically subsisted of adding a new policy module which turned an existing type into a permissive type. In my case I made ntpd_t permissive and then ran programs as runcon -t ntpd_t 'script' We would get a log message only one time just like is seen with the global non-enforcing. Removing that policy module would reset the AVC and would subsequently deny the decision.

Quoted 3 lines

Patches for libsepol and checkpolicy will be forthcoming as soon as I get them cleaned up to the point where they don't look like I just threw up in the code base and out popped permissive domains.

The secrets of SELinux tool development revealed!

;)

Quoted 7 lines
 security/selinux/avc.c              |    9 ++++++++-
 security/selinux/include/security.h |    5 ++++-
 security/selinux/ss/policydb.c      |   11 +++++++++++
 security/selinux/ss/policydb.h      |    2 ++
 security/selinux/ss/services.c      |   15 +++++++++++++++
 5 files changed, 40 insertions(+), 2 deletions(-)

...

Quoted 14 lines
security/selinux/include/security.h +1 -0
@@ -26,13 +26,14 @@
 #define POLICYDB_VERSION_AVTAB		20
 #define POLICYDB_VERSION_RANGETRANS	21
 #define POLICYDB_VERSION_POLCAP		22
+#define POLICYDB_VERSION_PERMISSIVE	23
 
 /* Range of policy versions we understand*/
 #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
 #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
 #define

POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VAL
UE #else

security/selinux/include/security.h line 37

Quoted 3 lines
security/selinux/include/security.h +1 -1
-#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_POLCAP
+#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_PERMISSIVE
 #endif

I believe you need to update the Kconfig maximum policy version too.

Quoted 12 lines
(quoted diff) +0 -0

b/security/selinux/ss/services.c index f374186..97b4453 100644

security/selinux/ss/services.c +4 -0
@@ -416,6 +416,21 @@ inval_class:
 	return -EINVAL;
 }
 
+/*
+ * Given a sid find if the type has the permissive flag set
+ */
+int security_permissive_sid(u32 sid)

security/selinux/ss/services.c inval_class: · line 432

Quoted 10 lines
security/selinux/ss/services.c +10 -0
+{
+	struct context *context;
+	u32 type;
+
+	context = sidtab_search(&sidtab, sid);
+	BUG_ON(!context);
+
+	type = context->type;
+	return ebitmap_get_bit(&policydb.permissive_map, type);
+}

I'm almost certain you need to do this wrapped with POLICY_RDLOCK and POLICY_RDUNLOCK.

Signature · 7 lines
paul moore
linux security @ hp

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to [email protected] with
the words "unsubscribe selinux" without quotes as the message.