All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
@ 2010-01-31 22:43 Guido Trentalancia
  2010-02-01 15:28 ` Stephen Smalley
  2010-02-01 18:16 ` Stephen Smalley
  0 siblings, 2 replies; 33+ messages in thread
From: Guido Trentalancia @ 2010-01-31 22:43 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: selinux, eparis, jmorris


[-- Attachment #1.1: Type: text/plain, Size: 32781 bytes --]

Dear Stephen,

I have created the patch for allowing runtime switch between different policy types, according to your advice and previous discussions on this mailing list. The patch obsoletes the small piece of documentation that I wrote a few days ago to help new users cope with the limitation.

I would be very grateful if you could review the patch so that, as soon as it is reviewed, it can be posted to the kernel mailing list. I have done some basic testing and it works on one of my systems, although sometimes I get the following side-effect:

/dev/pts/0 changed labels.
Unable to restore tty label...

which however doesn't affect the system. I am not sure where that comes from (perhaps bash)...

Regards,

Guido Trentalancia

Author: Guido Trentalancia <guido@trentalancia.com>
Date:   Sun Jan 31 22:10:22 2010 +0100

    Allow runtime switching between different policy types (e.g. from a MLS/MCS
    policy to a non-MLS/non-MCS policy or viceversa).

    Signed-off-by: Guido Trentalancia <guido@trentalancia.com>

diff -pruN security-testing-2.6/security/selinux/Makefile security-testing-2.6-new/security/selinux/Makefile
--- security-testing-2.6/security/selinux/Makefile	2010-01-29 01:06:42.132070393 +0100
+++ security-testing-2.6-new/security/selinux/Makefile	2010-01-29 02:13:42.497044862 +0100
@@ -18,7 +18,7 @@ selinux-$(CONFIG_SECURITY_NETWORK_XFRM)

 selinux-$(CONFIG_NETLABEL) += netlabel.o

-EXTRA_CFLAGS += -Isecurity/selinux -Isecurity/selinux/include
+EXTRA_CFLAGS += -Isecurity/selinux -Isecurity/selinux/ss -Isecurity/selinux/include

 $(obj)/avc.o: $(obj)/flask.h

diff -pruN security-testing-2.6/security/selinux/include/security.h security-testing-2.6-new/security/selinux/include/security.h
--- security-testing-2.6/security/selinux/include/security.h	2010-01-29 02:02:47.737045258 +0100
+++ security-testing-2.6-new/security/selinux/include/security.h	2010-01-29 02:13:59.641064788 +0100
@@ -57,7 +57,6 @@
 struct netlbl_lsm_secattr;

 extern int selinux_enabled;
-extern int selinux_mls_enabled;

 /* Policy capabilities */
 enum {
diff -pruN security-testing-2.6/security/selinux/selinuxfs.c security-testing-2.6-new/security/selinux/selinuxfs.c
--- security-testing-2.6/security/selinux/selinuxfs.c	2010-01-29 02:02:47.738046835 +0100
+++ security-testing-2.6-new/security/selinux/selinuxfs.c	2010-01-31 23:17:44.494329730 +0100
@@ -38,6 +38,10 @@
 #include "security.h"
 #include "objsec.h"
 #include "conditional.h"
+#include "services.h"
+#include "policydb.h"
+
+extern struct policydb policydb;

 /* Policy capability filenames */
 static char *policycap_names[] = {
@@ -282,7 +286,8 @@ static ssize_t sel_read_mls(struct file
 	char tmpbuf[TMPBUFLEN];
 	ssize_t length;

-	length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_mls_enabled);
+	length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
+		policydb.selinux_mls_enabled);
 	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
 }

diff -pruN security-testing-2.6/security/selinux/ss/Makefile security-testing-2.6-new/security/selinux/ss/Makefile
--- security-testing-2.6/security/selinux/ss/Makefile	2010-01-29 01:06:42.157062028 +0100
+++ security-testing-2.6-new/security/selinux/ss/Makefile	2010-01-29 02:15:52.319045091 +0100
@@ -5,5 +5,5 @@
 EXTRA_CFLAGS += -Isecurity/selinux -Isecurity/selinux/include
 obj-y := ss.o

-ss-y := ebitmap.o hashtab.o symtab.o sidtab.o avtab.o policydb.o services.o conditional.o mls.o
+ss-y := context.o ebitmap.o hashtab.o symtab.o sidtab.o avtab.o policydb.o services.o conditional.o mls.o mls_types.o

diff -pruN security-testing-2.6/security/selinux/ss/context.c security-testing-2.6-new/security/selinux/ss/context.c
--- security-testing-2.6/security/selinux/ss/context.c	1970-01-01 01:00:00.000000000 +0100
+++ security-testing-2.6-new/security/selinux/ss/context.c	2010-01-31 21:39:01.293500739 +0100
@@ -0,0 +1,131 @@
+/*
+ * Security context auxiliary functions
+ *
+ * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
+ */
+
+#include "context.h"
+#include "ebitmap.h"
+#include "mls_types.h"
+#include "security.h"
+#include "policydb.h"
+
+inline void mls_context_init(struct context *c)
+{
+	memset(&c->range, 0, sizeof(c->range));
+}
+
+inline int mls_context_cpy(struct context *dst, struct context *src)
+{
+	int rc;
+
+	if (!policydb.selinux_mls_enabled)
+		return 0;
+
+	dst->range.level[0].sens = src->range.level[0].sens;
+	rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
+	if (rc)
+		goto out;
+
+	dst->range.level[1].sens = src->range.level[1].sens;
+	rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[1].cat);
+	if (rc)
+		ebitmap_destroy(&dst->range.level[0].cat);
+out:
+	return rc;
+}
+
+/*
+ * Sets both levels in the MLS range of 'dst' to the low level of 'src'.
+ */
+inline int mls_context_cpy_low(struct context *dst, struct context *src)
+{
+	int rc;
+
+	if (!policydb.selinux_mls_enabled)
+		return 0;
+
+	dst->range.level[0].sens = src->range.level[0].sens;
+	rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
+	if (rc)
+		goto out;
+
+	dst->range.level[1].sens = src->range.level[0].sens;
+	rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[0].cat);
+	if (rc)
+		ebitmap_destroy(&dst->range.level[0].cat);
+out:
+	return rc;
+}
+
+inline int mls_context_cmp(struct context *c1, struct context *c2)
+{
+	if (!policydb.selinux_mls_enabled)
+		return 1;
+
+	return c1->range.level[0].sens == c2->range.level[0].sens &&
+		ebitmap_cmp(&c1->range.level[0].cat, &c2->range.level[0].cat) &&
+		c1->range.level[1].sens == c2->range.level[1].sens &&
+		ebitmap_cmp(&c1->range.level[1].cat, &c2->range.level[1].cat);
+}
+
+inline void mls_context_destroy(struct policydb *p, struct context *c)
+{
+	if (!p->selinux_mls_enabled)
+		return;
+
+	ebitmap_destroy(&c->range.level[0].cat);
+	ebitmap_destroy(&c->range.level[1].cat);
+	mls_context_init(c);
+}
+
+inline void context_init(struct context *c)
+{
+	memset(c, 0, sizeof(*c));
+}
+
+inline int context_cpy(struct context *dst, struct context *src)
+{
+	int rc;
+
+	dst->user = src->user;
+	dst->role = src->role;
+	dst->type = src->type;
+	if (src->str) {
+		dst->str = kstrdup(src->str, GFP_ATOMIC);
+		if (!dst->str)
+			return -ENOMEM;
+		dst->len = src->len;
+	} else {
+		dst->str = NULL;
+		dst->len = 0;
+	}
+	rc = mls_context_cpy(dst, src);
+	if (rc) {
+		kfree(dst->str);
+		return rc;
+	}
+	return 0;
+}
+
+inline void context_destroy(struct policydb *p, struct context *c)
+{
+	c->user = c->role = c->type = 0;
+	kfree(c->str);
+	c->str = NULL;
+	c->len = 0;
+	mls_context_destroy(p, c);
+}
+
+inline int context_cmp(struct context *c1, struct context *c2)
+{
+	if (c1->len && c2->len)
+		return (c1->len == c2->len && !strcmp(c1->str, c2->str));
+	if (c1->len || c2->len)
+		return 0;
+	return ((c1->user == c2->user) &&
+		(c1->role == c2->role) &&
+		(c1->type == c2->type) &&
+		mls_context_cmp(c1, c2));
+}
+
diff -pruN security-testing-2.6/security/selinux/ss/context.h security-testing-2.6-new/security/selinux/ss/context.h
--- security-testing-2.6/security/selinux/ss/context.h	2010-01-29 01:06:42.160060332 +0100
+++ security-testing-2.6-new/security/selinux/ss/context.h	2010-01-31 21:38:06.517349464 +0100
@@ -12,6 +12,7 @@
  *
  * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
  */
+
 #ifndef _SS_CONTEXT_H_
 #define _SS_CONTEXT_H_

@@ -19,6 +20,8 @@
 #include "mls_types.h"
 #include "security.h"

+extern struct policydb policydb;
+
 /*
  * A security context consists of an authenticated user
  * identity, a role, a type and a MLS range.
@@ -32,124 +35,15 @@ struct context {
 	char *str;	/* string representation if context cannot be mapped. */
 };

-static inline void mls_context_init(struct context *c)
-{
-	memset(&c->range, 0, sizeof(c->range));
-}
-
-static inline int mls_context_cpy(struct context *dst, struct context *src)
-{
-	int rc;
-
-	if (!selinux_mls_enabled)
-		return 0;
-
-	dst->range.level[0].sens = src->range.level[0].sens;
-	rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
-	if (rc)
-		goto out;
-
-	dst->range.level[1].sens = src->range.level[1].sens;
-	rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[1].cat);
-	if (rc)
-		ebitmap_destroy(&dst->range.level[0].cat);
-out:
-	return rc;
-}
-
-/*
- * Sets both levels in the MLS range of 'dst' to the low level of 'src'.
- */
-static inline int mls_context_cpy_low(struct context *dst, struct context *src)
-{
-	int rc;
-
-	if (!selinux_mls_enabled)
-		return 0;
-
-	dst->range.level[0].sens = src->range.level[0].sens;
-	rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
-	if (rc)
-		goto out;
-
-	dst->range.level[1].sens = src->range.level[0].sens;
-	rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[0].cat);
-	if (rc)
-		ebitmap_destroy(&dst->range.level[0].cat);
-out:
-	return rc;
-}
-
-static inline int mls_context_cmp(struct context *c1, struct context *c2)
-{
-	if (!selinux_mls_enabled)
-		return 1;
-
-	return ((c1->range.level[0].sens == c2->range.level[0].sens) &&
-		ebitmap_cmp(&c1->range.level[0].cat, &c2->range.level[0].cat) &&
-		(c1->range.level[1].sens == c2->range.level[1].sens) &&
-		ebitmap_cmp(&c1->range.level[1].cat, &c2->range.level[1].cat));
-}
-
-static inline void mls_context_destroy(struct context *c)
-{
-	if (!selinux_mls_enabled)
-		return;
-
-	ebitmap_destroy(&c->range.level[0].cat);
-	ebitmap_destroy(&c->range.level[1].cat);
-	mls_context_init(c);
-}
-
-static inline void context_init(struct context *c)
-{
-	memset(c, 0, sizeof(*c));
-}
-
-static inline int context_cpy(struct context *dst, struct context *src)
-{
-	int rc;
-
-	dst->user = src->user;
-	dst->role = src->role;
-	dst->type = src->type;
-	if (src->str) {
-		dst->str = kstrdup(src->str, GFP_ATOMIC);
-		if (!dst->str)
-			return -ENOMEM;
-		dst->len = src->len;
-	} else {
-		dst->str = NULL;
-		dst->len = 0;
-	}
-	rc = mls_context_cpy(dst, src);
-	if (rc) {
-		kfree(dst->str);
-		return rc;
-	}
-	return 0;
-}
-
-static inline void context_destroy(struct context *c)
-{
-	c->user = c->role = c->type = 0;
-	kfree(c->str);
-	c->str = NULL;
-	c->len = 0;
-	mls_context_destroy(c);
-}
-
-static inline int context_cmp(struct context *c1, struct context *c2)
-{
-	if (c1->len && c2->len)
-		return (c1->len == c2->len && !strcmp(c1->str, c2->str));
-	if (c1->len || c2->len)
-		return 0;
-	return ((c1->user == c2->user) &&
-		(c1->role == c2->role) &&
-		(c1->type == c2->type) &&
-		mls_context_cmp(c1, c2));
-}
+inline void mls_context_init(struct context *c);
+inline int mls_context_cpy(struct context *dst, struct context *src);
+inline int mls_context_cpy_low(struct context *dst, struct context *src);
+inline int mls_context_cmp(struct context *c1, struct context *c2);
+inline void mls_context_destroy(struct policydb *p, struct context *c);
+inline void context_init(struct context *c);
+inline int context_cpy(struct context *dst, struct context *src);
+inline void context_destroy(struct policydb *p, struct context *c);
+inline int context_cmp(struct context *c1, struct context *c2);

 #endif	/* _SS_CONTEXT_H_ */

diff -pruN security-testing-2.6/security/selinux/ss/mls.c security-testing-2.6-new/security/selinux/ss/mls.c
--- security-testing-2.6/security/selinux/ss/mls.c	2010-01-29 02:02:47.739046177 +0100
+++ security-testing-2.6-new/security/selinux/ss/mls.c	2010-01-31 21:49:38.704348310 +0100
@@ -39,7 +39,7 @@ int mls_compute_context_len(struct conte
 	struct ebitmap *e;
 	struct ebitmap_node *node;

-	if (!selinux_mls_enabled)
+	if (!policydb.selinux_mls_enabled)
 		return 0;

 	len = 1; /* for the beginning ":" */
@@ -93,7 +93,7 @@ void mls_sid_to_context(struct context *
 	struct ebitmap *e;
 	struct ebitmap_node *node;

-	if (!selinux_mls_enabled)
+	if (!policydb.selinux_mls_enabled)
 		return;

 	scontextp = *scontext;
@@ -200,7 +200,7 @@ int mls_context_isvalid(struct policydb
 {
 	struct user_datum *usrdatum;

-	if (!selinux_mls_enabled)
+	if (!p->selinux_mls_enabled)
 		return 1;

 	if (!mls_range_isvalid(p, &c->range))
@@ -253,7 +253,7 @@ int mls_context_to_sid(struct policydb *
 	struct cat_datum *catdatum, *rngdatum;
 	int l, rc = -EINVAL;

-	if (!selinux_mls_enabled) {
+	if (!pol->selinux_mls_enabled) {
 		if (def_sid != SECSID_NULL && oldc)
 			*scontext += strlen(*scontext)+1;
 		return 0;
@@ -387,7 +387,7 @@ int mls_from_string(char *str, struct co
 	char *tmpstr, *freestr;
 	int rc;

-	if (!selinux_mls_enabled)
+	if (!policydb.selinux_mls_enabled)
 		return -EINVAL;

 	/* we need freestr because mls_context_to_sid will change
@@ -407,7 +407,7 @@ int mls_from_string(char *str, struct co
 /*
  * Copies the MLS range `range' into `context'.
  */
-static inline int mls_range_set(struct context *context,
+inline int mls_range_set(struct context *context,
 				struct mls_range *range)
 {
 	int l, rc = 0;
@@ -427,7 +427,7 @@ static inline int mls_range_set(struct c
 int mls_setup_user_range(struct context *fromcon, struct user_datum *user,
 			 struct context *usercon)
 {
-	if (selinux_mls_enabled) {
+	if (policydb.selinux_mls_enabled) {
 		struct mls_level *fromcon_sen = &(fromcon->range.level[0]);
 		struct mls_level *fromcon_clr = &(fromcon->range.level[1]);
 		struct mls_level *user_low = &(user->range.level[0]);
@@ -477,7 +477,7 @@ int mls_convert_context(struct policydb
 	struct ebitmap_node *node;
 	int l, i;

-	if (!selinux_mls_enabled)
+	if (!policydb.selinux_mls_enabled)
 		return 0;

 	for (l = 0; l < 2; l++) {
@@ -516,7 +516,7 @@ int mls_compute_sid(struct context *scon
 	struct range_trans rtr;
 	struct mls_range *r;

-	if (!selinux_mls_enabled)
+	if (!policydb.selinux_mls_enabled)
 		return 0;

 	switch (specified) {
@@ -559,7 +559,7 @@ int mls_compute_sid(struct context *scon
 void mls_export_netlbl_lvl(struct context *context,
 			   struct netlbl_lsm_secattr *secattr)
 {
-	if (!selinux_mls_enabled)
+	if (!policydb.selinux_mls_enabled)
 		return;

 	secattr->attr.mls.lvl = context->range.level[0].sens - 1;
@@ -579,7 +579,7 @@ void mls_export_netlbl_lvl(struct contex
 void mls_import_netlbl_lvl(struct context *context,
 			   struct netlbl_lsm_secattr *secattr)
 {
-	if (!selinux_mls_enabled)
+	if (!policydb.selinux_mls_enabled)
 		return;

 	context->range.level[0].sens = secattr->attr.mls.lvl + 1;
@@ -601,7 +601,7 @@ int mls_export_netlbl_cat(struct context
 {
 	int rc;

-	if (!selinux_mls_enabled)
+	if (!policydb.selinux_mls_enabled)
 		return 0;

 	rc = ebitmap_netlbl_export(&context->range.level[0].cat,
@@ -629,7 +629,7 @@ int mls_import_netlbl_cat(struct context
 {
 	int rc;

-	if (!selinux_mls_enabled)
+	if (!policydb.selinux_mls_enabled)
 		return 0;

 	rc = ebitmap_netlbl_import(&context->range.level[0].cat,
diff -pruN security-testing-2.6/security/selinux/ss/mls.h security-testing-2.6-new/security/selinux/ss/mls.h
--- security-testing-2.6/security/selinux/ss/mls.h	2010-01-29 01:06:42.168051431 +0100
+++ security-testing-2.6-new/security/selinux/ss/mls.h	2010-01-31 21:50:17.923330980 +0100
@@ -24,6 +24,8 @@
 #include "context.h"
 #include "policydb.h"

+extern struct policydb policydb;
+
 int mls_compute_context_len(struct context *context);
 void mls_sid_to_context(struct context *context, char **scontext);
 int mls_context_isvalid(struct policydb *p, struct context *c);
@@ -39,6 +41,8 @@ int mls_context_to_sid(struct policydb *

 int mls_from_string(char *str, struct context *context, gfp_t gfp_mask);

+inline int mls_range_set(struct context *context, struct mls_range *range);
+
 int mls_convert_context(struct policydb *oldp,
 			struct policydb *newp,
 			struct context *context);
diff -pruN security-testing-2.6/security/selinux/ss/mls_types.c security-testing-2.6-new/security/selinux/ss/mls_types.c
--- security-testing-2.6/security/selinux/ss/mls_types.c	1970-01-01 01:00:00.000000000 +0100
+++ security-testing-2.6-new/security/selinux/ss/mls_types.c	2010-01-29 02:36:49.528045041 +0100
@@ -0,0 +1,27 @@
+/*
+ * Auxiliary functions for the multi-level security (MLS) policy.
+ *
+ * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
+ */
+
+#include "mls_types.h"
+#include "policydb.h"
+
+inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2)
+{
+	if (!policydb.selinux_mls_enabled)
+		return 1;
+
+	return ((l1->sens == l2->sens) &&
+		ebitmap_cmp(&l1->cat, &l2->cat));
+}
+
+inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2)
+{
+	if (!policydb.selinux_mls_enabled)
+		return 1;
+
+	return ((l1->sens >= l2->sens) &&
+		ebitmap_contains(&l1->cat, &l2->cat));
+}
+
diff -pruN security-testing-2.6/security/selinux/ss/mls_types.h security-testing-2.6-new/security/selinux/ss/mls_types.h
--- security-testing-2.6/security/selinux/ss/mls_types.h	2010-01-29 01:06:42.168051431 +0100
+++ security-testing-2.6-new/security/selinux/ss/mls_types.h	2010-01-29 02:23:39.017044387 +0100
@@ -14,7 +14,9 @@
 #ifndef _SS_MLS_TYPES_H_
 #define _SS_MLS_TYPES_H_

-#include "security.h"
+#include "ebitmap.h"
+
+extern struct policydb policydb;

 struct mls_level {
 	u32 sens;		/* sensitivity */
@@ -25,23 +27,8 @@ struct mls_range {
 	struct mls_level level[2]; /* low == level[0], high == level[1] */
 };

-static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2)
-{
-	if (!selinux_mls_enabled)
-		return 1;
-
-	return ((l1->sens == l2->sens) &&
-		ebitmap_cmp(&l1->cat, &l2->cat));
-}
-
-static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2)
-{
-	if (!selinux_mls_enabled)
-		return 1;
-
-	return ((l1->sens >= l2->sens) &&
-		ebitmap_contains(&l1->cat, &l2->cat));
-}
+inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2);
+inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2);

 #define mls_level_incomp(l1, l2)
 (!mls_level_dom((l1), (l2)) && !mls_level_dom((l2), (l1)))
diff -pruN security-testing-2.6/security/selinux/ss/policydb.c security-testing-2.6-new/security/selinux/ss/policydb.c
--- security-testing-2.6/security/selinux/ss/policydb.c	2010-01-29 02:02:47.740046077 +0100
+++ security-testing-2.6-new/security/selinux/ss/policydb.c	2010-01-31 21:41:44.306327882 +0100
@@ -52,8 +52,6 @@ static char *symtab_name[SYM_NUM] = {
 };
 #endif

-int selinux_mls_enabled;
-
 static unsigned int symtab_sizes[SYM_NUM] = {
 	2,
 	32,
@@ -455,7 +453,7 @@ static int policydb_index_others(struct

 	printk(KERN_DEBUG "SELinux:  %d users, %d roles, %d types, %d bools",
 	       p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim);
-	if (selinux_mls_enabled)
+	if (p->selinux_mls_enabled)
 		printk(", %d sens, %d cats", p->p_levels.nprim,
 		       p->p_cats.nprim);
 	printk("n");
@@ -656,10 +654,10 @@ static int range_tr_destroy(void *key, v
 	return 0;
 }

-static void ocontext_destroy(struct ocontext *c, int i)
+static void ocontext_destroy(struct policydb *p, struct ocontext *c, int i)
 {
-	context_destroy(&c->context[0]);
-	context_destroy(&c->context[1]);
+	context_destroy(p, &c->context[0]);
+	context_destroy(p, &c->context[1]);
 	if (i == OCON_ISID || i == OCON_FS ||
 	    i == OCON_NETIF || i == OCON_FSUSE)
 		kfree(c->u.name);
@@ -699,7 +697,7 @@ void policydb_destroy(struct policydb *p
 		while (c) {
 			ctmp = c;
 			c = c->next;
-			ocontext_destroy(ctmp, i);
+			ocontext_destroy(p, ctmp, i);
 		}
 		p->ocontexts[i] = NULL;
 	}
@@ -712,7 +710,7 @@ void policydb_destroy(struct policydb *p
 		while (c) {
 			ctmp = c;
 			c = c->next;
-			ocontext_destroy(ctmp, OCON_FSUSE);
+			ocontext_destroy(p, ctmp, OCON_FSUSE);
 		}
 		gtmp = g;
 		g = g->next;
@@ -942,7 +940,7 @@ static int context_read_and_validate(str

 	if (!policydb_context_isvalid(p, c)) {
 		printk(KERN_ERR "SELinux:  invalid security contextn");
-		context_destroy(c);
+		context_destroy(p, c);
 		rc = -EINVAL;
 	}
 out:
@@ -1787,12 +1785,7 @@ int policydb_read(struct policydb *p, vo
 	}

 	if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) {
-		if (ss_initialized && !selinux_mls_enabled) {
-			printk(KERN_ERR "SELinux: Cannot switch between non-MLS"
-				" and MLS policiesn");
-			goto bad;
-		}
-		selinux_mls_enabled = 1;
+		p->selinux_mls_enabled = 1;
 		config |= POLICYDB_CONFIG_MLS;

 		if (p->policyvers < POLICYDB_VERSION_MLS) {
@@ -1801,12 +1794,6 @@ int policydb_read(struct policydb *p, vo
 				p->policyvers);
 			goto bad;
 		}
-	} else {
-		if (ss_initialized && selinux_mls_enabled) {
-			printk(KERN_ERR "SELinux: Cannot switch between MLS and"
-				" non-MLS policiesn");
-			goto bad;
-		}
 	}
 	p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN);
 	p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);
@@ -2234,7 +2221,7 @@ int policydb_read(struct policydb *p, vo
 out:
 	return rc;
 bad_newc:
-	ocontext_destroy(newc, OCON_FSUSE);
+	ocontext_destroy(p, newc, OCON_FSUSE);
 bad:
 	if (!rc)
 		rc = -EINVAL;
diff -pruN security-testing-2.6/security/selinux/ss/policydb.h security-testing-2.6-new/security/selinux/ss/policydb.h
--- security-testing-2.6/security/selinux/ss/policydb.h	2010-01-29 02:02:47.740046077 +0100
+++ security-testing-2.6-new/security/selinux/ss/policydb.h	2010-01-29 02:33:01.393045934 +0100
@@ -185,6 +185,8 @@ struct genfs {

 /* The policy database */
 struct policydb {
+	int selinux_mls_enabled;
+
 	/* symbol tables */
 	struct symtab symtab[SYM_NUM];
 #define p_commons symtab[SYM_COMMONS]
diff -pruN security-testing-2.6/security/selinux/ss/services.c security-testing-2.6-new/security/selinux/ss/services.c
--- security-testing-2.6/security/selinux/ss/services.c	2010-01-29 02:02:47.742042805 +0100
+++ security-testing-2.6-new/security/selinux/ss/services.c	2010-01-31 23:28:26.440336638 +0100
@@ -26,6 +26,10 @@
  *
  *  Added support for bounds domain and audit messaged on masked permissions
  *
+ * Updated: Guido Trentalancia <guido@trentalancia.com>
+ *
+ *  Added support for runtime switching of the policy type
+ *
  * Copyright (C) 2008, 2009 NEC Corporation
  * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P.
  * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
@@ -1145,7 +1149,7 @@ static int string_to_context_struct(stru
 	rc = 0;
 out:
 	if (rc)
-		context_destroy(ctx);
+		context_destroy(pol, ctx);
 	return rc;
 }

@@ -1198,7 +1202,7 @@ static int security_context_to_sid_core(
 	} else if (rc)
 		goto out;
 	rc = sidtab_context_to_sid(&sidtab, &context, sid);
-	context_destroy(&context);
+	context_destroy(&policydb, &context);
 out:
 	read_unlock(&policy_rwlock);
 	kfree(scontext2);
@@ -1419,7 +1423,7 @@ static int security_compute_sid(u32 ssid
 	rc = sidtab_context_to_sid(&sidtab, &newcontext, out_sid);
 out_unlock:
 	read_unlock(&policy_rwlock);
-	context_destroy(&newcontext);
+	context_destroy(&policydb, &newcontext);
 out:
 	return rc;
 }
@@ -1547,6 +1551,8 @@ static int convert_context(u32 key,
 {
 	struct convert_context_args *args;
 	struct context oldc;
+	struct ocontext *oc;
+	struct mls_range *range;
 	struct role_datum *role;
 	struct type_datum *typdatum;
 	struct user_datum *usrdatum;
@@ -1614,9 +1620,29 @@ static int convert_context(u32 key,
 		goto bad;
 	c->type = typdatum->value;

-	rc = mls_convert_context(args->oldp, args->newp, c);
-	if (rc)
-		goto bad;
+	/* Convert the MLS/MCS fields or deal with policy type switch */
+	if (args->oldp->selinux_mls_enabled
+	    && args->newp->selinux_mls_enabled) {
+		rc = mls_convert_context(args->oldp, args->newp, c);
+		if (rc)
+			goto bad;
+	} else if (args->oldp->selinux_mls_enabled
+		   && !args->newp->selinux_mls_enabled)
+	/* Switching between MLS/MCS and non-MLS/non-MCS policy: */
+	/* free any storage used by the MLS fields in the        */
+	/* context for all existing entries in the sidtab.       */
+		mls_context_destroy(args->oldp, c);
+	else if (!args->oldp->selinux_mls_enabled
+		 && args->newp->selinux_mls_enabled) {
+	/* Switching between non-MLS/non-MCS and MLS/MCS policy:  */
+	/* ensure that the MLS fields of the context for all      */
+	/* existing entries in the sidtab are filled in with a    */
+	/* suitable default value, likely taken from one of the   */
+	/* initial SIDs.                                          */
+		oc = args->newp->ocontexts[OCON_ISID];
+		range = &oc->context[0].range;
+		mls_range_set(c, range);
+	}

 	/* Check the validity of the new context. */
 	if (!policydb_context_isvalid(args->newp, c)) {
@@ -1625,7 +1651,7 @@ static int convert_context(u32 key,
 			goto bad;
 	}

-	context_destroy(&oldc);
+	context_destroy(args->oldp, &oldc);
 	rc = 0;
 out:
 	return rc;
@@ -1633,8 +1659,8 @@ bad:
 	/* Map old representation to string and save it. */
 	if (context_struct_to_string(&oldc, &s, &len))
 		return -ENOMEM;
-	context_destroy(&oldc);
-	context_destroy(c);
+	context_destroy(args->oldp, &oldc);
+	context_destroy(args->newp, c);
 	c->str = s;
 	c->len = len;
 	printk(KERN_INFO
@@ -1712,6 +1738,15 @@ int security_load_policy(void *data, siz
 	if (policydb_read(&newpolicydb, fp))
 		return -EINVAL;

+	/* If switching between different policy types, log it */
+	if (policydb.selinux_mls_enabled && newpolicydb.selinux_mls_enabled)
+		printk(KERN_INFO "SELinux: Switching between MLS/MCS"
+			" and standard policy...n");
+	else if (!policydb.selinux_mls_enabled
+	  && newpolicydb.selinux_mls_enabled)
+		printk(KERN_INFO "SELinux: Switching between standard"
+			" and MLS/MCS policy...n");
+
 	if (sidtab_init(&newsidtab)) {
 		policydb_destroy(&newpolicydb);
 		return -ENOMEM;
@@ -1741,8 +1776,12 @@ int security_load_policy(void *data, siz
 	args.oldp = &policydb;
 	args.newp = &newpolicydb;
 	rc = sidtab_map(&newsidtab, convert_context, &args);
-	if (rc)
+	if (rc) {
+		printk(KERN_ERR "SELinux:  unable to convert the internal"
+			" representation of contexts in the new SID"
+			" tablen");
 		goto err;
+	}

 	/* Save the old policydb and SID table to free later. */
 	memcpy(&oldpolicydb, &policydb, sizeof policydb);
@@ -1761,7 +1800,7 @@ int security_load_policy(void *data, siz

 	/* Free the old policydb and SID table. */
 	policydb_destroy(&oldpolicydb);
-	sidtab_destroy(&oldsidtab);
+	sidtab_destroy(&oldpolicydb, &oldsidtab);
 	kfree(oldmap);

 	avc_ss_reset(seqno);
@@ -1773,7 +1812,7 @@ int security_load_policy(void *data, siz

 err:
 	kfree(map);
-	sidtab_destroy(&newsidtab);
+	sidtab_destroy(&newpolicydb, &newsidtab);
 	policydb_destroy(&newpolicydb);
 	return rc;

@@ -2338,7 +2377,7 @@ int security_sid_mls_copy(u32 sid, u32 m
 	u32 len;
 	int rc = 0;

-	if (!ss_initialized || !selinux_mls_enabled) {
+	if (!ss_initialized || !policydb.selinux_mls_enabled) {
 		*new_sid = sid;
 		goto out;
 	}
@@ -2388,7 +2427,7 @@ bad:

 out_unlock:
 	read_unlock(&policy_rwlock);
-	context_destroy(&newcon);
+	context_destroy(&policydb, &newcon);
 out:
 	return rc;
 }
@@ -2439,7 +2478,7 @@ int security_net_peersid_resolve(u32 nlb
 	/* we don't need to check ss_initialized here since the only way both
 	 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the
 	 * security server was initialized and ss_initialized was true */
-	if (!selinux_mls_enabled) {
+	if (!policydb.selinux_mls_enabled) {
 		*peer_sid = SECSID_NULL;
 		return 0;
 	}
@@ -2612,7 +2651,7 @@ void selinux_audit_rule_free(void *vrule
 	struct selinux_audit_rule *rule = vrule;

 	if (rule) {
-		context_destroy(&rule->au_ctxt);
+		context_destroy(&policydb, &rule->au_ctxt);
 		kfree(rule);
 	}
 }
diff -pruN security-testing-2.6/security/selinux/ss/services.h security-testing-2.6-new/security/selinux/ss/services.h
--- security-testing-2.6/security/selinux/ss/services.h	2010-01-29 01:06:42.174044406 +0100
+++ security-testing-2.6-new/security/selinux/ss/services.h	2010-01-31 23:24:36.677347711 +0100
@@ -3,6 +3,7 @@
  *
  * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
  */
+
 #ifndef _SS_SERVICES_H_
 #define _SS_SERVICES_H_

@@ -11,5 +12,51 @@

 extern struct policydb policydb;

+int security_bounded_transition(u32 old_sid, u32 new_sid);
+void security_compute_av(u32 ssid, u32 tsid, u16 orig_tclass,
+			 struct av_decision *avd);
+void security_compute_av_user(u32 ssid, u32 tsid, u16 tclass,
+			      struct av_decision *avd);
+const char *security_get_initial_sid_context(u32 sid);
+int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len);
+int security_sid_to_context_force(u32 sid, char **scontext, u32 *scontext_len);
+int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *sid);
+int security_context_to_sid_default(const char *scontext, u32 scontext_len,
+				    u32 *sid, u32 def_sid, gfp_t gfp_flags);
+int security_context_to_sid_force(const char *scontext, u32 scontext_len,
+				  u32 *sid);
+int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid);
+int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid);
+int security_member_sid(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid);
+int security_change_sid(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid);
+int security_load_policy(void *data, size_t len);
+int security_port_sid(u8 protocol, u16 port, u32 *out_sid);
+int security_netif_sid(char *name, u32 *if_sid);
+int security_node_sid(u16 domain, void *addrp, u32 addrlen, u32 *out_sid);
+int security_get_user_sids(u32 fromsid, char *username, u32 **sids, u32 *nel);
+int security_genfs_sid(const char *fstype, char *path, u16 orig_sclass,
+		       u32 *sid);
+int security_fs_use(const char *fstype, unsigned int *behavior, u32 *sid);
+int security_get_bools(int *len, char ***names, int **values);
+int security_set_bools(int len, int *values);
+int security_get_bool_value(int bool);
+int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid);
+int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type, u32 xfrm_sid,
+				 u32 *peer_sid);
+int security_get_classes(char ***classes, int *nclasses);
+int security_get_permissions(char *class, char ***perms, int *nperms);
+int security_get_reject_unknown(void);
+int security_get_allow_unknown(void);
+int security_policycap_supported(unsigned int req_cap);
+void selinux_audit_rule_free(void *vrule);
+int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule);
+int selinux_audit_rule_known(struct audit_krule *rule);
+int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
+			     struct audit_context *actx);
+int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
+				   u32 *sid);
+int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr);
+
+
 #endif	/* _SS_SERVICES_H_ */

diff -pruN security-testing-2.6/security/selinux/ss/sidtab.c security-testing-2.6-new/security/selinux/ss/sidtab.c
--- security-testing-2.6/security/selinux/ss/sidtab.c	2010-01-29 01:06:42.174044406 +0100
+++ security-testing-2.6-new/security/selinux/ss/sidtab.c	2010-01-31 21:42:55.649896349 +0100
@@ -232,7 +232,7 @@ void sidtab_hash_eval(struct sidtab *h,
 	       max_chain_len);
 }

-void sidtab_destroy(struct sidtab *s)
+void sidtab_destroy(struct policydb *p, struct sidtab *s)
 {
 	int i;
 	struct sidtab_node *cur, *temp;
@@ -245,7 +245,7 @@ void sidtab_destroy(struct sidtab *s)
 		while (cur) {
 			temp = cur;
 			cur = cur->next;
-			context_destroy(&temp->context);
+			context_destroy(p, &temp->context);
 			kfree(temp);
 		}
 		s->htable[i] = NULL;
diff -pruN security-testing-2.6/security/selinux/ss/sidtab.h security-testing-2.6-new/security/selinux/ss/sidtab.h
--- security-testing-2.6/security/selinux/ss/sidtab.h	2010-01-29 01:06:42.175047659 +0100
+++ security-testing-2.6-new/security/selinux/ss/sidtab.h	2010-01-31 21:42:31.052348740 +0100
@@ -45,7 +45,7 @@ int sidtab_context_to_sid(struct sidtab
 			  u32 *sid);

 void sidtab_hash_eval(struct sidtab *h, char *tag);
-void sidtab_destroy(struct sidtab *s);
+void sidtab_destroy(struct policydb *p, struct sidtab *s);
 void sidtab_set(struct sidtab *dst, struct sidtab *src);
 void sidtab_shutdown(struct sidtab *s);


[-- Attachment #2: switch-policy.patch --]
[-- Type: application/octet-stream, Size: 31154 bytes --]

Author: Guido Trentalancia <guido@trentalancia.com>
Date:   Sun Jan 31 22:10:22 2010 +0100

    Allow runtime switching between different policy types (e.g. from a MLS/MCS
    policy to a non-MLS/non-MCS policy or viceversa).

    Signed-off-by: Guido Trentalancia <guido@trentalancia.com>

diff -pruN security-testing-2.6/security/selinux/Makefile security-testing-2.6-new/security/selinux/Makefile
--- security-testing-2.6/security/selinux/Makefile	2010-01-29 01:06:42.132070393 +0100
+++ security-testing-2.6-new/security/selinux/Makefile	2010-01-29 02:13:42.497044862 +0100
@@ -18,7 +18,7 @@ selinux-$(CONFIG_SECURITY_NETWORK_XFRM) 
 
 selinux-$(CONFIG_NETLABEL) += netlabel.o
 
-EXTRA_CFLAGS += -Isecurity/selinux -Isecurity/selinux/include
+EXTRA_CFLAGS += -Isecurity/selinux -Isecurity/selinux/ss -Isecurity/selinux/include
 
 $(obj)/avc.o: $(obj)/flask.h
 
diff -pruN security-testing-2.6/security/selinux/include/security.h security-testing-2.6-new/security/selinux/include/security.h
--- security-testing-2.6/security/selinux/include/security.h	2010-01-29 02:02:47.737045258 +0100
+++ security-testing-2.6-new/security/selinux/include/security.h	2010-01-29 02:13:59.641064788 +0100
@@ -57,7 +57,6 @@
 struct netlbl_lsm_secattr;
 
 extern int selinux_enabled;
-extern int selinux_mls_enabled;
 
 /* Policy capabilities */
 enum {
diff -pruN security-testing-2.6/security/selinux/selinuxfs.c security-testing-2.6-new/security/selinux/selinuxfs.c
--- security-testing-2.6/security/selinux/selinuxfs.c	2010-01-29 02:02:47.738046835 +0100
+++ security-testing-2.6-new/security/selinux/selinuxfs.c	2010-01-31 23:17:44.494329730 +0100
@@ -38,6 +38,10 @@
 #include "security.h"
 #include "objsec.h"
 #include "conditional.h"
+#include "services.h"
+#include "policydb.h"
+
+extern struct policydb policydb;
 
 /* Policy capability filenames */
 static char *policycap_names[] = {
@@ -282,7 +286,8 @@ static ssize_t sel_read_mls(struct file 
 	char tmpbuf[TMPBUFLEN];
 	ssize_t length;
 
-	length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_mls_enabled);
+	length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
+		policydb.selinux_mls_enabled);
 	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
 }
 
diff -pruN security-testing-2.6/security/selinux/ss/Makefile security-testing-2.6-new/security/selinux/ss/Makefile
--- security-testing-2.6/security/selinux/ss/Makefile	2010-01-29 01:06:42.157062028 +0100
+++ security-testing-2.6-new/security/selinux/ss/Makefile	2010-01-29 02:15:52.319045091 +0100
@@ -5,5 +5,5 @@
 EXTRA_CFLAGS += -Isecurity/selinux -Isecurity/selinux/include
 obj-y := ss.o
 
-ss-y := ebitmap.o hashtab.o symtab.o sidtab.o avtab.o policydb.o services.o conditional.o mls.o
+ss-y := context.o ebitmap.o hashtab.o symtab.o sidtab.o avtab.o policydb.o services.o conditional.o mls.o mls_types.o
 
diff -pruN security-testing-2.6/security/selinux/ss/context.c security-testing-2.6-new/security/selinux/ss/context.c
--- security-testing-2.6/security/selinux/ss/context.c	1970-01-01 01:00:00.000000000 +0100
+++ security-testing-2.6-new/security/selinux/ss/context.c	2010-01-31 21:39:01.293500739 +0100
@@ -0,0 +1,131 @@
+/*
+ * Security context auxiliary functions
+ *
+ * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
+ */
+
+#include "context.h"
+#include "ebitmap.h"
+#include "mls_types.h"
+#include "security.h"
+#include "policydb.h"
+
+inline void mls_context_init(struct context *c)
+{
+	memset(&c->range, 0, sizeof(c->range));
+}
+
+inline int mls_context_cpy(struct context *dst, struct context *src)
+{
+	int rc;
+
+	if (!policydb.selinux_mls_enabled)
+		return 0;
+
+	dst->range.level[0].sens = src->range.level[0].sens;
+	rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
+	if (rc)
+		goto out;
+
+	dst->range.level[1].sens = src->range.level[1].sens;
+	rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[1].cat);
+	if (rc)
+		ebitmap_destroy(&dst->range.level[0].cat);
+out:
+	return rc;
+}
+
+/*
+ * Sets both levels in the MLS range of 'dst' to the low level of 'src'.
+ */
+inline int mls_context_cpy_low(struct context *dst, struct context *src)
+{
+	int rc;
+
+	if (!policydb.selinux_mls_enabled)
+		return 0;
+
+	dst->range.level[0].sens = src->range.level[0].sens;
+	rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
+	if (rc)
+		goto out;
+
+	dst->range.level[1].sens = src->range.level[0].sens;
+	rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[0].cat);
+	if (rc)
+		ebitmap_destroy(&dst->range.level[0].cat);
+out:
+	return rc;
+}
+
+inline int mls_context_cmp(struct context *c1, struct context *c2)
+{
+	if (!policydb.selinux_mls_enabled)
+		return 1;
+
+	return c1->range.level[0].sens == c2->range.level[0].sens &&
+		ebitmap_cmp(&c1->range.level[0].cat, &c2->range.level[0].cat) &&
+		c1->range.level[1].sens == c2->range.level[1].sens &&
+		ebitmap_cmp(&c1->range.level[1].cat, &c2->range.level[1].cat);
+}
+
+inline void mls_context_destroy(struct policydb *p, struct context *c)
+{
+	if (!p->selinux_mls_enabled)
+		return;
+
+	ebitmap_destroy(&c->range.level[0].cat);
+	ebitmap_destroy(&c->range.level[1].cat);
+	mls_context_init(c);
+}
+
+inline void context_init(struct context *c)
+{
+	memset(c, 0, sizeof(*c));
+}
+
+inline int context_cpy(struct context *dst, struct context *src)
+{
+	int rc;
+
+	dst->user = src->user;
+	dst->role = src->role;
+	dst->type = src->type;
+	if (src->str) {
+		dst->str = kstrdup(src->str, GFP_ATOMIC);
+		if (!dst->str)
+			return -ENOMEM;
+		dst->len = src->len;
+	} else {
+		dst->str = NULL;
+		dst->len = 0;
+	}
+	rc = mls_context_cpy(dst, src);
+	if (rc) {
+		kfree(dst->str);
+		return rc;
+	}
+	return 0;
+}
+
+inline void context_destroy(struct policydb *p, struct context *c)
+{
+	c->user = c->role = c->type = 0;
+	kfree(c->str);
+	c->str = NULL;
+	c->len = 0;
+	mls_context_destroy(p, c);
+}
+
+inline int context_cmp(struct context *c1, struct context *c2)
+{
+	if (c1->len && c2->len)
+		return (c1->len == c2->len && !strcmp(c1->str, c2->str));
+	if (c1->len || c2->len)
+		return 0;
+	return ((c1->user == c2->user) &&
+		(c1->role == c2->role) &&
+		(c1->type == c2->type) &&
+		mls_context_cmp(c1, c2));
+}
+
diff -pruN security-testing-2.6/security/selinux/ss/context.h security-testing-2.6-new/security/selinux/ss/context.h
--- security-testing-2.6/security/selinux/ss/context.h	2010-01-29 01:06:42.160060332 +0100
+++ security-testing-2.6-new/security/selinux/ss/context.h	2010-01-31 21:38:06.517349464 +0100
@@ -12,6 +12,7 @@
  *
  * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
  */
+
 #ifndef _SS_CONTEXT_H_
 #define _SS_CONTEXT_H_
 
@@ -19,6 +20,8 @@
 #include "mls_types.h"
 #include "security.h"
 
+extern struct policydb policydb;
+
 /*
  * A security context consists of an authenticated user
  * identity, a role, a type and a MLS range.
@@ -32,124 +35,15 @@ struct context {
 	char *str;	/* string representation if context cannot be mapped. */
 };
 
-static inline void mls_context_init(struct context *c)
-{
-	memset(&c->range, 0, sizeof(c->range));
-}
-
-static inline int mls_context_cpy(struct context *dst, struct context *src)
-{
-	int rc;
-
-	if (!selinux_mls_enabled)
-		return 0;
-
-	dst->range.level[0].sens = src->range.level[0].sens;
-	rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
-	if (rc)
-		goto out;
-
-	dst->range.level[1].sens = src->range.level[1].sens;
-	rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[1].cat);
-	if (rc)
-		ebitmap_destroy(&dst->range.level[0].cat);
-out:
-	return rc;
-}
-
-/*
- * Sets both levels in the MLS range of 'dst' to the low level of 'src'.
- */
-static inline int mls_context_cpy_low(struct context *dst, struct context *src)
-{
-	int rc;
-
-	if (!selinux_mls_enabled)
-		return 0;
-
-	dst->range.level[0].sens = src->range.level[0].sens;
-	rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
-	if (rc)
-		goto out;
-
-	dst->range.level[1].sens = src->range.level[0].sens;
-	rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[0].cat);
-	if (rc)
-		ebitmap_destroy(&dst->range.level[0].cat);
-out:
-	return rc;
-}
-
-static inline int mls_context_cmp(struct context *c1, struct context *c2)
-{
-	if (!selinux_mls_enabled)
-		return 1;
-
-	return ((c1->range.level[0].sens == c2->range.level[0].sens) &&
-		ebitmap_cmp(&c1->range.level[0].cat, &c2->range.level[0].cat) &&
-		(c1->range.level[1].sens == c2->range.level[1].sens) &&
-		ebitmap_cmp(&c1->range.level[1].cat, &c2->range.level[1].cat));
-}
-
-static inline void mls_context_destroy(struct context *c)
-{
-	if (!selinux_mls_enabled)
-		return;
-
-	ebitmap_destroy(&c->range.level[0].cat);
-	ebitmap_destroy(&c->range.level[1].cat);
-	mls_context_init(c);
-}
-
-static inline void context_init(struct context *c)
-{
-	memset(c, 0, sizeof(*c));
-}
-
-static inline int context_cpy(struct context *dst, struct context *src)
-{
-	int rc;
-
-	dst->user = src->user;
-	dst->role = src->role;
-	dst->type = src->type;
-	if (src->str) {
-		dst->str = kstrdup(src->str, GFP_ATOMIC);
-		if (!dst->str)
-			return -ENOMEM;
-		dst->len = src->len;
-	} else {
-		dst->str = NULL;
-		dst->len = 0;
-	}
-	rc = mls_context_cpy(dst, src);
-	if (rc) {
-		kfree(dst->str);
-		return rc;
-	}
-	return 0;
-}
-
-static inline void context_destroy(struct context *c)
-{
-	c->user = c->role = c->type = 0;
-	kfree(c->str);
-	c->str = NULL;
-	c->len = 0;
-	mls_context_destroy(c);
-}
-
-static inline int context_cmp(struct context *c1, struct context *c2)
-{
-	if (c1->len && c2->len)
-		return (c1->len == c2->len && !strcmp(c1->str, c2->str));
-	if (c1->len || c2->len)
-		return 0;
-	return ((c1->user == c2->user) &&
-		(c1->role == c2->role) &&
-		(c1->type == c2->type) &&
-		mls_context_cmp(c1, c2));
-}
+inline void mls_context_init(struct context *c);
+inline int mls_context_cpy(struct context *dst, struct context *src);
+inline int mls_context_cpy_low(struct context *dst, struct context *src);
+inline int mls_context_cmp(struct context *c1, struct context *c2);
+inline void mls_context_destroy(struct policydb *p, struct context *c);
+inline void context_init(struct context *c);
+inline int context_cpy(struct context *dst, struct context *src);
+inline void context_destroy(struct policydb *p, struct context *c);
+inline int context_cmp(struct context *c1, struct context *c2);
 
 #endif	/* _SS_CONTEXT_H_ */
 
diff -pruN security-testing-2.6/security/selinux/ss/mls.c security-testing-2.6-new/security/selinux/ss/mls.c
--- security-testing-2.6/security/selinux/ss/mls.c	2010-01-29 02:02:47.739046177 +0100
+++ security-testing-2.6-new/security/selinux/ss/mls.c	2010-01-31 21:49:38.704348310 +0100
@@ -39,7 +39,7 @@ int mls_compute_context_len(struct conte
 	struct ebitmap *e;
 	struct ebitmap_node *node;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.selinux_mls_enabled)
 		return 0;
 
 	len = 1; /* for the beginning ":" */
@@ -93,7 +93,7 @@ void mls_sid_to_context(struct context *
 	struct ebitmap *e;
 	struct ebitmap_node *node;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.selinux_mls_enabled)
 		return;
 
 	scontextp = *scontext;
@@ -200,7 +200,7 @@ int mls_context_isvalid(struct policydb 
 {
 	struct user_datum *usrdatum;
 
-	if (!selinux_mls_enabled)
+	if (!p->selinux_mls_enabled)
 		return 1;
 
 	if (!mls_range_isvalid(p, &c->range))
@@ -253,7 +253,7 @@ int mls_context_to_sid(struct policydb *
 	struct cat_datum *catdatum, *rngdatum;
 	int l, rc = -EINVAL;
 
-	if (!selinux_mls_enabled) {
+	if (!pol->selinux_mls_enabled) {
 		if (def_sid != SECSID_NULL && oldc)
 			*scontext += strlen(*scontext)+1;
 		return 0;
@@ -387,7 +387,7 @@ int mls_from_string(char *str, struct co
 	char *tmpstr, *freestr;
 	int rc;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.selinux_mls_enabled)
 		return -EINVAL;
 
 	/* we need freestr because mls_context_to_sid will change
@@ -407,7 +407,7 @@ int mls_from_string(char *str, struct co
 /*
  * Copies the MLS range `range' into `context'.
  */
-static inline int mls_range_set(struct context *context,
+inline int mls_range_set(struct context *context,
 				struct mls_range *range)
 {
 	int l, rc = 0;
@@ -427,7 +427,7 @@ static inline int mls_range_set(struct c
 int mls_setup_user_range(struct context *fromcon, struct user_datum *user,
 			 struct context *usercon)
 {
-	if (selinux_mls_enabled) {
+	if (policydb.selinux_mls_enabled) {
 		struct mls_level *fromcon_sen = &(fromcon->range.level[0]);
 		struct mls_level *fromcon_clr = &(fromcon->range.level[1]);
 		struct mls_level *user_low = &(user->range.level[0]);
@@ -477,7 +477,7 @@ int mls_convert_context(struct policydb 
 	struct ebitmap_node *node;
 	int l, i;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.selinux_mls_enabled)
 		return 0;
 
 	for (l = 0; l < 2; l++) {
@@ -516,7 +516,7 @@ int mls_compute_sid(struct context *scon
 	struct range_trans rtr;
 	struct mls_range *r;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.selinux_mls_enabled)
 		return 0;
 
 	switch (specified) {
@@ -559,7 +559,7 @@ int mls_compute_sid(struct context *scon
 void mls_export_netlbl_lvl(struct context *context,
 			   struct netlbl_lsm_secattr *secattr)
 {
-	if (!selinux_mls_enabled)
+	if (!policydb.selinux_mls_enabled)
 		return;
 
 	secattr->attr.mls.lvl = context->range.level[0].sens - 1;
@@ -579,7 +579,7 @@ void mls_export_netlbl_lvl(struct contex
 void mls_import_netlbl_lvl(struct context *context,
 			   struct netlbl_lsm_secattr *secattr)
 {
-	if (!selinux_mls_enabled)
+	if (!policydb.selinux_mls_enabled)
 		return;
 
 	context->range.level[0].sens = secattr->attr.mls.lvl + 1;
@@ -601,7 +601,7 @@ int mls_export_netlbl_cat(struct context
 {
 	int rc;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.selinux_mls_enabled)
 		return 0;
 
 	rc = ebitmap_netlbl_export(&context->range.level[0].cat,
@@ -629,7 +629,7 @@ int mls_import_netlbl_cat(struct context
 {
 	int rc;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.selinux_mls_enabled)
 		return 0;
 
 	rc = ebitmap_netlbl_import(&context->range.level[0].cat,
diff -pruN security-testing-2.6/security/selinux/ss/mls.h security-testing-2.6-new/security/selinux/ss/mls.h
--- security-testing-2.6/security/selinux/ss/mls.h	2010-01-29 01:06:42.168051431 +0100
+++ security-testing-2.6-new/security/selinux/ss/mls.h	2010-01-31 21:50:17.923330980 +0100
@@ -24,6 +24,8 @@
 #include "context.h"
 #include "policydb.h"
 
+extern struct policydb policydb;
+
 int mls_compute_context_len(struct context *context);
 void mls_sid_to_context(struct context *context, char **scontext);
 int mls_context_isvalid(struct policydb *p, struct context *c);
@@ -39,6 +41,8 @@ int mls_context_to_sid(struct policydb *
 
 int mls_from_string(char *str, struct context *context, gfp_t gfp_mask);
 
+inline int mls_range_set(struct context *context, struct mls_range *range);
+
 int mls_convert_context(struct policydb *oldp,
 			struct policydb *newp,
 			struct context *context);
diff -pruN security-testing-2.6/security/selinux/ss/mls_types.c security-testing-2.6-new/security/selinux/ss/mls_types.c
--- security-testing-2.6/security/selinux/ss/mls_types.c	1970-01-01 01:00:00.000000000 +0100
+++ security-testing-2.6-new/security/selinux/ss/mls_types.c	2010-01-29 02:36:49.528045041 +0100
@@ -0,0 +1,27 @@
+/*
+ * Auxiliary functions for the multi-level security (MLS) policy.
+ *
+ * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
+ */
+
+#include "mls_types.h"
+#include "policydb.h"
+
+inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2)
+{
+	if (!policydb.selinux_mls_enabled)
+		return 1;
+
+	return ((l1->sens == l2->sens) &&
+		ebitmap_cmp(&l1->cat, &l2->cat));
+}
+
+inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2)
+{
+	if (!policydb.selinux_mls_enabled)
+		return 1;
+
+	return ((l1->sens >= l2->sens) &&
+		ebitmap_contains(&l1->cat, &l2->cat));
+}
+
diff -pruN security-testing-2.6/security/selinux/ss/mls_types.h security-testing-2.6-new/security/selinux/ss/mls_types.h
--- security-testing-2.6/security/selinux/ss/mls_types.h	2010-01-29 01:06:42.168051431 +0100
+++ security-testing-2.6-new/security/selinux/ss/mls_types.h	2010-01-29 02:23:39.017044387 +0100
@@ -14,7 +14,9 @@
 #ifndef _SS_MLS_TYPES_H_
 #define _SS_MLS_TYPES_H_
 
-#include "security.h"
+#include "ebitmap.h"
+
+extern struct policydb policydb;
 
 struct mls_level {
 	u32 sens;		/* sensitivity */
@@ -25,23 +27,8 @@ struct mls_range {
 	struct mls_level level[2]; /* low == level[0], high == level[1] */
 };
 
-static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2)
-{
-	if (!selinux_mls_enabled)
-		return 1;
-
-	return ((l1->sens == l2->sens) &&
-		ebitmap_cmp(&l1->cat, &l2->cat));
-}
-
-static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2)
-{
-	if (!selinux_mls_enabled)
-		return 1;
-
-	return ((l1->sens >= l2->sens) &&
-		ebitmap_contains(&l1->cat, &l2->cat));
-}
+inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2);
+inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2);
 
 #define mls_level_incomp(l1, l2) \
 (!mls_level_dom((l1), (l2)) && !mls_level_dom((l2), (l1)))
diff -pruN security-testing-2.6/security/selinux/ss/policydb.c security-testing-2.6-new/security/selinux/ss/policydb.c
--- security-testing-2.6/security/selinux/ss/policydb.c	2010-01-29 02:02:47.740046077 +0100
+++ security-testing-2.6-new/security/selinux/ss/policydb.c	2010-01-31 21:41:44.306327882 +0100
@@ -52,8 +52,6 @@ static char *symtab_name[SYM_NUM] = {
 };
 #endif
 
-int selinux_mls_enabled;
-
 static unsigned int symtab_sizes[SYM_NUM] = {
 	2,
 	32,
@@ -455,7 +453,7 @@ static int policydb_index_others(struct 
 
 	printk(KERN_DEBUG "SELinux:  %d users, %d roles, %d types, %d bools",
 	       p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim);
-	if (selinux_mls_enabled)
+	if (p->selinux_mls_enabled)
 		printk(", %d sens, %d cats", p->p_levels.nprim,
 		       p->p_cats.nprim);
 	printk("\n");
@@ -656,10 +654,10 @@ static int range_tr_destroy(void *key, v
 	return 0;
 }
 
-static void ocontext_destroy(struct ocontext *c, int i)
+static void ocontext_destroy(struct policydb *p, struct ocontext *c, int i)
 {
-	context_destroy(&c->context[0]);
-	context_destroy(&c->context[1]);
+	context_destroy(p, &c->context[0]);
+	context_destroy(p, &c->context[1]);
 	if (i == OCON_ISID || i == OCON_FS ||
 	    i == OCON_NETIF || i == OCON_FSUSE)
 		kfree(c->u.name);
@@ -699,7 +697,7 @@ void policydb_destroy(struct policydb *p
 		while (c) {
 			ctmp = c;
 			c = c->next;
-			ocontext_destroy(ctmp, i);
+			ocontext_destroy(p, ctmp, i);
 		}
 		p->ocontexts[i] = NULL;
 	}
@@ -712,7 +710,7 @@ void policydb_destroy(struct policydb *p
 		while (c) {
 			ctmp = c;
 			c = c->next;
-			ocontext_destroy(ctmp, OCON_FSUSE);
+			ocontext_destroy(p, ctmp, OCON_FSUSE);
 		}
 		gtmp = g;
 		g = g->next;
@@ -942,7 +940,7 @@ static int context_read_and_validate(str
 
 	if (!policydb_context_isvalid(p, c)) {
 		printk(KERN_ERR "SELinux:  invalid security context\n");
-		context_destroy(c);
+		context_destroy(p, c);
 		rc = -EINVAL;
 	}
 out:
@@ -1787,12 +1785,7 @@ int policydb_read(struct policydb *p, vo
 	}
 
 	if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) {
-		if (ss_initialized && !selinux_mls_enabled) {
-			printk(KERN_ERR "SELinux: Cannot switch between non-MLS"
-				" and MLS policies\n");
-			goto bad;
-		}
-		selinux_mls_enabled = 1;
+		p->selinux_mls_enabled = 1;
 		config |= POLICYDB_CONFIG_MLS;
 
 		if (p->policyvers < POLICYDB_VERSION_MLS) {
@@ -1801,12 +1794,6 @@ int policydb_read(struct policydb *p, vo
 				p->policyvers);
 			goto bad;
 		}
-	} else {
-		if (ss_initialized && selinux_mls_enabled) {
-			printk(KERN_ERR "SELinux: Cannot switch between MLS and"
-				" non-MLS policies\n");
-			goto bad;
-		}
 	}
 	p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN);
 	p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);
@@ -2234,7 +2221,7 @@ int policydb_read(struct policydb *p, vo
 out:
 	return rc;
 bad_newc:
-	ocontext_destroy(newc, OCON_FSUSE);
+	ocontext_destroy(p, newc, OCON_FSUSE);
 bad:
 	if (!rc)
 		rc = -EINVAL;
diff -pruN security-testing-2.6/security/selinux/ss/policydb.h security-testing-2.6-new/security/selinux/ss/policydb.h
--- security-testing-2.6/security/selinux/ss/policydb.h	2010-01-29 02:02:47.740046077 +0100
+++ security-testing-2.6-new/security/selinux/ss/policydb.h	2010-01-29 02:33:01.393045934 +0100
@@ -185,6 +185,8 @@ struct genfs {
 
 /* The policy database */
 struct policydb {
+	int selinux_mls_enabled;
+
 	/* symbol tables */
 	struct symtab symtab[SYM_NUM];
 #define p_commons symtab[SYM_COMMONS]
diff -pruN security-testing-2.6/security/selinux/ss/services.c security-testing-2.6-new/security/selinux/ss/services.c
--- security-testing-2.6/security/selinux/ss/services.c	2010-01-29 02:02:47.742042805 +0100
+++ security-testing-2.6-new/security/selinux/ss/services.c	2010-01-31 23:28:26.440336638 +0100
@@ -26,6 +26,10 @@
  *
  *  Added support for bounds domain and audit messaged on masked permissions
  *
+ * Updated: Guido Trentalancia <guido@trentalancia.com>
+ *
+ *  Added support for runtime switching of the policy type
+ *
  * Copyright (C) 2008, 2009 NEC Corporation
  * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P.
  * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
@@ -1145,7 +1149,7 @@ static int string_to_context_struct(stru
 	rc = 0;
 out:
 	if (rc)
-		context_destroy(ctx);
+		context_destroy(pol, ctx);
 	return rc;
 }
 
@@ -1198,7 +1202,7 @@ static int security_context_to_sid_core(
 	} else if (rc)
 		goto out;
 	rc = sidtab_context_to_sid(&sidtab, &context, sid);
-	context_destroy(&context);
+	context_destroy(&policydb, &context);
 out:
 	read_unlock(&policy_rwlock);
 	kfree(scontext2);
@@ -1419,7 +1423,7 @@ static int security_compute_sid(u32 ssid
 	rc = sidtab_context_to_sid(&sidtab, &newcontext, out_sid);
 out_unlock:
 	read_unlock(&policy_rwlock);
-	context_destroy(&newcontext);
+	context_destroy(&policydb, &newcontext);
 out:
 	return rc;
 }
@@ -1547,6 +1551,8 @@ static int convert_context(u32 key,
 {
 	struct convert_context_args *args;
 	struct context oldc;
+	struct ocontext *oc;
+	struct mls_range *range;
 	struct role_datum *role;
 	struct type_datum *typdatum;
 	struct user_datum *usrdatum;
@@ -1614,9 +1620,29 @@ static int convert_context(u32 key,
 		goto bad;
 	c->type = typdatum->value;
 
-	rc = mls_convert_context(args->oldp, args->newp, c);
-	if (rc)
-		goto bad;
+	/* Convert the MLS/MCS fields or deal with policy type switch */
+	if (args->oldp->selinux_mls_enabled
+	    && args->newp->selinux_mls_enabled) {
+		rc = mls_convert_context(args->oldp, args->newp, c);
+		if (rc)
+			goto bad;
+	} else if (args->oldp->selinux_mls_enabled
+		   && !args->newp->selinux_mls_enabled)
+	/* Switching between MLS/MCS and non-MLS/non-MCS policy: */
+	/* free any storage used by the MLS fields in the        */
+	/* context for all existing entries in the sidtab.       */
+		mls_context_destroy(args->oldp, c);
+	else if (!args->oldp->selinux_mls_enabled
+		 && args->newp->selinux_mls_enabled) {
+	/* Switching between non-MLS/non-MCS and MLS/MCS policy:  */
+	/* ensure that the MLS fields of the context for all      */
+	/* existing entries in the sidtab are filled in with a    */
+	/* suitable default value, likely taken from one of the   */
+	/* initial SIDs.                                          */
+		oc = args->newp->ocontexts[OCON_ISID];
+		range = &oc->context[0].range;
+		mls_range_set(c, range);
+	}
 
 	/* Check the validity of the new context. */
 	if (!policydb_context_isvalid(args->newp, c)) {
@@ -1625,7 +1651,7 @@ static int convert_context(u32 key,
 			goto bad;
 	}
 
-	context_destroy(&oldc);
+	context_destroy(args->oldp, &oldc);
 	rc = 0;
 out:
 	return rc;
@@ -1633,8 +1659,8 @@ bad:
 	/* Map old representation to string and save it. */
 	if (context_struct_to_string(&oldc, &s, &len))
 		return -ENOMEM;
-	context_destroy(&oldc);
-	context_destroy(c);
+	context_destroy(args->oldp, &oldc);
+	context_destroy(args->newp, c);
 	c->str = s;
 	c->len = len;
 	printk(KERN_INFO
@@ -1712,6 +1738,15 @@ int security_load_policy(void *data, siz
 	if (policydb_read(&newpolicydb, fp))
 		return -EINVAL;
 
+	/* If switching between different policy types, log it */
+	if (policydb.selinux_mls_enabled && newpolicydb.selinux_mls_enabled)
+		printk(KERN_INFO "SELinux: Switching between MLS/MCS"
+			" and standard policy...\n");
+	else if (!policydb.selinux_mls_enabled
+	  && newpolicydb.selinux_mls_enabled)
+		printk(KERN_INFO "SELinux: Switching between standard"
+			" and MLS/MCS policy...\n");
+
 	if (sidtab_init(&newsidtab)) {
 		policydb_destroy(&newpolicydb);
 		return -ENOMEM;
@@ -1741,8 +1776,12 @@ int security_load_policy(void *data, siz
 	args.oldp = &policydb;
 	args.newp = &newpolicydb;
 	rc = sidtab_map(&newsidtab, convert_context, &args);
-	if (rc)
+	if (rc) {
+		printk(KERN_ERR "SELinux:  unable to convert the internal"
+			" representation of contexts in the new SID"
+			" table\n");
 		goto err;
+	}
 
 	/* Save the old policydb and SID table to free later. */
 	memcpy(&oldpolicydb, &policydb, sizeof policydb);
@@ -1761,7 +1800,7 @@ int security_load_policy(void *data, siz
 
 	/* Free the old policydb and SID table. */
 	policydb_destroy(&oldpolicydb);
-	sidtab_destroy(&oldsidtab);
+	sidtab_destroy(&oldpolicydb, &oldsidtab);
 	kfree(oldmap);
 
 	avc_ss_reset(seqno);
@@ -1773,7 +1812,7 @@ int security_load_policy(void *data, siz
 
 err:
 	kfree(map);
-	sidtab_destroy(&newsidtab);
+	sidtab_destroy(&newpolicydb, &newsidtab);
 	policydb_destroy(&newpolicydb);
 	return rc;
 
@@ -2338,7 +2377,7 @@ int security_sid_mls_copy(u32 sid, u32 m
 	u32 len;
 	int rc = 0;
 
-	if (!ss_initialized || !selinux_mls_enabled) {
+	if (!ss_initialized || !policydb.selinux_mls_enabled) {
 		*new_sid = sid;
 		goto out;
 	}
@@ -2388,7 +2427,7 @@ bad:
 
 out_unlock:
 	read_unlock(&policy_rwlock);
-	context_destroy(&newcon);
+	context_destroy(&policydb, &newcon);
 out:
 	return rc;
 }
@@ -2439,7 +2478,7 @@ int security_net_peersid_resolve(u32 nlb
 	/* we don't need to check ss_initialized here since the only way both
 	 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the
 	 * security server was initialized and ss_initialized was true */
-	if (!selinux_mls_enabled) {
+	if (!policydb.selinux_mls_enabled) {
 		*peer_sid = SECSID_NULL;
 		return 0;
 	}
@@ -2612,7 +2651,7 @@ void selinux_audit_rule_free(void *vrule
 	struct selinux_audit_rule *rule = vrule;
 
 	if (rule) {
-		context_destroy(&rule->au_ctxt);
+		context_destroy(&policydb, &rule->au_ctxt);
 		kfree(rule);
 	}
 }
diff -pruN security-testing-2.6/security/selinux/ss/services.h security-testing-2.6-new/security/selinux/ss/services.h
--- security-testing-2.6/security/selinux/ss/services.h	2010-01-29 01:06:42.174044406 +0100
+++ security-testing-2.6-new/security/selinux/ss/services.h	2010-01-31 23:24:36.677347711 +0100
@@ -3,6 +3,7 @@
  *
  * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
  */
+
 #ifndef _SS_SERVICES_H_
 #define _SS_SERVICES_H_
 
@@ -11,5 +12,51 @@
 
 extern struct policydb policydb;
 
+int security_bounded_transition(u32 old_sid, u32 new_sid);
+void security_compute_av(u32 ssid, u32 tsid, u16 orig_tclass,
+			 struct av_decision *avd);
+void security_compute_av_user(u32 ssid, u32 tsid, u16 tclass,
+			      struct av_decision *avd);
+const char *security_get_initial_sid_context(u32 sid);
+int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len);
+int security_sid_to_context_force(u32 sid, char **scontext, u32 *scontext_len);
+int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *sid);
+int security_context_to_sid_default(const char *scontext, u32 scontext_len,
+				    u32 *sid, u32 def_sid, gfp_t gfp_flags);
+int security_context_to_sid_force(const char *scontext, u32 scontext_len,
+				  u32 *sid);
+int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid);
+int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid);
+int security_member_sid(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid);
+int security_change_sid(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid);
+int security_load_policy(void *data, size_t len);
+int security_port_sid(u8 protocol, u16 port, u32 *out_sid);
+int security_netif_sid(char *name, u32 *if_sid);
+int security_node_sid(u16 domain, void *addrp, u32 addrlen, u32 *out_sid);
+int security_get_user_sids(u32 fromsid, char *username, u32 **sids, u32 *nel);
+int security_genfs_sid(const char *fstype, char *path, u16 orig_sclass,
+		       u32 *sid);
+int security_fs_use(const char *fstype, unsigned int *behavior, u32 *sid);
+int security_get_bools(int *len, char ***names, int **values);
+int security_set_bools(int len, int *values);
+int security_get_bool_value(int bool);
+int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid);
+int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type, u32 xfrm_sid,
+				 u32 *peer_sid);
+int security_get_classes(char ***classes, int *nclasses);
+int security_get_permissions(char *class, char ***perms, int *nperms);
+int security_get_reject_unknown(void);
+int security_get_allow_unknown(void);
+int security_policycap_supported(unsigned int req_cap);
+void selinux_audit_rule_free(void *vrule);
+int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule);
+int selinux_audit_rule_known(struct audit_krule *rule);
+int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
+			     struct audit_context *actx);
+int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
+				   u32 *sid);
+int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr);
+
+
 #endif	/* _SS_SERVICES_H_ */
 
diff -pruN security-testing-2.6/security/selinux/ss/sidtab.c security-testing-2.6-new/security/selinux/ss/sidtab.c
--- security-testing-2.6/security/selinux/ss/sidtab.c	2010-01-29 01:06:42.174044406 +0100
+++ security-testing-2.6-new/security/selinux/ss/sidtab.c	2010-01-31 21:42:55.649896349 +0100
@@ -232,7 +232,7 @@ void sidtab_hash_eval(struct sidtab *h, 
 	       max_chain_len);
 }
 
-void sidtab_destroy(struct sidtab *s)
+void sidtab_destroy(struct policydb *p, struct sidtab *s)
 {
 	int i;
 	struct sidtab_node *cur, *temp;
@@ -245,7 +245,7 @@ void sidtab_destroy(struct sidtab *s)
 		while (cur) {
 			temp = cur;
 			cur = cur->next;
-			context_destroy(&temp->context);
+			context_destroy(p, &temp->context);
 			kfree(temp);
 		}
 		s->htable[i] = NULL;
diff -pruN security-testing-2.6/security/selinux/ss/sidtab.h security-testing-2.6-new/security/selinux/ss/sidtab.h
--- security-testing-2.6/security/selinux/ss/sidtab.h	2010-01-29 01:06:42.175047659 +0100
+++ security-testing-2.6-new/security/selinux/ss/sidtab.h	2010-01-31 21:42:31.052348740 +0100
@@ -45,7 +45,7 @@ int sidtab_context_to_sid(struct sidtab 
 			  u32 *sid);
 
 void sidtab_hash_eval(struct sidtab *h, char *tag);
-void sidtab_destroy(struct sidtab *s);
+void sidtab_destroy(struct policydb *p, struct sidtab *s);
 void sidtab_set(struct sidtab *dst, struct sidtab *src);
 void sidtab_shutdown(struct sidtab *s);
 

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
  2010-01-31 22:43 [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload Guido Trentalancia
@ 2010-02-01 15:28 ` Stephen Smalley
  2010-02-01 15:37   ` Stephen Smalley
  2010-02-01 18:16 ` Stephen Smalley
  1 sibling, 1 reply; 33+ messages in thread
From: Stephen Smalley @ 2010-02-01 15:28 UTC (permalink / raw)
  To: Guido Trentalancia; +Cc: selinux, eparis, jmorris

On Sun, 2010-01-31 at 23:43 +0100, Guido Trentalancia wrote:
> Dear Stephen,
> 
> I have created the patch for allowing runtime switch between different policy types, according to your advice and previous discussions on this mailing list. The patch obsoletes the small piece of documentation that I wrote a few days ago to help new users cope with the limitation.
> 
> I would be very grateful if you could review the patch so that, as soon as it is reviewed, it can be posted to the kernel mailing list. I have done some basic testing and it works on one of my systems, although sometimes I get the following side-effect:
> 
> /dev/pts/0 changed labels.
> Unable to restore tty label...
> 
> which however doesn't affect the system. I am not sure where that comes from (perhaps bash)...

pam_selinux and openssh set the tty label on session open and restore it
upon session close.  But if it changes in the interim, they won't
restore it.  Switching MLS status will appear to change the tty label
because of the addition or removal of the MLS suffix.  I guess we'll
have to think about how/whether the userspace logic should change.

> Regards,
> 
> Guido Trentalancia
> 
> Author: Guido Trentalancia <guido@trentalancia.com>
> Date:   Sun Jan 31 22:10:22 2010 +0100
> 
>     Allow runtime switching between different policy types (e.g. from a MLS/MCS
>     policy to a non-MLS/non-MCS policy or viceversa).
> 
>     Signed-off-by: Guido Trentalancia <guido@trentalancia.com>
> 
> diff -pruN security-testing-2.6/security/selinux/Makefile security-testing-2.6-new/security/selinux/Makefile
> --- security-testing-2.6/security/selinux/Makefile	2010-01-29 01:06:42.132070393 +0100
> +++ security-testing-2.6-new/security/selinux/Makefile	2010-01-29 02:13:42.497044862 +0100
> @@ -18,7 +18,7 @@ selinux-$(CONFIG_SECURITY_NETWORK_XFRM) 
>  
>  selinux-$(CONFIG_NETLABEL) += netlabel.o
>  
> -EXTRA_CFLAGS += -Isecurity/selinux -Isecurity/selinux/include
> +EXTRA_CFLAGS += -Isecurity/selinux -Isecurity/selinux/ss -Isecurity/selinux/include
>  
>  $(obj)/avc.o: $(obj)/flask.h

We don't want to do this.  The ss/ subdirectory contains the "security
server", which is the policy engine.  It should only interact with the
rest of SELinux through a well-defined interface to preserve the
encapsulation of the security policy.  The ss/ header files are private
to it.  Instead, define interfaces as needed in include/security.h and
use them.

> diff -pruN security-testing-2.6/security/selinux/selinuxfs.c security-testing-2.6-new/security/selinux/selinuxfs.c
> --- security-testing-2.6/security/selinux/selinuxfs.c	2010-01-29 02:02:47.738046835 +0100
> +++ security-testing-2.6-new/security/selinux/selinuxfs.c	2010-01-31 23:17:44.494329730 +0100
> @@ -38,6 +38,10 @@
>  #include "security.h"
>  #include "objsec.h"
>  #include "conditional.h"
> +#include "services.h"
> +#include "policydb.h"
> +
> +extern struct policydb policydb;

Avoid adding extern declarations to .c files - they are discouraged.
The current code isn't pristine in this regard, but let's not make it
worse.

>  
>  /* Policy capability filenames */
>  static char *policycap_names[] = {
> @@ -282,7 +286,8 @@ static ssize_t sel_read_mls(struct file 
>  	char tmpbuf[TMPBUFLEN];
>  	ssize_t length;
>  
> -	length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_mls_enabled);
> +	length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
> +		policydb.selinux_mls_enabled);
>  	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
>  }

The correct way to do this would be to add a security_mls_enabled()
function to ss/services.c, with a function prototype in
include/security.h, and call that function.  Internally that function
can then read policydb.selinux_mls_enabled.

I'd also suggest just naming the field mls_enabled or mls, as you no
longer need the selinux_ prefix once it is a struct member rather than a
global variable.

> diff -pruN security-testing-2.6/security/selinux/ss/context.c security-testing-2.6-new/security/selinux/ss/context.c
> --- security-testing-2.6/security/selinux/ss/context.c	1970-01-01 01:00:00.000000000 +0100
> +++ security-testing-2.6-new/security/selinux/ss/context.c	2010-01-31 21:39:01.293500739 +0100
> @@ -0,0 +1,131 @@
> +/*
> + * Security context auxiliary functions
> + *
> + * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
> + */
> +
> +#include "context.h"
> +#include "ebitmap.h"
> +#include "mls_types.h"
> +#include "security.h"
> +#include "policydb.h"
> +
> +inline void mls_context_init(struct context *c)
> +{
> +	memset(&c->range, 0, sizeof(c->range));
> +}

I wouldn't take these functions to their own .c file, and if you do so,
then "inline" no longer makes sense.  But why did you do so?  It will
add overhead to make them out-of-line with no obvious benefit.

> +inline void mls_context_destroy(struct policydb *p, struct context *c)
> +{
> +	if (!p->selinux_mls_enabled)
> +		return;

This seems inconsistent with the other functions - here you pass the
policydb as an argument rather than just using the active policydb.
If that were truly necessary, I'd argue for passing the policydb to all
of the functions for consistency.  But I think in fact that we can drop
this !mls_enabled check altogether, given that the context is fully
initialized by context_init() and thus the ebitmap_destroy() calls
should be safe regardless of whether or not MLS is enabled.

> +	ebitmap_destroy(&c->range.level[0].cat);
> +	ebitmap_destroy(&c->range.level[1].cat);
> +	mls_context_init(c);
> +}
> +

> diff -pruN security-testing-2.6/security/selinux/ss/mls.h security-testing-2.6-new/security/selinux/ss/mls.h
> --- security-testing-2.6/security/selinux/ss/mls.h	2010-01-29 01:06:42.168051431 +0100
> +++ security-testing-2.6-new/security/selinux/ss/mls.h	2010-01-31 21:50:17.923330980 +0100
> @@ -24,6 +24,8 @@
>  #include "context.h"
>  #include "policydb.h"
>  
> +extern struct policydb policydb;
> +
>  int mls_compute_context_len(struct context *context);
>  void mls_sid_to_context(struct context *context, char **scontext);
>  int mls_context_isvalid(struct policydb *p, struct context *c);
> @@ -39,6 +41,8 @@ int mls_context_to_sid(struct policydb *
>  
>  int mls_from_string(char *str, struct context *context, gfp_t gfp_mask);
>  
> +inline int mls_range_set(struct context *context, struct mls_range *range);

Doesn't make sense to make it inline if it isn't defined here, and if it
were, it would need to be static inline.

> +
>  int mls_convert_context(struct policydb *oldp,
>  			struct policydb *newp,
>  			struct context *context);
> diff -pruN security-testing-2.6/security/selinux/ss/mls_types.c security-testing-2.6-new/security/selinux/ss/mls_types.c
> --- security-testing-2.6/security/selinux/ss/mls_types.c	1970-01-01 01:00:00.000000000 +0100
> +++ security-testing-2.6-new/security/selinux/ss/mls_types.c	2010-01-29 02:36:49.528045041 +0100
> @@ -0,0 +1,27 @@
> +/*
> + * Auxiliary functions for the multi-level security (MLS) policy.
> + *
> + * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
> + */
> +
> +#include "mls_types.h"
> +#include "policydb.h"
> +
> +inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2)
> +{
> +	if (!policydb.selinux_mls_enabled)
> +		return 1;
> +
> +	return ((l1->sens == l2->sens) &&
> +		ebitmap_cmp(&l1->cat, &l2->cat));
> +}
> +
> +inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2)
> +{
> +	if (!policydb.selinux_mls_enabled)
> +		return 1;
> +
> +	return ((l1->sens >= l2->sens) &&
> +		ebitmap_contains(&l1->cat, &l2->cat));
> +}
> +

Same deal - don't take these to their own .c file without justification.

> diff -pruN security-testing-2.6/security/selinux/ss/policydb.c security-testing-2.6-new/security/selinux/ss/policydb.c
> --- security-testing-2.6/security/selinux/ss/policydb.c	2010-01-29 02:02:47.740046077 +0100
> +++ security-testing-2.6-new/security/selinux/ss/policydb.c	2010-01-31 21:41:44.306327882 +0100
> @@ -656,10 +654,10 @@ static int range_tr_destroy(void *key, v
>  	return 0;
>  }
>  
> -static void ocontext_destroy(struct ocontext *c, int i)
> +static void ocontext_destroy(struct policydb *p, struct ocontext *c, int i)
>  {
> -	context_destroy(&c->context[0]);
> -	context_destroy(&c->context[1]);
> +	context_destroy(p, &c->context[0]);
> +	context_destroy(p, &c->context[1]);

I think we can avoid the need for passing the policydb here, as
mentioned above for mls_context_destroy.

> @@ -1787,12 +1785,7 @@ int policydb_read(struct policydb *p, vo
>  	}
>  
>  	if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) {
> -		if (ss_initialized && !selinux_mls_enabled) {
> -			printk(KERN_ERR "SELinux: Cannot switch between non-MLS"
> -				" and MLS policiesn");
> -			goto bad;
> -		}
> -		selinux_mls_enabled = 1;
> +		p->selinux_mls_enabled = 1;
>  		config |= POLICYDB_CONFIG_MLS;

It looks like this "config" variable might be a leftover of older logic
and can be removed altogether?

> diff -pruN security-testing-2.6/security/selinux/ss/policydb.h security-testing-2.6-new/security/selinux/ss/policydb.h
> --- security-testing-2.6/security/selinux/ss/policydb.h	2010-01-29 02:02:47.740046077 +0100
> +++ security-testing-2.6-new/security/selinux/ss/policydb.h	2010-01-29 02:33:01.393045934 +0100
> @@ -185,6 +185,8 @@ struct genfs {
>  
>  /* The policy database */
>  struct policydb {
> +	int selinux_mls_enabled;

Just call it mls or mls_enabled.

> +
>  	/* symbol tables */
>  	struct symtab symtab[SYM_NUM];
>  #define p_commons symtab[SYM_COMMONS]
> diff -pruN security-testing-2.6/security/selinux/ss/services.c security-testing-2.6-new/security/selinux/ss/services.c
> --- security-testing-2.6/security/selinux/ss/services.c	2010-01-29 02:02:47.742042805 +0100
> +++ security-testing-2.6-new/security/selinux/ss/services.c	2010-01-31 23:28:26.440336638 +0100
> @@ -26,6 +26,10 @@
>   *
>   *  Added support for bounds domain and audit messaged on masked permissions
>   *
> + * Updated: Guido Trentalancia <guido@trentalancia.com>
> + *
> + *  Added support for runtime switching of the policy type
> + *
>   * Copyright (C) 2008, 2009 NEC Corporation
>   * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P.
>   * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
> @@ -1145,7 +1149,7 @@ static int string_to_context_struct(stru
>  	rc = 0;
>  out:
>  	if (rc)
> -		context_destroy(ctx);
> +		context_destroy(pol, ctx);

Unnecessary I think, as before.

>  	return rc;
>  }
>  

> @@ -1547,6 +1551,8 @@ static int convert_context(u32 key,
>  {
>  	struct convert_context_args *args;
>  	struct context oldc;
> +	struct ocontext *oc;
> +	struct mls_range *range;
>  	struct role_datum *role;
>  	struct type_datum *typdatum;
>  	struct user_datum *usrdatum;
> @@ -1614,9 +1620,29 @@ static int convert_context(u32 key,
>  		goto bad;
>  	c->type = typdatum->value;
>  
> -	rc = mls_convert_context(args->oldp, args->newp, c);
> -	if (rc)
> -		goto bad;
> +	/* Convert the MLS/MCS fields or deal with policy type switch */
> +	if (args->oldp->selinux_mls_enabled
> +	    && args->newp->selinux_mls_enabled) {
> +		rc = mls_convert_context(args->oldp, args->newp, c);
> +		if (rc)
> +			goto bad;
> +	} else if (args->oldp->selinux_mls_enabled
> +		   && !args->newp->selinux_mls_enabled)
> +	/* Switching between MLS/MCS and non-MLS/non-MCS policy: */
> +	/* free any storage used by the MLS fields in the        */
> +	/* context for all existing entries in the sidtab.       */
> +		mls_context_destroy(args->oldp, c);
> +	else if (!args->oldp->selinux_mls_enabled
> +		 && args->newp->selinux_mls_enabled) {
> +	/* Switching between non-MLS/non-MCS and MLS/MCS policy:  */
> +	/* ensure that the MLS fields of the context for all      */
> +	/* existing entries in the sidtab are filled in with a    */
> +	/* suitable default value, likely taken from one of the   */
> +	/* initial SIDs.                                          */
> +		oc = args->newp->ocontexts[OCON_ISID];
> +		range = &oc->context[0].range;
> +		mls_range_set(c, range);

This could fail due to ENOMEM, so check and handle errors.
Comment style is wrong also, see CodingStyle and use checkpatch.pl.


> @@ -1712,6 +1738,15 @@ int security_load_policy(void *data, siz
>  	if (policydb_read(&newpolicydb, fp))
>  		return -EINVAL;
>  
> +	/* If switching between different policy types, log it */
> +	if (policydb.selinux_mls_enabled && newpolicydb.selinux_mls_enabled)
> +		printk(KERN_INFO "SELinux: Switching between MLS/MCS"
> +			" and standard policy...n");

Is that supposed to be "\n" aka newline rather than just "n"?

> +	else if (!policydb.selinux_mls_enabled
> +	  && newpolicydb.selinux_mls_enabled)
> +		printk(KERN_INFO "SELinux: Switching between standard"
> +			" and MLS/MCS policy...n");

Ditto.

> +
>  	if (sidtab_init(&newsidtab)) {
>  		policydb_destroy(&newpolicydb);
>  		return -ENOMEM;
> @@ -1741,8 +1776,12 @@ int security_load_policy(void *data, siz
>  	args.oldp = &policydb;
>  	args.newp = &newpolicydb;
>  	rc = sidtab_map(&newsidtab, convert_context, &args);
> -	if (rc)
> +	if (rc) {
> +		printk(KERN_ERR "SELinux:  unable to convert the internal"
> +			" representation of contexts in the new SID"
> +			" tablen");

Ditto.


> diff -pruN security-testing-2.6/security/selinux/ss/services.h security-testing-2.6-new/security/selinux/ss/services.h
> --- security-testing-2.6/security/selinux/ss/services.h	2010-01-29 01:06:42.174044406 +0100
> +++ security-testing-2.6-new/security/selinux/ss/services.h	2010-01-31 23:24:36.677347711 +0100
> @@ -3,6 +3,7 @@
>   *
>   * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
>   */
> +
>  #ifndef _SS_SERVICES_H_
>  #define _SS_SERVICES_H_
>  
> @@ -11,5 +12,51 @@
>  
>  extern struct policydb policydb;
>  
> +int security_bounded_transition(u32 old_sid, u32 new_sid);
> +void security_compute_av(u32 ssid, u32 tsid, u16 orig_tclass,
> +			 struct av_decision *avd);
> +void security_compute_av_user(u32 ssid, u32 tsid, u16 tclass,
> +			      struct av_decision *avd);
> +const char *security_get_initial_sid_context(u32 sid);
> +int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len);
> +int security_sid_to_context_force(u32 sid, char **scontext, u32 *scontext_len);
> +int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *sid);
> +int security_context_to_sid_default(const char *scontext, u32 scontext_len,
> +				    u32 *sid, u32 def_sid, gfp_t gfp_flags);
> +int security_context_to_sid_force(const char *scontext, u32 scontext_len,
> +				  u32 *sid);
> +int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid);
> +int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid);
> +int security_member_sid(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid);
> +int security_change_sid(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid);
> +int security_load_policy(void *data, size_t len);
> +int security_port_sid(u8 protocol, u16 port, u32 *out_sid);
> +int security_netif_sid(char *name, u32 *if_sid);
> +int security_node_sid(u16 domain, void *addrp, u32 addrlen, u32 *out_sid);
> +int security_get_user_sids(u32 fromsid, char *username, u32 **sids, u32 *nel);
> +int security_genfs_sid(const char *fstype, char *path, u16 orig_sclass,
> +		       u32 *sid);
> +int security_fs_use(const char *fstype, unsigned int *behavior, u32 *sid);
> +int security_get_bools(int *len, char ***names, int **values);
> +int security_set_bools(int len, int *values);
> +int security_get_bool_value(int bool);
> +int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid);
> +int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type, u32 xfrm_sid,
> +				 u32 *peer_sid);
> +int security_get_classes(char ***classes, int *nclasses);
> +int security_get_permissions(char *class, char ***perms, int *nperms);
> +int security_get_reject_unknown(void);
> +int security_get_allow_unknown(void);
> +int security_policycap_supported(unsigned int req_cap);
> +void selinux_audit_rule_free(void *vrule);
> +int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule);
> +int selinux_audit_rule_known(struct audit_krule *rule);
> +int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
> +			     struct audit_context *actx);
> +int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
> +				   u32 *sid);
> +int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr);
> +
> +
>  #endif	/* _SS_SERVICES_H_ */

No, you don't want to move these here.  This is private to ss/.
 
> diff -pruN security-testing-2.6/security/selinux/ss/sidtab.c security-testing-2.6-new/security/selinux/ss/sidtab.c
> --- security-testing-2.6/security/selinux/ss/sidtab.c	2010-01-29 01:06:42.174044406 +0100
> +++ security-testing-2.6-new/security/selinux/ss/sidtab.c	2010-01-31 21:42:55.649896349 +0100
> @@ -232,7 +232,7 @@ void sidtab_hash_eval(struct sidtab *h, 
>  	       max_chain_len);
>  }
>  
> -void sidtab_destroy(struct sidtab *s)
> +void sidtab_destroy(struct policydb *p, struct sidtab *s)

As before, I think we can avoid this by just making
mls_context_destroy() unconditional.  Should be harmless, just like
free(NULL).

-- 
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 majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
  2010-02-01 15:28 ` Stephen Smalley
@ 2010-02-01 15:37   ` Stephen Smalley
  0 siblings, 0 replies; 33+ messages in thread
From: Stephen Smalley @ 2010-02-01 15:37 UTC (permalink / raw)
  To: Guido Trentalancia; +Cc: selinux, eparis, jmorris

On Mon, 2010-02-01 at 10:28 -0500, Stephen Smalley wrote:
> On Sun, 2010-01-31 at 23:43 +0100, Guido Trentalancia wrote:
> > Dear Stephen,
> > 
> > I have created the patch for allowing runtime switch between different policy types, according to your advice and previous discussions on this mailing list. The patch obsoletes the small piece of documentation that I wrote a few days ago to help new users cope with the limitation.
> > 
> > I would be very grateful if you could review the patch so that, as soon as it is reviewed, it can be posted to the kernel mailing list. I have done some basic testing and it works on one of my systems, although sometimes I get the following side-effect:
> > 
> > /dev/pts/0 changed labels.
> > Unable to restore tty label...
> > 
> > which however doesn't affect the system. I am not sure where that comes from (perhaps bash)...
> 
> pam_selinux and openssh set the tty label on session open and restore it
> upon session close.  But if it changes in the interim, they won't
> restore it.  Switching MLS status will appear to change the tty label
> because of the addition or removal of the MLS suffix.  I guess we'll
> have to think about how/whether the userspace logic should change.
> 
> > Regards,
> > 
> > Guido Trentalancia
> > 
> > Author: Guido Trentalancia <guido@trentalancia.com>
> > Date:   Sun Jan 31 22:10:22 2010 +0100
> > 
> >     Allow runtime switching between different policy types (e.g. from a MLS/MCS
> >     policy to a non-MLS/non-MCS policy or viceversa).
> > 
> >     Signed-off-by: Guido Trentalancia <guido@trentalancia.com>
> > 
> > diff -pruN security-testing-2.6/security/selinux/Makefile security-testing-2.6-new/security/selinux/Makefile

Also:
- Missing diffstat -p1 output before the patch (see SubmittingPatches),
- Life will be easier for you if you just create the patches using git.

-- 
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 majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
  2010-01-31 22:43 [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload Guido Trentalancia
  2010-02-01 15:28 ` Stephen Smalley
@ 2010-02-01 18:16 ` Stephen Smalley
  2010-02-02 22:28   ` Guido Trentalancia
  1 sibling, 1 reply; 33+ messages in thread
From: Stephen Smalley @ 2010-02-01 18:16 UTC (permalink / raw)
  To: Guido Trentalancia; +Cc: selinux, eparis, jmorris

One last comment below:

On Sun, 2010-01-31 at 23:43 +0100, Guido Trentalancia wrote:
> diff -pruN security-testing-2.6/security/selinux/ss/services.c security-testing-2.6-new/security/selinux/ss/services.c
> --- security-testing-2.6/security/selinux/ss/services.c	2010-01-29 02:02:47.742042805 +0100
> +++ security-testing-2.6-new/security/selinux/ss/services.c	2010-01-31 23:28:26.440336638 +0100
> @@ -1614,9 +1620,29 @@ static int convert_context(u32 key,
>  		goto bad;
>  	c->type = typdatum->value;
>  
> -	rc = mls_convert_context(args->oldp, args->newp, c);
> -	if (rc)
> -		goto bad;
> +	/* Convert the MLS/MCS fields or deal with policy type switch */
> +	if (args->oldp->selinux_mls_enabled
> +	    && args->newp->selinux_mls_enabled) {
> +		rc = mls_convert_context(args->oldp, args->newp, c);
> +		if (rc)
> +			goto bad;
> +	} else if (args->oldp->selinux_mls_enabled
> +		   && !args->newp->selinux_mls_enabled)
> +	/* Switching between MLS/MCS and non-MLS/non-MCS policy: */
> +	/* free any storage used by the MLS fields in the        */
> +	/* context for all existing entries in the sidtab.       */
> +		mls_context_destroy(args->oldp, c);
> +	else if (!args->oldp->selinux_mls_enabled
> +		 && args->newp->selinux_mls_enabled) {
> +	/* Switching between non-MLS/non-MCS and MLS/MCS policy:  */
> +	/* ensure that the MLS fields of the context for all      */
> +	/* existing entries in the sidtab are filled in with a    */
> +	/* suitable default value, likely taken from one of the   */
> +	/* initial SIDs.                                          */
> +		oc = args->newp->ocontexts[OCON_ISID];
> +		range = &oc->context[0].range;
> +		mls_range_set(c, range);
> +	}

ocontexts[OCON_ISID] is a list of initial SIDs and their contexts.
Your current code takes the MLS range from whatever happens to be the
first entry in the list and uses that for all of the contexts.  That
isn't very well-defined.  At present, the first entry in the list
happens to be the last initial SID just by virtue of how the list is
constructed, but nothing else relies on any ordering of that list.

We could scan the list for a particular initial SID, e.g.
	while (oc && oc->sid[0] != SECINITSID_UNLABELED)
		oc = oc->next;

That would at least give us well-defined behavior regardless of the list
order.  However, it still doesn't really reflect what would happen if
the system had booted with the MLS/MCS policy in the first place, as
demonstrated by the sshd behavior.

Another difference is that initial SID contexts are only loaded upon the
first policy load (via policydb_load_isids).  I suppose
convert_context() could in fact just replace c with the contents of
oc->context[0] if key == oc->sid[0] to update the initial SIDs, although
care would need to be taken that the number of initial SIDs did not
change.

-- 
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 majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
  2010-02-01 18:16 ` Stephen Smalley
@ 2010-02-02 22:28   ` Guido Trentalancia
  2010-02-03 15:48     ` Stephen Smalley
  0 siblings, 1 reply; 33+ messages in thread
From: Guido Trentalancia @ 2010-02-02 22:28 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: selinux

Stephen,

the message quoted below is the message that I was referring to, when I
recalled that the actual behaviour of convert_context() is sub-optimal
(the ssh server case).

On Mon, 2010-02-01 at 13:16 -0500, Stephen Smalley wrote:
> One last comment below:
> 
> On Sun, 2010-01-31 at 23:43 +0100, Guido Trentalancia wrote:
> > diff -pruN security-testing-2.6/security/selinux/ss/services.c security-testing-2.6-new/security/selinux/ss/services.c
> > --- security-testing-2.6/security/selinux/ss/services.c	2010-01-29 02:02:47.742042805 +0100
> > +++ security-testing-2.6-new/security/selinux/ss/services.c	2010-01-31 23:28:26.440336638 +0100
> > @@ -1614,9 +1620,29 @@ static int convert_context(u32 key,
> >  		goto bad;
> >  	c->type = typdatum->value;
> >  
> > -	rc = mls_convert_context(args->oldp, args->newp, c);
> > -	if (rc)
> > -		goto bad;
> > +	/* Convert the MLS/MCS fields or deal with policy type switch */
> > +	if (args->oldp->selinux_mls_enabled
> > +	    && args->newp->selinux_mls_enabled) {
> > +		rc = mls_convert_context(args->oldp, args->newp, c);
> > +		if (rc)
> > +			goto bad;
> > +	} else if (args->oldp->selinux_mls_enabled
> > +		   && !args->newp->selinux_mls_enabled)
> > +	/* Switching between MLS/MCS and non-MLS/non-MCS policy: */
> > +	/* free any storage used by the MLS fields in the        */
> > +	/* context for all existing entries in the sidtab.       */
> > +		mls_context_destroy(args->oldp, c);
> > +	else if (!args->oldp->selinux_mls_enabled
> > +		 && args->newp->selinux_mls_enabled) {
> > +	/* Switching between non-MLS/non-MCS and MLS/MCS policy:  */
> > +	/* ensure that the MLS fields of the context for all      */
> > +	/* existing entries in the sidtab are filled in with a    */
> > +	/* suitable default value, likely taken from one of the   */
> > +	/* initial SIDs.                                          */
> > +		oc = args->newp->ocontexts[OCON_ISID];
> > +		range = &oc->context[0].range;
> > +		mls_range_set(c, range);
> > +	}
> 
> ocontexts[OCON_ISID] is a list of initial SIDs and their contexts.
> Your current code takes the MLS range from whatever happens to be the
> first entry in the list and uses that for all of the contexts.  That
> isn't very well-defined.  At present, the first entry in the list
> happens to be the last initial SID just by virtue of how the list is
> constructed, but nothing else relies on any ordering of that list.
> 
> We could scan the list for a particular initial SID, e.g.
> 	while (oc && oc->sid[0] != SECINITSID_UNLABELED)
> 		oc = oc->next;
> 
> That would at least give us well-defined behavior regardless of the list
> order.  However, it still doesn't really reflect what would happen if
> the system had booted with the MLS/MCS policy in the first place, as
> demonstrated by the sshd behavior.

This is the issue that is bothering me now. We shall tackle it,
preferably in the same patch, because otherwise we would break the
stability of the whole SELinux code.

> Another difference is that initial SID contexts are only loaded upon the
> first policy load (via policydb_load_isids).  I suppose
> convert_context() could in fact just replace c with the contents of
> oc->context[0] if key == oc->sid[0] to update the initial SIDs, although
> care would need to be taken that the number of initial SIDs did not
> change.

We now have a very simple separate patch that calls
policydb_load_isids() at every policy load and not just at the initial
load. I have tested it and it works fine, although it still doesn't
solve the "ssh server issue".

Or is it the "ssh server" that needs to react on that ?

Regards,

Guido


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
  2010-02-02 22:28   ` Guido Trentalancia
@ 2010-02-03 15:48     ` Stephen Smalley
  0 siblings, 0 replies; 33+ messages in thread
From: Stephen Smalley @ 2010-02-03 15:48 UTC (permalink / raw)
  To: Guido Trentalancia; +Cc: selinux

On Tue, 2010-02-02 at 23:28 +0100, Guido Trentalancia wrote:
> Stephen,
> 
> the message quoted below is the message that I was referring to, when I
> recalled that the actual behaviour of convert_context() is sub-optimal
> (the ssh server case).
> 
> On Mon, 2010-02-01 at 13:16 -0500, Stephen Smalley wrote:
> > One last comment below:
> > 
> > On Sun, 2010-01-31 at 23:43 +0100, Guido Trentalancia wrote:
> > > diff -pruN security-testing-2.6/security/selinux/ss/services.c security-testing-2.6-new/security/selinux/ss/services.c
> > > --- security-testing-2.6/security/selinux/ss/services.c	2010-01-29 02:02:47.742042805 +0100
> > > +++ security-testing-2.6-new/security/selinux/ss/services.c	2010-01-31 23:28:26.440336638 +0100
> > > @@ -1614,9 +1620,29 @@ static int convert_context(u32 key,
> > >  		goto bad;
> > >  	c->type = typdatum->value;
> > >  
> > > -	rc = mls_convert_context(args->oldp, args->newp, c);
> > > -	if (rc)
> > > -		goto bad;
> > > +	/* Convert the MLS/MCS fields or deal with policy type switch */
> > > +	if (args->oldp->selinux_mls_enabled
> > > +	    && args->newp->selinux_mls_enabled) {
> > > +		rc = mls_convert_context(args->oldp, args->newp, c);
> > > +		if (rc)
> > > +			goto bad;
> > > +	} else if (args->oldp->selinux_mls_enabled
> > > +		   && !args->newp->selinux_mls_enabled)
> > > +	/* Switching between MLS/MCS and non-MLS/non-MCS policy: */
> > > +	/* free any storage used by the MLS fields in the        */
> > > +	/* context for all existing entries in the sidtab.       */
> > > +		mls_context_destroy(args->oldp, c);
> > > +	else if (!args->oldp->selinux_mls_enabled
> > > +		 && args->newp->selinux_mls_enabled) {
> > > +	/* Switching between non-MLS/non-MCS and MLS/MCS policy:  */
> > > +	/* ensure that the MLS fields of the context for all      */
> > > +	/* existing entries in the sidtab are filled in with a    */
> > > +	/* suitable default value, likely taken from one of the   */
> > > +	/* initial SIDs.                                          */
> > > +		oc = args->newp->ocontexts[OCON_ISID];
> > > +		range = &oc->context[0].range;
> > > +		mls_range_set(c, range);
> > > +	}
> > 
> > ocontexts[OCON_ISID] is a list of initial SIDs and their contexts.
> > Your current code takes the MLS range from whatever happens to be the
> > first entry in the list and uses that for all of the contexts.  That
> > isn't very well-defined.  At present, the first entry in the list
> > happens to be the last initial SID just by virtue of how the list is
> > constructed, but nothing else relies on any ordering of that list.
> > 
> > We could scan the list for a particular initial SID, e.g.
> > 	while (oc && oc->sid[0] != SECINITSID_UNLABELED)
> > 		oc = oc->next;
> > 
> > That would at least give us well-defined behavior regardless of the list
> > order.  However, it still doesn't really reflect what would happen if
> > the system had booted with the MLS/MCS policy in the first place, as
> > demonstrated by the sshd behavior.
> 
> This is the issue that is bothering me now. We shall tackle it,
> preferably in the same patch, because otherwise we would break the
> stability of the whole SELinux code.
> 
> > Another difference is that initial SID contexts are only loaded upon the
> > first policy load (via policydb_load_isids).  I suppose
> > convert_context() could in fact just replace c with the contents of
> > oc->context[0] if key == oc->sid[0] to update the initial SIDs, although
> > care would need to be taken that the number of initial SIDs did not
> > change.
> 
> We now have a very simple separate patch that calls
> policydb_load_isids() at every policy load and not just at the initial
> load. I have tested it and it works fine, although it still doesn't
> solve the "ssh server issue".
> 
> Or is it the "ssh server" that needs to react on that ?

That doesn't address the already-running server issue, and the same
issue already exists when changing TE policy, e.g. if you switch to a
policy that defines a domain for an already running daemon, that daemon
won't be placed into that domain until it gets restarted.

So it truly is separable, and you should post the final form of the MLS
switching patch once you have tested it.

-- 
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 majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
  2010-02-04 19:27 Guido Trentalancia
@ 2010-02-04 19:37 ` Eric Paris
  0 siblings, 0 replies; 33+ messages in thread
From: Eric Paris @ 2010-02-04 19:37 UTC (permalink / raw)
  To: Guido Trentalancia; +Cc: selinux

On Thu, 2010-02-04 at 20:27 +0100, Guido Trentalancia wrote:

> You should fix this line to match the line above that you changed ?? I
> didn't get that... Do you mean tab misalignment or what ?

yes, tab misalignment, but all the functionality of the patch was fine,
so I'm happy.


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
@ 2010-02-04 19:27 Guido Trentalancia
  2010-02-04 19:37 ` Eric Paris
  0 siblings, 1 reply; 33+ messages in thread
From: Guido Trentalancia @ 2010-02-04 19:27 UTC (permalink / raw)
  To: Eric Paris; +Cc: selinux

Eric,

thanks for your comments. Unfortunately you are commenting an old
version of the patch.

The latest version of the "initial SIDs loading" patch was posted on
Wed, 03 Feb 2010 at 12:59:13 -0500 (18:59 CET).

The latest version of the "runtime switching between different policy
types" was posted on Wed, 03 Feb 2010 at 16:40:20 +0100.

And they've both been commited already by James Morris on Thu, 4 Feb
2010 at 09:07:38 +1100 (EST) (Wed, 23:07 CET).

The comment about the boolean has been removed by Stephen, I was just
following the other comments. Of course, that's an integer but
functionally it represents a boolean (on/off). To be picky it should
have been unsigned int.

The newline issue has been fixed. I am sorry about that...

You should fix this line to match the line above that you changed ?? I
didn't get that... Do you mean tab misalignment or what ?

Regards,

Guido


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
  2010-02-01 22:36 Guido Trentalancia
@ 2010-02-04 19:12 ` Eric Paris
  0 siblings, 0 replies; 33+ messages in thread
From: Eric Paris @ 2010-02-04 19:12 UTC (permalink / raw)
  To: Guido Trentalancia; +Cc: sds, selinux, eparis, jmorris

On Mon, 2010-02-01 at 23:36 +0100, Guido Trentalancia wrote:

> Author: Guido Trentalancia <guido@trentalancia.com>
> Date:   Mon Feb 01 23:29:52 2010 +0100
> 
>     Allow runtime switching between different policy types (e.g. from a MLS/MCS
>     policy to a non-MLS/non-MCS policy or viceversa).
> 
>     Signed-off-by: Guido Trentalancia <guido@trentalancia.com>
> 
>  security/selinux/include/security.h |    3 -
>  security/selinux/selinuxfs.c        |    3 -
>  security/selinux/ss/.policydb.c.swp |binary
>  security/selinux/ss/context.h       |    9 +--
>  security/selinux/ss/mls.c           |   26 ++++-----
>  security/selinux/ss/mls.h           |    2
>  security/selinux/ss/mls_types.h     |    5 +
>  security/selinux/ss/policydb.c      |   24 +-------
>  security/selinux/ss/policydb.h      |    4 +
>  security/selinux/ss/services.c      |   74 +++++++++++++++++++++++---
>  10 files changed, 101 insertions(+), 49 deletions(-)

One style issue and all of your \ are missing.  Send a patch with those
things fixed and you can add Acked-by: Eric Paris <eparis@redhat.com>
> 
> diff -pruN security-testing-2.6/security/selinux/include/security.h security-testing-2.6-new/security/selinux/include/security.h
> --- security-testing-2.6/security/selinux/include/security.h	2010-01-29 02:02:47.737045258 +0100
> +++ security-testing-2.6-new/security/selinux/include/security.h	2010-02-01 23:12:28.898233272 +0100
> @@ -57,7 +57,6 @@
>  struct netlbl_lsm_secattr;
>  
>  extern int selinux_enabled;
> -extern int selinux_mls_enabled;
>  
>  /* Policy capabilities */
>  enum {
> @@ -80,6 +79,8 @@ extern int selinux_policycap_openperm;
>  /* limitation of boundary depth  */
>  #define POLICYDB_BOUNDS_MAXDEPTH	4
>  
> +int security_mls_enabled(void);
> +
>  int security_load_policy(void *data, size_t len);
>  
>  int security_policycap_supported(unsigned int req_cap);
> diff -pruN security-testing-2.6/security/selinux/selinuxfs.c security-testing-2.6-new/security/selinux/selinuxfs.c
> --- security-testing-2.6/security/selinux/selinuxfs.c	2010-01-29 02:02:47.738046835 +0100
> +++ security-testing-2.6-new/security/selinux/selinuxfs.c	2010-02-01 22:06:21.709234039 +0100
> @@ -282,7 +282,8 @@ static ssize_t sel_read_mls(struct file 
>  	char tmpbuf[TMPBUFLEN];
>  	ssize_t length;
>  
> -	length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_mls_enabled);
> +	length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
> +			   security_mls_enabled());
>  	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
>  }
>  
> diff -pruN security-testing-2.6/security/selinux/ss/context.h security-testing-2.6-new/security/selinux/ss/context.h
> --- security-testing-2.6/security/selinux/ss/context.h	2010-01-29 01:06:42.160060332 +0100
> +++ security-testing-2.6-new/security/selinux/ss/context.h	2010-02-01 23:13:35.857235582 +0100
> @@ -41,7 +41,7 @@ static inline int mls_context_cpy(struct
>  {
>  	int rc;
>  
> -	if (!selinux_mls_enabled)
> +	if (!security_mls_enabled())
>  		return 0;
>  
>  	dst->range.level[0].sens = src->range.level[0].sens;
> @@ -64,7 +64,7 @@ static inline int mls_context_cpy_low(st
>  {
>  	int rc;
>  
> -	if (!selinux_mls_enabled)
> +	if (!security_mls_enabled())
>  		return 0;
>  
>  	dst->range.level[0].sens = src->range.level[0].sens;
> @@ -82,7 +82,7 @@ out:
>  
>  static inline int mls_context_cmp(struct context *c1, struct context *c2)
>  {
> -	if (!selinux_mls_enabled)
> +	if (!security_mls_enabled())
>  		return 1;
>  
>  	return ((c1->range.level[0].sens == c2->range.level[0].sens) &&
> @@ -93,9 +93,6 @@ static inline int mls_context_cmp(struct
>  
>  static inline void mls_context_destroy(struct context *c)
>  {
> -	if (!selinux_mls_enabled)
> -		return;
> -
>  	ebitmap_destroy(&c->range.level[0].cat);
>  	ebitmap_destroy(&c->range.level[1].cat);
>  	mls_context_init(c);
> diff -pruN security-testing-2.6/security/selinux/ss/mls.c security-testing-2.6-new/security/selinux/ss/mls.c
> --- security-testing-2.6/security/selinux/ss/mls.c	2010-01-29 02:02:47.739046177 +0100
> +++ security-testing-2.6-new/security/selinux/ss/mls.c	2010-02-01 22:15:48.062233721 +0100
> @@ -39,7 +39,7 @@ int mls_compute_context_len(struct conte
>  	struct ebitmap *e;
>  	struct ebitmap_node *node;
>  
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return 0;
>  
>  	len = 1; /* for the beginning ":" */
> @@ -93,7 +93,7 @@ void mls_sid_to_context(struct context *
>  	struct ebitmap *e;
>  	struct ebitmap_node *node;
>  
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return;
>  
>  	scontextp = *scontext;
> @@ -200,7 +200,7 @@ int mls_context_isvalid(struct policydb 
>  {
>  	struct user_datum *usrdatum;
>  
> -	if (!selinux_mls_enabled)
> +	if (!p->mls_enabled)
>  		return 1;
>  
>  	if (!mls_range_isvalid(p, &c->range))
> @@ -253,7 +253,7 @@ int mls_context_to_sid(struct policydb *
>  	struct cat_datum *catdatum, *rngdatum;
>  	int l, rc = -EINVAL;
>  
> -	if (!selinux_mls_enabled) {
> +	if (!pol->mls_enabled) {
>  		if (def_sid != SECSID_NULL && oldc)
>  			*scontext += strlen(*scontext)+1;
>  		return 0;
> @@ -387,7 +387,7 @@ int mls_from_string(char *str, struct co
>  	char *tmpstr, *freestr;
>  	int rc;
>  
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return -EINVAL;
>  
>  	/* we need freestr because mls_context_to_sid will change
> @@ -407,7 +407,7 @@ int mls_from_string(char *str, struct co
>  /*
>   * Copies the MLS range `range' into `context'.
>   */
> -static inline int mls_range_set(struct context *context,
> +int mls_range_set(struct context *context,
>  				struct mls_range *range)

You should fix this line to match the line above that you changed.

>  {
>  	int l, rc = 0;
> @@ -427,7 +427,7 @@ static inline int mls_range_set(struct c
>  int mls_setup_user_range(struct context *fromcon, struct user_datum *user,
>  			 struct context *usercon)
>  {
> -	if (selinux_mls_enabled) {
> +	if (policydb.mls_enabled) {
>  		struct mls_level *fromcon_sen = &(fromcon->range.level[0]);
>  		struct mls_level *fromcon_clr = &(fromcon->range.level[1]);
>  		struct mls_level *user_low = &(user->range.level[0]);
> @@ -477,7 +477,7 @@ int mls_convert_context(struct policydb 
>  	struct ebitmap_node *node;
>  	int l, i;
>  
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return 0;
>  
>  	for (l = 0; l < 2; l++) {
> @@ -516,7 +516,7 @@ int mls_compute_sid(struct context *scon
>  	struct range_trans rtr;
>  	struct mls_range *r;
>  
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return 0;
>  
>  	switch (specified) {
> @@ -559,7 +559,7 @@ int mls_compute_sid(struct context *scon
>  void mls_export_netlbl_lvl(struct context *context,
>  			   struct netlbl_lsm_secattr *secattr)
>  {
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return;
>  
>  	secattr->attr.mls.lvl = context->range.level[0].sens - 1;
> @@ -579,7 +579,7 @@ void mls_export_netlbl_lvl(struct contex
>  void mls_import_netlbl_lvl(struct context *context,
>  			   struct netlbl_lsm_secattr *secattr)
>  {
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return;
>  
>  	context->range.level[0].sens = secattr->attr.mls.lvl + 1;
> @@ -601,7 +601,7 @@ int mls_export_netlbl_cat(struct context
>  {
>  	int rc;
>  
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return 0;
>  
>  	rc = ebitmap_netlbl_export(&context->range.level[0].cat,
> @@ -629,7 +629,7 @@ int mls_import_netlbl_cat(struct context
>  {
>  	int rc;
>  
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return 0;
>  
>  	rc = ebitmap_netlbl_import(&context->range.level[0].cat,
> diff -pruN security-testing-2.6/security/selinux/ss/mls.h security-testing-2.6-new/security/selinux/ss/mls.h
> --- security-testing-2.6/security/selinux/ss/mls.h	2010-01-29 01:06:42.168051431 +0100
> +++ security-testing-2.6-new/security/selinux/ss/mls.h	2010-02-01 23:17:31.025223083 +0100
> @@ -39,6 +39,8 @@ int mls_context_to_sid(struct policydb *
>  
>  int mls_from_string(char *str, struct context *context, gfp_t gfp_mask);
>  
> +int mls_range_set(struct context *context, struct mls_range *range);
> +
>  int mls_convert_context(struct policydb *oldp,
>  			struct policydb *newp,
>  			struct context *context);
> diff -pruN security-testing-2.6/security/selinux/ss/mls_types.h security-testing-2.6-new/security/selinux/ss/mls_types.h
> --- security-testing-2.6/security/selinux/ss/mls_types.h	2010-01-29 01:06:42.168051431 +0100
> +++ security-testing-2.6-new/security/selinux/ss/mls_types.h	2010-02-01 22:23:11.799224771 +0100
> @@ -15,6 +15,7 @@
>  #define _SS_MLS_TYPES_H_
>  
>  #include "security.h"
> +#include "ebitmap.h"
>  
>  struct mls_level {
>  	u32 sens;		/* sensitivity */
> @@ -27,7 +28,7 @@ struct mls_range {
>  
>  static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2)
>  {
> -	if (!selinux_mls_enabled)
> +	if (!security_mls_enabled())
>  		return 1;
>  
>  	return ((l1->sens == l2->sens) &&
> @@ -36,7 +37,7 @@ static inline int mls_level_eq(struct ml
>  
>  static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2)
>  {
> -	if (!selinux_mls_enabled)
> +	if (!security_mls_enabled())
>  		return 1;
>  
>  	return ((l1->sens >= l2->sens) &&
> diff -pruN security-testing-2.6/security/selinux/ss/policydb.c security-testing-2.6-new/security/selinux/ss/policydb.c
> --- security-testing-2.6/security/selinux/ss/policydb.c	2010-01-29 02:02:47.740046077 +0100
> +++ security-testing-2.6-new/security/selinux/ss/policydb.c	2010-02-01 22:12:18.601226073 +0100
> @@ -52,8 +52,6 @@ static char *symtab_name[SYM_NUM] = {
>  };
>  #endif
>  
> -int selinux_mls_enabled;
> -
>  static unsigned int symtab_sizes[SYM_NUM] = {
>  	2,
>  	32,
> @@ -455,7 +453,7 @@ static int policydb_index_others(struct 
>  
>  	printk(KERN_DEBUG "SELinux:  %d users, %d roles, %d types, %d bools",
>  	       p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim);
> -	if (selinux_mls_enabled)
> +	if (p->mls_enabled)
>  		printk(", %d sens, %d cats", p->p_levels.nprim,
>  		       p->p_cats.nprim);
>  	printk("n");
> @@ -1717,14 +1715,12 @@ int policydb_read(struct policydb *p, vo
>  	int i, j, rc;
>  	__le32 buf[4];
>  	u32 nodebuf[8];
> -	u32 len, len2, config, nprim, nel, nel2;
> +	u32 len, len2, nprim, nel, nel2;
>  	char *policydb_str;
>  	struct policydb_compat_info *info;
>  	struct range_trans *rt;
>  	struct mls_range *r;
>  
> -	config = 0;
> -
>  	rc = policydb_init(p);
>  	if (rc)
>  		goto out;
> @@ -1772,7 +1768,7 @@ int policydb_read(struct policydb *p, vo
>  	kfree(policydb_str);
>  	policydb_str = NULL;
>  
> -	/* Read the version, config, and table sizes. */
> +	/* Read the version and table sizes. */
>  	rc = next_entry(buf, fp, sizeof(u32)*4);
>  	if (rc < 0)
>  		goto bad;
> @@ -1787,13 +1783,7 @@ int policydb_read(struct policydb *p, vo
>  	}
>  
>  	if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) {
> -		if (ss_initialized && !selinux_mls_enabled) {
> -			printk(KERN_ERR "SELinux: Cannot switch between non-MLS"
> -				" and MLS policiesn");
> -			goto bad;
> -		}
> -		selinux_mls_enabled = 1;
> -		config |= POLICYDB_CONFIG_MLS;
> +		p->mls_enabled = 1;
>  
>  		if (p->policyvers < POLICYDB_VERSION_MLS) {
>  			printk(KERN_ERR "SELinux: security policydb version %d "
> @@ -1801,12 +1791,6 @@ int policydb_read(struct policydb *p, vo
>  				p->policyvers);
>  			goto bad;
>  		}
> -	} else {
> -		if (ss_initialized && selinux_mls_enabled) {
> -			printk(KERN_ERR "SELinux: Cannot switch between MLS and"
> -				" non-MLS policiesn");
> -			goto bad;
> -		}
>  	}
>  	p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN);
>  	p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);
> diff -pruN security-testing-2.6/security/selinux/ss/policydb.h security-testing-2.6-new/security/selinux/ss/policydb.h
> --- security-testing-2.6/security/selinux/ss/policydb.h	2010-01-29 02:02:47.740046077 +0100
> +++ security-testing-2.6-new/security/selinux/ss/policydb.h	2010-02-01 20:47:08.352232380 +0100
> @@ -27,6 +27,8 @@
>  #include "symtab.h"
>  #include "avtab.h"
>  #include "sidtab.h"
> +#include "ebitmap.h"
> +#include "mls_types.h"
>  #include "context.h"
>  #include "constraint.h"
>  
> @@ -185,6 +187,8 @@ struct genfs {
>  
>  /* The policy database */
>  struct policydb {
> +	int mls_enabled;
> +
>  	/* symbol tables */
>  	struct symtab symtab[SYM_NUM];
>  #define p_commons symtab[SYM_COMMONS]
> diff -pruN security-testing-2.6/security/selinux/ss/services.c security-testing-2.6-new/security/selinux/ss/services.c
> --- security-testing-2.6/security/selinux/ss/services.c	2010-01-29 02:02:47.742042805 +0100
> +++ security-testing-2.6-new/security/selinux/ss/services.c	2010-02-01 23:28:02.338227931 +0100
> @@ -26,6 +26,10 @@
>   *
>   *  Added support for bounds domain and audit messaged on masked permissions
>   *
> + * Updated: Guido Trentalancia <guido@trentalancia.com>
> + *
> + *  Added support for runtime switching of the policy type
> + *
>   * Copyright (C) 2008, 2009 NEC Corporation
>   * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P.
>   * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
> @@ -232,6 +236,16 @@ static void map_decision(u16 tclass, str
>  	}
>  }
>  
> +/*
> + * Returns a boolean value.
> + * True: if the specified policy is MLS or MCS
> + * False: if the specified policy is a standard policy
> + * 	  without MLS/MCS support
> + */
> +int security_mls_enabled(void)
> +{
> +	return policydb.mls_enabled;
> +}

You comment isn't really true, it returns an int.  bool, which returns
true or false is a valid type even if the SELinux code doesn't make much
(?any?) use of it.  I'm not saying you should change either the comment
or the code, it's consistent with the other lies which follow, but I'm
just being picky.....

>  
>  /*
>   * Return the boolean value of a constraint expression
> @@ -1547,6 +1561,8 @@ static int convert_context(u32 key,
>  {
>  	struct convert_context_args *args;
>  	struct context oldc;
> +	struct ocontext *oc;
> +	struct mls_range *range;
>  	struct role_datum *role;
>  	struct type_datum *typdatum;
>  	struct user_datum *usrdatum;
> @@ -1614,9 +1630,43 @@ static int convert_context(u32 key,
>  		goto bad;
>  	c->type = typdatum->value;
>  
> -	rc = mls_convert_context(args->oldp, args->newp, c);
> -	if (rc)
> -		goto bad;
> +	/* Convert the MLS/MCS fields if dealing with MLS/MCS policies */
> +	if (args->oldp->mls_enabled
> +	    && args->newp->mls_enabled) {
> +		rc = mls_convert_context(args->oldp, args->newp, c);
> +		if (rc)
> +			goto bad;
> +	}
> +
> +	/*
> +	 * Switching between MLS/MCS and non-MLS/non-MCS policy:
> +	 * free any storage used by the MLS fields in the
> +	 * context for all existing entries in the sidtab.
> +	 */
> +	if (args->oldp->mls_enabled && !args->newp->mls_enabled)
> +		mls_context_destroy(c);
> +
> +	/*
> +	 * Switching between non-MLS/non-MCS and MLS/MCS policy:
> +	 * ensure that the MLS fields of the context for all
> +	 * existing entries in the sidtab are filled in with a
> +	 * suitable default value, likely taken from one of the
> +	 * initial SIDs.
> +	 */
> +	if (!args->oldp->mls_enabled && args->newp->mls_enabled) {
> +		oc = args->newp->ocontexts[OCON_ISID];
> +		while (oc && oc->sid[0] != SECINITSID_UNLABELED)
> +			oc = oc->next;
> +		if (!oc) {
> +			printk(KERN_ERR "SELinux:  unable to look up"
> +				" the initial SIDs listn");

What happened to your \'s ?

> +			goto bad;
> +		}
> +		range = &oc->context[0].range;
> +		rc = mls_range_set(c, range);
> +		if (rc)
> +			goto bad;
> +	}
>  
>  	/* Check the validity of the new context. */
>  	if (!policydb_context_isvalid(args->newp, c)) {
> @@ -1712,6 +1762,14 @@ int security_load_policy(void *data, siz
>  	if (policydb_read(&newpolicydb, fp))
>  		return -EINVAL;
>  
> +	/* If switching between different policy types, log it */
> +	if (policydb.mls_enabled && !newpolicydb.mls_enabled)
> +		printk(KERN_INFO "SELinux: Switching between MLS/MCS"
> +			" and standard policy...n");

More missing \

> +	else if (!policydb.mls_enabled && newpolicydb.mls_enabled)
> +		printk(KERN_INFO "SELinux: Switching between standard"
> +			" and MLS/MCS policy...n");
> +
>  	if (sidtab_init(&newsidtab)) {
>  		policydb_destroy(&newpolicydb);
>  		return -ENOMEM;
> @@ -1741,8 +1799,12 @@ int security_load_policy(void *data, siz
>  	args.oldp = &policydb;
>  	args.newp = &newpolicydb;
>  	rc = sidtab_map(&newsidtab, convert_context, &args);
> -	if (rc)
> +	if (rc) {
> +		printk(KERN_ERR "SELinux:  unable to convert the internal"
> +			" representation of contexts in the new SID"
> +			" tablen");

Not going to mention them any more....

>  		goto err;
> +	}
>  
>  	/* Save the old policydb and SID table to free later. */
>  	memcpy(&oldpolicydb, &policydb, sizeof policydb);
> @@ -2338,7 +2400,7 @@ int security_sid_mls_copy(u32 sid, u32 m
>  	u32 len;
>  	int rc = 0;
>  
> -	if (!ss_initialized || !selinux_mls_enabled) {
> +	if (!ss_initialized || !policydb.mls_enabled) {
>  		*new_sid = sid;
>  		goto out;
>  	}
> @@ -2439,7 +2501,7 @@ int security_net_peersid_resolve(u32 nlb
>  	/* we don't need to check ss_initialized here since the only way both
>  	 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the
>  	 * security server was initialized and ss_initialized was true */
> -	if (!selinux_mls_enabled) {
> +	if (!policydb.mls_enabled) {
>  		*peer_sid = SECSID_NULL;
>  		return 0;
>  	} 



--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
  2010-02-03 15:40 Guido Trentalancia
  2010-02-03 15:53 ` Stephen Smalley
@ 2010-02-03 22:07 ` James Morris
  1 sibling, 0 replies; 33+ messages in thread
From: James Morris @ 2010-02-03 22:07 UTC (permalink / raw)
  To: Guido Trentalancia; +Cc: Stephen Smalley, selinux

On Wed, 3 Feb 2010, Guido Trentalancia wrote:

> Author: Guido Trentalancia <guido@trentalancia.com>
> Date:   Mon Feb 02 23:11:07 2010 +0100
> 
>     Allow runtime switching between different policy types (e.g. from a MLS/MCS
>     policy to a non-MLS/non-MCS policy or viceversa).
> 
>     Signed-off-by: Guido Trentalancia <guido@trentalancia.com>


Applied to
git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6#next


-- 
James Morris
<jmorris@namei.org>

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
  2010-02-03 15:40 Guido Trentalancia
@ 2010-02-03 15:53 ` Stephen Smalley
  2010-02-03 22:07 ` James Morris
  1 sibling, 0 replies; 33+ messages in thread
From: Stephen Smalley @ 2010-02-03 15:53 UTC (permalink / raw)
  To: Guido Trentalancia; +Cc: selinux, James Morris, Eric Paris, Paul Moore

On Wed, 2010-02-03 at 16:40 +0100, Guido Trentalancia wrote:
> Author: Guido Trentalancia <guido@trentalancia.com>
> Date:   Mon Feb 02 23:11:07 2010 +0100
> 
>     Allow runtime switching between different policy types (e.g. from a MLS/MCS
>     policy to a non-MLS/non-MCS policy or viceversa).
> 
>     Signed-off-by: Guido Trentalancia <guido@trentalancia.com>

Acked-by: Stephen Smalley <sds@tycho.nsa.gov>

> 
> ---
> 
>  security/selinux/include/security.h |    3 -
>  security/selinux/selinuxfs.c        |    3 -
>  security/selinux/ss/context.h       |   12 -----
>  security/selinux/ss/mls.c           |   26 +++++-----
>  security/selinux/ss/mls.h           |    2 
>  security/selinux/ss/mls_types.h     |    7 --
>  security/selinux/ss/policydb.c      |   24 +---------
>  security/selinux/ss/policydb.h      |    4 +
>  security/selinux/ss/services.c      |   62 +++++++++++++++++++++++---
>  9 files changed, 84 insertions(+), 59 deletions(-)
> 
> diff -pruN security-testing-2.6/security/selinux/include/security.h security-testing-2.6-new/security/selinux/include/security.h
> --- security-testing-2.6/security/selinux/include/security.h	2010-01-29 02:02:47.737045258 +0100
> +++ security-testing-2.6-new/security/selinux/include/security.h	2010-02-01 23:12:28.898233272 +0100
> @@ -57,7 +57,6 @@
>  struct netlbl_lsm_secattr;
>  
>  extern int selinux_enabled;
> -extern int selinux_mls_enabled;
>  
>  /* Policy capabilities */
>  enum {
> @@ -80,6 +79,8 @@ extern int selinux_policycap_openperm;
>  /* limitation of boundary depth  */
>  #define POLICYDB_BOUNDS_MAXDEPTH	4
>  
> +int security_mls_enabled(void);
> +
>  int security_load_policy(void *data, size_t len);
>  
>  int security_policycap_supported(unsigned int req_cap);
> diff -pruN security-testing-2.6/security/selinux/selinuxfs.c security-testing-2.6-new/security/selinux/selinuxfs.c
> --- security-testing-2.6/security/selinux/selinuxfs.c	2010-01-29 02:02:47.738046835 +0100
> +++ security-testing-2.6-new/security/selinux/selinuxfs.c	2010-02-01 22:06:21.709234039 +0100
> @@ -282,7 +282,8 @@ static ssize_t sel_read_mls(struct file 
>  	char tmpbuf[TMPBUFLEN];
>  	ssize_t length;
>  
> -	length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_mls_enabled);
> +	length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
> +			   security_mls_enabled());
>  	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
>  }
>  
> diff -pruN security-testing-2.6/security/selinux/ss/context.h security-testing-2.6-new/security/selinux/ss/context.h
> --- security-testing-2.6/security/selinux/ss/context.h	2010-01-29 01:06:42.160060332 +0100
> +++ security-testing-2.6-new/security/selinux/ss/context.h	2010-02-02 21:49:41.210011207 +0100
> @@ -41,9 +41,6 @@ static inline int mls_context_cpy(struct
>  {
>  	int rc;
>  
> -	if (!selinux_mls_enabled)
> -		return 0;
> -
>  	dst->range.level[0].sens = src->range.level[0].sens;
>  	rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
>  	if (rc)
> @@ -64,9 +61,6 @@ static inline int mls_context_cpy_low(st
>  {
>  	int rc;
>  
> -	if (!selinux_mls_enabled)
> -		return 0;
> -
>  	dst->range.level[0].sens = src->range.level[0].sens;
>  	rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
>  	if (rc)
> @@ -82,9 +76,6 @@ out:
>  
>  static inline int mls_context_cmp(struct context *c1, struct context *c2)
>  {
> -	if (!selinux_mls_enabled)
> -		return 1;
> -
>  	return ((c1->range.level[0].sens == c2->range.level[0].sens) &&
>  		ebitmap_cmp(&c1->range.level[0].cat, &c2->range.level[0].cat) &&
>  		(c1->range.level[1].sens == c2->range.level[1].sens) &&
> @@ -93,9 +84,6 @@ static inline int mls_context_cmp(struct
>  
>  static inline void mls_context_destroy(struct context *c)
>  {
> -	if (!selinux_mls_enabled)
> -		return;
> -
>  	ebitmap_destroy(&c->range.level[0].cat);
>  	ebitmap_destroy(&c->range.level[1].cat);
>  	mls_context_init(c);
> diff -pruN security-testing-2.6/security/selinux/ss/mls.c security-testing-2.6-new/security/selinux/ss/mls.c
> --- security-testing-2.6/security/selinux/ss/mls.c	2010-01-29 02:02:47.739046177 +0100
> +++ security-testing-2.6-new/security/selinux/ss/mls.c	2010-02-01 22:15:48.062233721 +0100
> @@ -39,7 +39,7 @@ int mls_compute_context_len(struct conte
>  	struct ebitmap *e;
>  	struct ebitmap_node *node;
>  
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return 0;
>  
>  	len = 1; /* for the beginning ":" */
> @@ -93,7 +93,7 @@ void mls_sid_to_context(struct context *
>  	struct ebitmap *e;
>  	struct ebitmap_node *node;
>  
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return;
>  
>  	scontextp = *scontext;
> @@ -200,7 +200,7 @@ int mls_context_isvalid(struct policydb 
>  {
>  	struct user_datum *usrdatum;
>  
> -	if (!selinux_mls_enabled)
> +	if (!p->mls_enabled)
>  		return 1;
>  
>  	if (!mls_range_isvalid(p, &c->range))
> @@ -253,7 +253,7 @@ int mls_context_to_sid(struct policydb *
>  	struct cat_datum *catdatum, *rngdatum;
>  	int l, rc = -EINVAL;
>  
> -	if (!selinux_mls_enabled) {
> +	if (!pol->mls_enabled) {
>  		if (def_sid != SECSID_NULL && oldc)
>  			*scontext += strlen(*scontext)+1;
>  		return 0;
> @@ -387,7 +387,7 @@ int mls_from_string(char *str, struct co
>  	char *tmpstr, *freestr;
>  	int rc;
>  
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return -EINVAL;
>  
>  	/* we need freestr because mls_context_to_sid will change
> @@ -407,7 +407,7 @@ int mls_from_string(char *str, struct co
>  /*
>   * Copies the MLS range `range' into `context'.
>   */
> -static inline int mls_range_set(struct context *context,
> +int mls_range_set(struct context *context,
>  				struct mls_range *range)
>  {
>  	int l, rc = 0;
> @@ -427,7 +427,7 @@ static inline int mls_range_set(struct c
>  int mls_setup_user_range(struct context *fromcon, struct user_datum *user,
>  			 struct context *usercon)
>  {
> -	if (selinux_mls_enabled) {
> +	if (policydb.mls_enabled) {
>  		struct mls_level *fromcon_sen = &(fromcon->range.level[0]);
>  		struct mls_level *fromcon_clr = &(fromcon->range.level[1]);
>  		struct mls_level *user_low = &(user->range.level[0]);
> @@ -477,7 +477,7 @@ int mls_convert_context(struct policydb 
>  	struct ebitmap_node *node;
>  	int l, i;
>  
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return 0;
>  
>  	for (l = 0; l < 2; l++) {
> @@ -516,7 +516,7 @@ int mls_compute_sid(struct context *scon
>  	struct range_trans rtr;
>  	struct mls_range *r;
>  
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return 0;
>  
>  	switch (specified) {
> @@ -559,7 +559,7 @@ int mls_compute_sid(struct context *scon
>  void mls_export_netlbl_lvl(struct context *context,
>  			   struct netlbl_lsm_secattr *secattr)
>  {
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return;
>  
>  	secattr->attr.mls.lvl = context->range.level[0].sens - 1;
> @@ -579,7 +579,7 @@ void mls_export_netlbl_lvl(struct contex
>  void mls_import_netlbl_lvl(struct context *context,
>  			   struct netlbl_lsm_secattr *secattr)
>  {
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return;
>  
>  	context->range.level[0].sens = secattr->attr.mls.lvl + 1;
> @@ -601,7 +601,7 @@ int mls_export_netlbl_cat(struct context
>  {
>  	int rc;
>  
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return 0;
>  
>  	rc = ebitmap_netlbl_export(&context->range.level[0].cat,
> @@ -629,7 +629,7 @@ int mls_import_netlbl_cat(struct context
>  {
>  	int rc;
>  
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return 0;
>  
>  	rc = ebitmap_netlbl_import(&context->range.level[0].cat,
> diff -pruN security-testing-2.6/security/selinux/ss/mls.h security-testing-2.6-new/security/selinux/ss/mls.h
> --- security-testing-2.6/security/selinux/ss/mls.h	2010-01-29 01:06:42.168051431 +0100
> +++ security-testing-2.6-new/security/selinux/ss/mls.h	2010-02-01 23:17:31.025223083 +0100
> @@ -39,6 +39,8 @@ int mls_context_to_sid(struct policydb *
>  
>  int mls_from_string(char *str, struct context *context, gfp_t gfp_mask);
>  
> +int mls_range_set(struct context *context, struct mls_range *range);
> +
>  int mls_convert_context(struct policydb *oldp,
>  			struct policydb *newp,
>  			struct context *context);
> diff -pruN security-testing-2.6/security/selinux/ss/mls_types.h security-testing-2.6-new/security/selinux/ss/mls_types.h
> --- security-testing-2.6/security/selinux/ss/mls_types.h	2010-01-29 01:06:42.168051431 +0100
> +++ security-testing-2.6-new/security/selinux/ss/mls_types.h	2010-02-02 21:49:54.108993602 +0100
> @@ -15,6 +15,7 @@
>  #define _SS_MLS_TYPES_H_
>  
>  #include "security.h"
> +#include "ebitmap.h"
>  
>  struct mls_level {
>  	u32 sens;		/* sensitivity */
> @@ -27,18 +28,12 @@ struct mls_range {
>  
>  static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2)
>  {
> -	if (!selinux_mls_enabled)
> -		return 1;
> -
>  	return ((l1->sens == l2->sens) &&
>  		ebitmap_cmp(&l1->cat, &l2->cat));
>  }
>  
>  static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2)
>  {
> -	if (!selinux_mls_enabled)
> -		return 1;
> -
>  	return ((l1->sens >= l2->sens) &&
>  		ebitmap_contains(&l1->cat, &l2->cat));
>  }
> diff -pruN security-testing-2.6/security/selinux/ss/policydb.c security-testing-2.6-new/security/selinux/ss/policydb.c
> --- security-testing-2.6/security/selinux/ss/policydb.c	2010-01-29 02:02:47.740046077 +0100
> +++ security-testing-2.6-new/security/selinux/ss/policydb.c	2010-02-01 22:12:18.601226073 +0100
> @@ -52,8 +52,6 @@ static char *symtab_name[SYM_NUM] = {
>  };
>  #endif
>  
> -int selinux_mls_enabled;
> -
>  static unsigned int symtab_sizes[SYM_NUM] = {
>  	2,
>  	32,
> @@ -455,7 +453,7 @@ static int policydb_index_others(struct 
>  
>  	printk(KERN_DEBUG "SELinux:  %d users, %d roles, %d types, %d bools",
>  	       p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim);
> -	if (selinux_mls_enabled)
> +	if (p->mls_enabled)
>  		printk(", %d sens, %d cats", p->p_levels.nprim,
>  		       p->p_cats.nprim);
>  	printk("\n");
> @@ -1717,14 +1715,12 @@ int policydb_read(struct policydb *p, vo
>  	int i, j, rc;
>  	__le32 buf[4];
>  	u32 nodebuf[8];
> -	u32 len, len2, config, nprim, nel, nel2;
> +	u32 len, len2, nprim, nel, nel2;
>  	char *policydb_str;
>  	struct policydb_compat_info *info;
>  	struct range_trans *rt;
>  	struct mls_range *r;
>  
> -	config = 0;
> -
>  	rc = policydb_init(p);
>  	if (rc)
>  		goto out;
> @@ -1772,7 +1768,7 @@ int policydb_read(struct policydb *p, vo
>  	kfree(policydb_str);
>  	policydb_str = NULL;
>  
> -	/* Read the version, config, and table sizes. */
> +	/* Read the version and table sizes. */
>  	rc = next_entry(buf, fp, sizeof(u32)*4);
>  	if (rc < 0)
>  		goto bad;
> @@ -1787,13 +1783,7 @@ int policydb_read(struct policydb *p, vo
>  	}
>  
>  	if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) {
> -		if (ss_initialized && !selinux_mls_enabled) {
> -			printk(KERN_ERR "SELinux: Cannot switch between non-MLS"
> -				" and MLS policies\n");
> -			goto bad;
> -		}
> -		selinux_mls_enabled = 1;
> -		config |= POLICYDB_CONFIG_MLS;
> +		p->mls_enabled = 1;
>  
>  		if (p->policyvers < POLICYDB_VERSION_MLS) {
>  			printk(KERN_ERR "SELinux: security policydb version %d "
> @@ -1801,12 +1791,6 @@ int policydb_read(struct policydb *p, vo
>  				p->policyvers);
>  			goto bad;
>  		}
> -	} else {
> -		if (ss_initialized && selinux_mls_enabled) {
> -			printk(KERN_ERR "SELinux: Cannot switch between MLS and"
> -				" non-MLS policies\n");
> -			goto bad;
> -		}
>  	}
>  	p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN);
>  	p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);
> diff -pruN security-testing-2.6/security/selinux/ss/policydb.h security-testing-2.6-new/security/selinux/ss/policydb.h
> --- security-testing-2.6/security/selinux/ss/policydb.h	2010-01-29 02:02:47.740046077 +0100
> +++ security-testing-2.6-new/security/selinux/ss/policydb.h	2010-02-01 20:47:08.352232380 +0100
> @@ -27,6 +27,8 @@
>  #include "symtab.h"
>  #include "avtab.h"
>  #include "sidtab.h"
> +#include "ebitmap.h"
> +#include "mls_types.h"
>  #include "context.h"
>  #include "constraint.h"
>  
> @@ -185,6 +187,8 @@ struct genfs {
>  
>  /* The policy database */
>  struct policydb {
> +	int mls_enabled;
> +
>  	/* symbol tables */
>  	struct symtab symtab[SYM_NUM];
>  #define p_commons symtab[SYM_COMMONS]
> diff -pruN security-testing-2.6/security/selinux/ss/services.c security-testing-2.6-new/security/selinux/ss/services.c
> --- security-testing-2.6/security/selinux/ss/services.c	2010-01-29 02:02:47.742042805 +0100
> +++ security-testing-2.6-new/security/selinux/ss/services.c	2010-02-02 23:48:07.637994777 +0100
> @@ -26,6 +26,10 @@
>   *
>   *  Added support for bounds domain and audit messaged on masked permissions
>   *
> + * Updated: Guido Trentalancia <guido@trentalancia.com>
> + *
> + *  Added support for runtime switching of the policy type
> + *
>   * Copyright (C) 2008, 2009 NEC Corporation
>   * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P.
>   * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
> @@ -232,6 +236,10 @@ static void map_decision(u16 tclass, str
>  	}
>  }
>  
> +int security_mls_enabled(void)
> +{
> +	return policydb.mls_enabled;
> +}
>  
>  /*
>   * Return the boolean value of a constraint expression
> @@ -1547,6 +1555,8 @@ static int convert_context(u32 key,
>  {
>  	struct convert_context_args *args;
>  	struct context oldc;
> +	struct ocontext *oc;
> +	struct mls_range *range;
>  	struct role_datum *role;
>  	struct type_datum *typdatum;
>  	struct user_datum *usrdatum;
> @@ -1614,9 +1624,39 @@ static int convert_context(u32 key,
>  		goto bad;
>  	c->type = typdatum->value;
>  
> -	rc = mls_convert_context(args->oldp, args->newp, c);
> -	if (rc)
> -		goto bad;
> +	/* Convert the MLS fields if dealing with MLS policies */
> +	if (args->oldp->mls_enabled && args->newp->mls_enabled) {
> +		rc = mls_convert_context(args->oldp, args->newp, c);
> +		if (rc)
> +			goto bad;
> +	} else if (args->oldp->mls_enabled && !args->newp->mls_enabled) {
> +		/*
> +		 * Switching between MLS and non-MLS policy:
> +		 * free any storage used by the MLS fields in the
> +		 * context for all existing entries in the sidtab.
> +		 */
> +		mls_context_destroy(c);
> +	} else if (!args->oldp->mls_enabled && args->newp->mls_enabled) {
> +		/*
> +		 * Switching between non-MLS and MLS policy:
> +		 * ensure that the MLS fields of the context for all
> +		 * existing entries in the sidtab are filled in with a
> +		 * suitable default value, likely taken from one of the
> +		 * initial SIDs.
> +		 */
> +		oc = args->newp->ocontexts[OCON_ISID];
> +		while (oc && oc->sid[0] != SECINITSID_UNLABELED)
> +			oc = oc->next;
> +		if (!oc) {
> +			printk(KERN_ERR "SELinux:  unable to look up"
> +				" the initial SIDs list\n");
> +			goto bad;
> +		}
> +		range = &oc->context[0].range;
> +		rc = mls_range_set(c, range);
> +		if (rc)
> +			goto bad;
> +	}
>  
>  	/* Check the validity of the new context. */
>  	if (!policydb_context_isvalid(args->newp, c)) {
> @@ -1712,6 +1752,12 @@ int security_load_policy(void *data, siz
>  	if (policydb_read(&newpolicydb, fp))
>  		return -EINVAL;
>  
> +	/* If switching between different policy types, log MLS status */
> +	if (policydb.mls_enabled && !newpolicydb.mls_enabled)
> +		printk(KERN_INFO "SELinux: Disabling MLS support...\n");
> +	else if (!policydb.mls_enabled && newpolicydb.mls_enabled)
> +		printk(KERN_INFO "SELinux: Enabling MLS support...\n");
> +
>  	if (sidtab_init(&newsidtab)) {
>  		policydb_destroy(&newpolicydb);
>  		return -ENOMEM;
> @@ -1741,8 +1787,12 @@ int security_load_policy(void *data, siz
>  	args.oldp = &policydb;
>  	args.newp = &newpolicydb;
>  	rc = sidtab_map(&newsidtab, convert_context, &args);
> -	if (rc)
> +	if (rc) {
> +		printk(KERN_ERR "SELinux:  unable to convert the internal"
> +			" representation of contexts in the new SID"
> +			" table\n");
>  		goto err;
> +	}
>  
>  	/* Save the old policydb and SID table to free later. */
>  	memcpy(&oldpolicydb, &policydb, sizeof policydb);
> @@ -2338,7 +2388,7 @@ int security_sid_mls_copy(u32 sid, u32 m
>  	u32 len;
>  	int rc = 0;
>  
> -	if (!ss_initialized || !selinux_mls_enabled) {
> +	if (!ss_initialized || !policydb.mls_enabled) {
>  		*new_sid = sid;
>  		goto out;
>  	}
> @@ -2439,7 +2489,7 @@ int security_net_peersid_resolve(u32 nlb
>  	/* we don't need to check ss_initialized here since the only way both
>  	 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the
>  	 * security server was initialized and ss_initialized was true */
> -	if (!selinux_mls_enabled) {
> +	if (!policydb.mls_enabled) {
>  		*peer_sid = SECSID_NULL;
>  		return 0;
>  	}
> 
> 
> 
> --
> This message was distributed to subscribers of the selinux mailing list.
> If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
> the words "unsubscribe selinux" without quotes as the message.
-- 
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 majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
@ 2010-02-03 15:40 Guido Trentalancia
  2010-02-03 15:53 ` Stephen Smalley
  2010-02-03 22:07 ` James Morris
  0 siblings, 2 replies; 33+ messages in thread
From: Guido Trentalancia @ 2010-02-03 15:40 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: selinux

Author: Guido Trentalancia <guido@trentalancia.com>
Date:   Mon Feb 02 23:11:07 2010 +0100

    Allow runtime switching between different policy types (e.g. from a MLS/MCS
    policy to a non-MLS/non-MCS policy or viceversa).

    Signed-off-by: Guido Trentalancia <guido@trentalancia.com>

---

 security/selinux/include/security.h |    3 -
 security/selinux/selinuxfs.c        |    3 -
 security/selinux/ss/context.h       |   12 -----
 security/selinux/ss/mls.c           |   26 +++++-----
 security/selinux/ss/mls.h           |    2 
 security/selinux/ss/mls_types.h     |    7 --
 security/selinux/ss/policydb.c      |   24 +---------
 security/selinux/ss/policydb.h      |    4 +
 security/selinux/ss/services.c      |   62 +++++++++++++++++++++++---
 9 files changed, 84 insertions(+), 59 deletions(-)

diff -pruN security-testing-2.6/security/selinux/include/security.h security-testing-2.6-new/security/selinux/include/security.h
--- security-testing-2.6/security/selinux/include/security.h	2010-01-29 02:02:47.737045258 +0100
+++ security-testing-2.6-new/security/selinux/include/security.h	2010-02-01 23:12:28.898233272 +0100
@@ -57,7 +57,6 @@
 struct netlbl_lsm_secattr;
 
 extern int selinux_enabled;
-extern int selinux_mls_enabled;
 
 /* Policy capabilities */
 enum {
@@ -80,6 +79,8 @@ extern int selinux_policycap_openperm;
 /* limitation of boundary depth  */
 #define POLICYDB_BOUNDS_MAXDEPTH	4
 
+int security_mls_enabled(void);
+
 int security_load_policy(void *data, size_t len);
 
 int security_policycap_supported(unsigned int req_cap);
diff -pruN security-testing-2.6/security/selinux/selinuxfs.c security-testing-2.6-new/security/selinux/selinuxfs.c
--- security-testing-2.6/security/selinux/selinuxfs.c	2010-01-29 02:02:47.738046835 +0100
+++ security-testing-2.6-new/security/selinux/selinuxfs.c	2010-02-01 22:06:21.709234039 +0100
@@ -282,7 +282,8 @@ static ssize_t sel_read_mls(struct file 
 	char tmpbuf[TMPBUFLEN];
 	ssize_t length;
 
-	length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_mls_enabled);
+	length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
+			   security_mls_enabled());
 	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
 }
 
diff -pruN security-testing-2.6/security/selinux/ss/context.h security-testing-2.6-new/security/selinux/ss/context.h
--- security-testing-2.6/security/selinux/ss/context.h	2010-01-29 01:06:42.160060332 +0100
+++ security-testing-2.6-new/security/selinux/ss/context.h	2010-02-02 21:49:41.210011207 +0100
@@ -41,9 +41,6 @@ static inline int mls_context_cpy(struct
 {
 	int rc;
 
-	if (!selinux_mls_enabled)
-		return 0;
-
 	dst->range.level[0].sens = src->range.level[0].sens;
 	rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
 	if (rc)
@@ -64,9 +61,6 @@ static inline int mls_context_cpy_low(st
 {
 	int rc;
 
-	if (!selinux_mls_enabled)
-		return 0;
-
 	dst->range.level[0].sens = src->range.level[0].sens;
 	rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
 	if (rc)
@@ -82,9 +76,6 @@ out:
 
 static inline int mls_context_cmp(struct context *c1, struct context *c2)
 {
-	if (!selinux_mls_enabled)
-		return 1;
-
 	return ((c1->range.level[0].sens == c2->range.level[0].sens) &&
 		ebitmap_cmp(&c1->range.level[0].cat, &c2->range.level[0].cat) &&
 		(c1->range.level[1].sens == c2->range.level[1].sens) &&
@@ -93,9 +84,6 @@ static inline int mls_context_cmp(struct
 
 static inline void mls_context_destroy(struct context *c)
 {
-	if (!selinux_mls_enabled)
-		return;
-
 	ebitmap_destroy(&c->range.level[0].cat);
 	ebitmap_destroy(&c->range.level[1].cat);
 	mls_context_init(c);
diff -pruN security-testing-2.6/security/selinux/ss/mls.c security-testing-2.6-new/security/selinux/ss/mls.c
--- security-testing-2.6/security/selinux/ss/mls.c	2010-01-29 02:02:47.739046177 +0100
+++ security-testing-2.6-new/security/selinux/ss/mls.c	2010-02-01 22:15:48.062233721 +0100
@@ -39,7 +39,7 @@ int mls_compute_context_len(struct conte
 	struct ebitmap *e;
 	struct ebitmap_node *node;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;
 
 	len = 1; /* for the beginning ":" */
@@ -93,7 +93,7 @@ void mls_sid_to_context(struct context *
 	struct ebitmap *e;
 	struct ebitmap_node *node;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return;
 
 	scontextp = *scontext;
@@ -200,7 +200,7 @@ int mls_context_isvalid(struct policydb 
 {
 	struct user_datum *usrdatum;
 
-	if (!selinux_mls_enabled)
+	if (!p->mls_enabled)
 		return 1;
 
 	if (!mls_range_isvalid(p, &c->range))
@@ -253,7 +253,7 @@ int mls_context_to_sid(struct policydb *
 	struct cat_datum *catdatum, *rngdatum;
 	int l, rc = -EINVAL;
 
-	if (!selinux_mls_enabled) {
+	if (!pol->mls_enabled) {
 		if (def_sid != SECSID_NULL && oldc)
 			*scontext += strlen(*scontext)+1;
 		return 0;
@@ -387,7 +387,7 @@ int mls_from_string(char *str, struct co
 	char *tmpstr, *freestr;
 	int rc;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return -EINVAL;
 
 	/* we need freestr because mls_context_to_sid will change
@@ -407,7 +407,7 @@ int mls_from_string(char *str, struct co
 /*
  * Copies the MLS range `range' into `context'.
  */
-static inline int mls_range_set(struct context *context,
+int mls_range_set(struct context *context,
 				struct mls_range *range)
 {
 	int l, rc = 0;
@@ -427,7 +427,7 @@ static inline int mls_range_set(struct c
 int mls_setup_user_range(struct context *fromcon, struct user_datum *user,
 			 struct context *usercon)
 {
-	if (selinux_mls_enabled) {
+	if (policydb.mls_enabled) {
 		struct mls_level *fromcon_sen = &(fromcon->range.level[0]);
 		struct mls_level *fromcon_clr = &(fromcon->range.level[1]);
 		struct mls_level *user_low = &(user->range.level[0]);
@@ -477,7 +477,7 @@ int mls_convert_context(struct policydb 
 	struct ebitmap_node *node;
 	int l, i;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;
 
 	for (l = 0; l < 2; l++) {
@@ -516,7 +516,7 @@ int mls_compute_sid(struct context *scon
 	struct range_trans rtr;
 	struct mls_range *r;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;
 
 	switch (specified) {
@@ -559,7 +559,7 @@ int mls_compute_sid(struct context *scon
 void mls_export_netlbl_lvl(struct context *context,
 			   struct netlbl_lsm_secattr *secattr)
 {
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return;
 
 	secattr->attr.mls.lvl = context->range.level[0].sens - 1;
@@ -579,7 +579,7 @@ void mls_export_netlbl_lvl(struct contex
 void mls_import_netlbl_lvl(struct context *context,
 			   struct netlbl_lsm_secattr *secattr)
 {
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return;
 
 	context->range.level[0].sens = secattr->attr.mls.lvl + 1;
@@ -601,7 +601,7 @@ int mls_export_netlbl_cat(struct context
 {
 	int rc;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;
 
 	rc = ebitmap_netlbl_export(&context->range.level[0].cat,
@@ -629,7 +629,7 @@ int mls_import_netlbl_cat(struct context
 {
 	int rc;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;
 
 	rc = ebitmap_netlbl_import(&context->range.level[0].cat,
diff -pruN security-testing-2.6/security/selinux/ss/mls.h security-testing-2.6-new/security/selinux/ss/mls.h
--- security-testing-2.6/security/selinux/ss/mls.h	2010-01-29 01:06:42.168051431 +0100
+++ security-testing-2.6-new/security/selinux/ss/mls.h	2010-02-01 23:17:31.025223083 +0100
@@ -39,6 +39,8 @@ int mls_context_to_sid(struct policydb *
 
 int mls_from_string(char *str, struct context *context, gfp_t gfp_mask);
 
+int mls_range_set(struct context *context, struct mls_range *range);
+
 int mls_convert_context(struct policydb *oldp,
 			struct policydb *newp,
 			struct context *context);
diff -pruN security-testing-2.6/security/selinux/ss/mls_types.h security-testing-2.6-new/security/selinux/ss/mls_types.h
--- security-testing-2.6/security/selinux/ss/mls_types.h	2010-01-29 01:06:42.168051431 +0100
+++ security-testing-2.6-new/security/selinux/ss/mls_types.h	2010-02-02 21:49:54.108993602 +0100
@@ -15,6 +15,7 @@
 #define _SS_MLS_TYPES_H_
 
 #include "security.h"
+#include "ebitmap.h"
 
 struct mls_level {
 	u32 sens;		/* sensitivity */
@@ -27,18 +28,12 @@ struct mls_range {
 
 static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2)
 {
-	if (!selinux_mls_enabled)
-		return 1;
-
 	return ((l1->sens == l2->sens) &&
 		ebitmap_cmp(&l1->cat, &l2->cat));
 }
 
 static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2)
 {
-	if (!selinux_mls_enabled)
-		return 1;
-
 	return ((l1->sens >= l2->sens) &&
 		ebitmap_contains(&l1->cat, &l2->cat));
 }
diff -pruN security-testing-2.6/security/selinux/ss/policydb.c security-testing-2.6-new/security/selinux/ss/policydb.c
--- security-testing-2.6/security/selinux/ss/policydb.c	2010-01-29 02:02:47.740046077 +0100
+++ security-testing-2.6-new/security/selinux/ss/policydb.c	2010-02-01 22:12:18.601226073 +0100
@@ -52,8 +52,6 @@ static char *symtab_name[SYM_NUM] = {
 };
 #endif
 
-int selinux_mls_enabled;
-
 static unsigned int symtab_sizes[SYM_NUM] = {
 	2,
 	32,
@@ -455,7 +453,7 @@ static int policydb_index_others(struct 
 
 	printk(KERN_DEBUG "SELinux:  %d users, %d roles, %d types, %d bools",
 	       p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim);
-	if (selinux_mls_enabled)
+	if (p->mls_enabled)
 		printk(", %d sens, %d cats", p->p_levels.nprim,
 		       p->p_cats.nprim);
 	printk("\n");
@@ -1717,14 +1715,12 @@ int policydb_read(struct policydb *p, vo
 	int i, j, rc;
 	__le32 buf[4];
 	u32 nodebuf[8];
-	u32 len, len2, config, nprim, nel, nel2;
+	u32 len, len2, nprim, nel, nel2;
 	char *policydb_str;
 	struct policydb_compat_info *info;
 	struct range_trans *rt;
 	struct mls_range *r;
 
-	config = 0;
-
 	rc = policydb_init(p);
 	if (rc)
 		goto out;
@@ -1772,7 +1768,7 @@ int policydb_read(struct policydb *p, vo
 	kfree(policydb_str);
 	policydb_str = NULL;
 
-	/* Read the version, config, and table sizes. */
+	/* Read the version and table sizes. */
 	rc = next_entry(buf, fp, sizeof(u32)*4);
 	if (rc < 0)
 		goto bad;
@@ -1787,13 +1783,7 @@ int policydb_read(struct policydb *p, vo
 	}
 
 	if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) {
-		if (ss_initialized && !selinux_mls_enabled) {
-			printk(KERN_ERR "SELinux: Cannot switch between non-MLS"
-				" and MLS policies\n");
-			goto bad;
-		}
-		selinux_mls_enabled = 1;
-		config |= POLICYDB_CONFIG_MLS;
+		p->mls_enabled = 1;
 
 		if (p->policyvers < POLICYDB_VERSION_MLS) {
 			printk(KERN_ERR "SELinux: security policydb version %d "
@@ -1801,12 +1791,6 @@ int policydb_read(struct policydb *p, vo
 				p->policyvers);
 			goto bad;
 		}
-	} else {
-		if (ss_initialized && selinux_mls_enabled) {
-			printk(KERN_ERR "SELinux: Cannot switch between MLS and"
-				" non-MLS policies\n");
-			goto bad;
-		}
 	}
 	p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN);
 	p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);
diff -pruN security-testing-2.6/security/selinux/ss/policydb.h security-testing-2.6-new/security/selinux/ss/policydb.h
--- security-testing-2.6/security/selinux/ss/policydb.h	2010-01-29 02:02:47.740046077 +0100
+++ security-testing-2.6-new/security/selinux/ss/policydb.h	2010-02-01 20:47:08.352232380 +0100
@@ -27,6 +27,8 @@
 #include "symtab.h"
 #include "avtab.h"
 #include "sidtab.h"
+#include "ebitmap.h"
+#include "mls_types.h"
 #include "context.h"
 #include "constraint.h"
 
@@ -185,6 +187,8 @@ struct genfs {
 
 /* The policy database */
 struct policydb {
+	int mls_enabled;
+
 	/* symbol tables */
 	struct symtab symtab[SYM_NUM];
 #define p_commons symtab[SYM_COMMONS]
diff -pruN security-testing-2.6/security/selinux/ss/services.c security-testing-2.6-new/security/selinux/ss/services.c
--- security-testing-2.6/security/selinux/ss/services.c	2010-01-29 02:02:47.742042805 +0100
+++ security-testing-2.6-new/security/selinux/ss/services.c	2010-02-02 23:48:07.637994777 +0100
@@ -26,6 +26,10 @@
  *
  *  Added support for bounds domain and audit messaged on masked permissions
  *
+ * Updated: Guido Trentalancia <guido@trentalancia.com>
+ *
+ *  Added support for runtime switching of the policy type
+ *
  * Copyright (C) 2008, 2009 NEC Corporation
  * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P.
  * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
@@ -232,6 +236,10 @@ static void map_decision(u16 tclass, str
 	}
 }
 
+int security_mls_enabled(void)
+{
+	return policydb.mls_enabled;
+}
 
 /*
  * Return the boolean value of a constraint expression
@@ -1547,6 +1555,8 @@ static int convert_context(u32 key,
 {
 	struct convert_context_args *args;
 	struct context oldc;
+	struct ocontext *oc;
+	struct mls_range *range;
 	struct role_datum *role;
 	struct type_datum *typdatum;
 	struct user_datum *usrdatum;
@@ -1614,9 +1624,39 @@ static int convert_context(u32 key,
 		goto bad;
 	c->type = typdatum->value;
 
-	rc = mls_convert_context(args->oldp, args->newp, c);
-	if (rc)
-		goto bad;
+	/* Convert the MLS fields if dealing with MLS policies */
+	if (args->oldp->mls_enabled && args->newp->mls_enabled) {
+		rc = mls_convert_context(args->oldp, args->newp, c);
+		if (rc)
+			goto bad;
+	} else if (args->oldp->mls_enabled && !args->newp->mls_enabled) {
+		/*
+		 * Switching between MLS and non-MLS policy:
+		 * free any storage used by the MLS fields in the
+		 * context for all existing entries in the sidtab.
+		 */
+		mls_context_destroy(c);
+	} else if (!args->oldp->mls_enabled && args->newp->mls_enabled) {
+		/*
+		 * Switching between non-MLS and MLS policy:
+		 * ensure that the MLS fields of the context for all
+		 * existing entries in the sidtab are filled in with a
+		 * suitable default value, likely taken from one of the
+		 * initial SIDs.
+		 */
+		oc = args->newp->ocontexts[OCON_ISID];
+		while (oc && oc->sid[0] != SECINITSID_UNLABELED)
+			oc = oc->next;
+		if (!oc) {
+			printk(KERN_ERR "SELinux:  unable to look up"
+				" the initial SIDs list\n");
+			goto bad;
+		}
+		range = &oc->context[0].range;
+		rc = mls_range_set(c, range);
+		if (rc)
+			goto bad;
+	}
 
 	/* Check the validity of the new context. */
 	if (!policydb_context_isvalid(args->newp, c)) {
@@ -1712,6 +1752,12 @@ int security_load_policy(void *data, siz
 	if (policydb_read(&newpolicydb, fp))
 		return -EINVAL;
 
+	/* If switching between different policy types, log MLS status */
+	if (policydb.mls_enabled && !newpolicydb.mls_enabled)
+		printk(KERN_INFO "SELinux: Disabling MLS support...\n");
+	else if (!policydb.mls_enabled && newpolicydb.mls_enabled)
+		printk(KERN_INFO "SELinux: Enabling MLS support...\n");
+
 	if (sidtab_init(&newsidtab)) {
 		policydb_destroy(&newpolicydb);
 		return -ENOMEM;
@@ -1741,8 +1787,12 @@ int security_load_policy(void *data, siz
 	args.oldp = &policydb;
 	args.newp = &newpolicydb;
 	rc = sidtab_map(&newsidtab, convert_context, &args);
-	if (rc)
+	if (rc) {
+		printk(KERN_ERR "SELinux:  unable to convert the internal"
+			" representation of contexts in the new SID"
+			" table\n");
 		goto err;
+	}
 
 	/* Save the old policydb and SID table to free later. */
 	memcpy(&oldpolicydb, &policydb, sizeof policydb);
@@ -2338,7 +2388,7 @@ int security_sid_mls_copy(u32 sid, u32 m
 	u32 len;
 	int rc = 0;
 
-	if (!ss_initialized || !selinux_mls_enabled) {
+	if (!ss_initialized || !policydb.mls_enabled) {
 		*new_sid = sid;
 		goto out;
 	}
@@ -2439,7 +2489,7 @@ int security_net_peersid_resolve(u32 nlb
 	/* we don't need to check ss_initialized here since the only way both
 	 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the
 	 * security server was initialized and ss_initialized was true */
-	if (!selinux_mls_enabled) {
+	if (!policydb.mls_enabled) {
 		*peer_sid = SECSID_NULL;
 		return 0;
 	}



--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
  2010-02-02 19:03     ` Stephen Smalley
@ 2010-02-02 19:11       ` Stephen Smalley
  0 siblings, 0 replies; 33+ messages in thread
From: Stephen Smalley @ 2010-02-02 19:11 UTC (permalink / raw)
  To: Guido Trentalancia; +Cc: selinux

On Tue, 2010-02-02 at 14:03 -0500, Stephen Smalley wrote:
> On Tue, 2010-02-02 at 19:28 +0100, Guido Trentalancia wrote:
> > Stephen,
> > 
> > did you mean something like the code below when mentioning about the
> > initial SID issue ? I remember you mentioned about matching oc->sid[0]
> > with the argument key of convert_context, so we can first scan for the
> > "unlabeled" SID and copy the MLS range only (as done in the previous
> > patch) and then afterwards if we find a match with the key argument, we
> > can copy the whole context over.
> > 
> > On Tue, 2010-02-02 at 11:44 -0500, Stephen Smalley wrote:
> > > On Tue, 2010-02-02 at 15:22 +0100, Guido Trentalancia wrote:
> > > Did you give up on addressing the initial SID issue or are you saving
> > > that for a later, separate patch?
> > 
> > 	/*
> > 	 * Switching between non-MLS and MLS policy:
> > 	 * ensure that the MLS fields of the context for all
> > 	 * existing entries in the sidtab are filled in with a
> > 	 * suitable default value, likely taken from one of the
> > 	 * initial SIDs.
> > 	 */
> > 	else if (!args->oldp->mls_enabled && args->newp->mls_enabled) {
> > 		int number_of_isids = 0;
> > 		int matching_key = 0;
> > 		oc = args->newp->ocontexts[OCON_ISID];
> > 		while (oc) {
> > 			if (oc->sid[0] == key)
> > 				matching_key = 1;
> > 			oc = oc->next;
> > 			number_of_isids = number_of_isids + 1;
> > 		}
> > 		oc = args->newp->ocontexts[OCON_ISID];
> > 		if (!matching_key) {
> > 			while (oc && oc->sid[0] != SECINITSID_UNLABELED)
> > 				oc = oc->next;
> > 			if (!oc) {
> > 				printk(KERN_ERR "SELinux:  unable to look up"
> > 					" the initial SIDs list\n");
> > 				goto bad;
> > 			}
> > 			range = &oc->context[0].range;
> > 			/* set only the MLS range from "unlabeled" */
> > 			rc = mls_range_set(c, range);
> > 			if (rc)
> > 				goto bad;
> > 		} else {
> > 			while (oc && oc->sid[0] != key)
> > 				oc = oc->next;
> > 			/* copy the whole context */
> > 			rc = context_cpy(c, oc->context[0]);
> > 			if (rc)
> > 				goto bad;
> > 		}
> > 	}
> > 
> > I look forward to hearing from you about the above issue.
> 
> We later talked about using policydb_load_isids().  See:
> http://marc.info/?l=selinux&m=126505150603677&w=2
> 
> This would be more general and would address reloading of initial SIDs
> even when staying within the same kind of policy.

Let's leave that for a separate, later patch though.

-- 
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 majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
  2010-02-02 18:28   ` Guido Trentalancia
@ 2010-02-02 19:03     ` Stephen Smalley
  2010-02-02 19:11       ` Stephen Smalley
  0 siblings, 1 reply; 33+ messages in thread
From: Stephen Smalley @ 2010-02-02 19:03 UTC (permalink / raw)
  To: Guido Trentalancia; +Cc: selinux

On Tue, 2010-02-02 at 19:28 +0100, Guido Trentalancia wrote:
> Stephen,
> 
> did you mean something like the code below when mentioning about the
> initial SID issue ? I remember you mentioned about matching oc->sid[0]
> with the argument key of convert_context, so we can first scan for the
> "unlabeled" SID and copy the MLS range only (as done in the previous
> patch) and then afterwards if we find a match with the key argument, we
> can copy the whole context over.
> 
> On Tue, 2010-02-02 at 11:44 -0500, Stephen Smalley wrote:
> > On Tue, 2010-02-02 at 15:22 +0100, Guido Trentalancia wrote:
> > Did you give up on addressing the initial SID issue or are you saving
> > that for a later, separate patch?
> 
> 	/*
> 	 * Switching between non-MLS and MLS policy:
> 	 * ensure that the MLS fields of the context for all
> 	 * existing entries in the sidtab are filled in with a
> 	 * suitable default value, likely taken from one of the
> 	 * initial SIDs.
> 	 */
> 	else if (!args->oldp->mls_enabled && args->newp->mls_enabled) {
> 		int number_of_isids = 0;
> 		int matching_key = 0;
> 		oc = args->newp->ocontexts[OCON_ISID];
> 		while (oc) {
> 			if (oc->sid[0] == key)
> 				matching_key = 1;
> 			oc = oc->next;
> 			number_of_isids = number_of_isids + 1;
> 		}
> 		oc = args->newp->ocontexts[OCON_ISID];
> 		if (!matching_key) {
> 			while (oc && oc->sid[0] != SECINITSID_UNLABELED)
> 				oc = oc->next;
> 			if (!oc) {
> 				printk(KERN_ERR "SELinux:  unable to look up"
> 					" the initial SIDs list\n");
> 				goto bad;
> 			}
> 			range = &oc->context[0].range;
> 			/* set only the MLS range from "unlabeled" */
> 			rc = mls_range_set(c, range);
> 			if (rc)
> 				goto bad;
> 		} else {
> 			while (oc && oc->sid[0] != key)
> 				oc = oc->next;
> 			/* copy the whole context */
> 			rc = context_cpy(c, oc->context[0]);
> 			if (rc)
> 				goto bad;
> 		}
> 	}
> 
> I look forward to hearing from you about the above issue.

We later talked about using policydb_load_isids().  See:
http://marc.info/?l=selinux&m=126505150603677&w=2

This would be more general and would address reloading of initial SIDs
even when staying within the same kind of policy.

-- 
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 majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
  2010-02-02 17:49       ` Guido Trentalancia
@ 2010-02-02 19:01         ` Stephen Smalley
  0 siblings, 0 replies; 33+ messages in thread
From: Stephen Smalley @ 2010-02-02 19:01 UTC (permalink / raw)
  To: Guido Trentalancia; +Cc: selinux

On Tue, 2010-02-02 at 18:49 +0100, Guido Trentalancia wrote:
> Well, after you told me to do that, we have context_destroy() calling
> mls_context_destroy(), which in turn calls:
> 
> ebitmap_destroy(&c->range.level[i].cat);   for i={0,1}
> memset(&c->range, 0, sizeof(c->range));
> 
> But in the case of a standard policy, there is no range field I suppose.

struct context is defined in context.h and always has a struct mls_range
range field (that was made unconditional when MLS support was turned
into a runtime option rather than a compile-time option).
context_init() always clears the entire structure, so all fields should
be initialized to zero.

A struct mls_range is an array of mls_level structures with two elements
(for the low and high).  A struct mls_level is an unsigned integer
sensitivity value and a struct ebitmap category set.  A struct ebitmap
is a node pointer and an unsigned integer highbit.

So if the structure was properly initialized, we should have an ebitmap
with a NULL node pointer and a 0 highbit value.  In that situation,
ebitmap_destroy() should merely re-clear the two fields and return
without any difficulty.

-- 
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 majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
  2010-02-02 16:44 ` Stephen Smalley
  2010-02-02 16:58   ` Guido Trentalancia
@ 2010-02-02 18:28   ` Guido Trentalancia
  2010-02-02 19:03     ` Stephen Smalley
  1 sibling, 1 reply; 33+ messages in thread
From: Guido Trentalancia @ 2010-02-02 18:28 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: selinux

Stephen,

did you mean something like the code below when mentioning about the
initial SID issue ? I remember you mentioned about matching oc->sid[0]
with the argument key of convert_context, so we can first scan for the
"unlabeled" SID and copy the MLS range only (as done in the previous
patch) and then afterwards if we find a match with the key argument, we
can copy the whole context over.

On Tue, 2010-02-02 at 11:44 -0500, Stephen Smalley wrote:
> On Tue, 2010-02-02 at 15:22 +0100, Guido Trentalancia wrote:
> Did you give up on addressing the initial SID issue or are you saving
> that for a later, separate patch?

	/*
	 * Switching between non-MLS and MLS policy:
	 * ensure that the MLS fields of the context for all
	 * existing entries in the sidtab are filled in with a
	 * suitable default value, likely taken from one of the
	 * initial SIDs.
	 */
	else if (!args->oldp->mls_enabled && args->newp->mls_enabled) {
		int number_of_isids = 0;
		int matching_key = 0;
		oc = args->newp->ocontexts[OCON_ISID];
		while (oc) {
			if (oc->sid[0] == key)
				matching_key = 1;
			oc = oc->next;
			number_of_isids = number_of_isids + 1;
		}
		oc = args->newp->ocontexts[OCON_ISID];
		if (!matching_key) {
			while (oc && oc->sid[0] != SECINITSID_UNLABELED)
				oc = oc->next;
			if (!oc) {
				printk(KERN_ERR "SELinux:  unable to look up"
					" the initial SIDs list\n");
				goto bad;
			}
			range = &oc->context[0].range;
			/* set only the MLS range from "unlabeled" */
			rc = mls_range_set(c, range);
			if (rc)
				goto bad;
		} else {
			while (oc && oc->sid[0] != key)
				oc = oc->next;
			/* copy the whole context */
			rc = context_cpy(c, oc->context[0]);
			if (rc)
				goto bad;
		}
	}

I look forward to hearing from you about the above issue.

Regards,

Guido


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
  2010-02-02 17:34     ` Stephen Smalley
@ 2010-02-02 17:49       ` Guido Trentalancia
  2010-02-02 19:01         ` Stephen Smalley
  0 siblings, 1 reply; 33+ messages in thread
From: Guido Trentalancia @ 2010-02-02 17:49 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: selinux

Hello again !

On Tue, 2010-02-02 at 12:34 -0500, Stephen Smalley wrote:
> On Tue, 2010-02-02 at 17:58 +0100, Guido Trentalancia wrote:
> > Hello again !
> > 
> > On Tue, 2010-02-02 at 11:44 -0500, Stephen Smalley wrote:
> You can't digitally sign the message w/o causing the inlined patch to be
> encoded.  So don't digitally sign patch postings.

That's fine. I won't sign patch postings anymore.

> That's ok.  checkpatch is just advisory; it still falls to a person to
> make the final judgment.

Ok.

> > Please let me know about the oops for ebitmap_destroy(). Do you think it
> > is due to the initial SID issue rather than to calling mls_destroy() for
> > a standard policy ? I wasn't saving that for a separate patch, it's just
> > that we did not discuss that further...
> 
> I'd rather track down the cause and see if we can allow
> mls_context_destroy() to be unconditionally safe.  In fact, I'm tempted
> to drop the mls_enabled tests from all of those inline functions and
> just ensure that the fields are always properly initialized and thus the
> functions will just evaluate properly even in the non-MLS case.

Well, after you told me to do that, we have context_destroy() calling
mls_context_destroy(), which in turn calls:

ebitmap_destroy(&c->range.level[i].cat);   for i={0,1}
memset(&c->range, 0, sizeof(c->range));

But in the case of a standard policy, there is no range field I suppose.

> Chris is correct btw - the kernel has no notions of "standard", or
> "MCS".  It only knows about MLS-enabled vs MLS-disabled.

Ok. So, I have now changed the message accordingly. Thanks again Chris
for pointing that out !

By the way, I think I have now got confused about the initial SID issue
that you mentioned earlier on... Could you please be more specific ? You
should know what the code looks like at the moment in ss/services.c.

Regards,

Guido



--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
  2010-02-02 16:58   ` Guido Trentalancia
@ 2010-02-02 17:34     ` Stephen Smalley
  2010-02-02 17:49       ` Guido Trentalancia
  0 siblings, 1 reply; 33+ messages in thread
From: Stephen Smalley @ 2010-02-02 17:34 UTC (permalink / raw)
  To: Guido Trentalancia; +Cc: selinux

On Tue, 2010-02-02 at 17:58 +0100, Guido Trentalancia wrote:
> Hello again !
> 
> On Tue, 2010-02-02 at 11:44 -0500, Stephen Smalley wrote:
> > On Tue, 2010-02-02 at 15:22 +0100, Guido Trentalancia wrote:
> > Patch mangled by your mail client, probably because you signed it.
> > Read and follow the instructions in Documentation/email-clients.txt, or
> > switch to another client.  In the case of Evolution, for example, you
> > set the paragraph style to Preformat and then use Insert->Text File to
> > insert the patch into the message.  To test, email it to yourself, save
> > the email message and try applying it.
> 
> That's really odd. I have followed the advice in
> Documentation/email-clients.txt which you quoted... I don't know what
> else to do. Perhaps, I can send the final version as an attachment to
> the list and then you can forward that to the kernel mailing list ?

You can't digitally sign the message w/o causing the inlined patch to be
encoded.  So don't digitally sign patch postings.

> That's what I did, but then checkpatch.pl was complaining about the {}
> block with a single statement (in disagreement with CodingStyle, so it's
> an inconsistency in the script with respect to the guidelines). I can do
> that easily, but then we'll get a warning !

That's ok.  checkpatch is just advisory; it still falls to a person to
make the final judgment.

> Please let me know about the oops for ebitmap_destroy(). Do you think it
> is due to the initial SID issue rather than to calling mls_destroy() for
> a standard policy ? I wasn't saving that for a separate patch, it's just
> that we did not discuss that further...

I'd rather track down the cause and see if we can allow
mls_context_destroy() to be unconditionally safe.  In fact, I'm tempted
to drop the mls_enabled tests from all of those inline functions and
just ensure that the fields are always properly initialized and thus the
functions will just evaluate properly even in the non-MLS case.

Chris is correct btw - the kernel has no notions of "standard", or
"MCS".  It only knows about MLS-enabled vs MLS-disabled.

-- 
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 majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
  2010-02-02 16:44 ` Stephen Smalley
@ 2010-02-02 16:58   ` Guido Trentalancia
  2010-02-02 17:34     ` Stephen Smalley
  2010-02-02 18:28   ` Guido Trentalancia
  1 sibling, 1 reply; 33+ messages in thread
From: Guido Trentalancia @ 2010-02-02 16:58 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: selinux

Hello again !

On Tue, 2010-02-02 at 11:44 -0500, Stephen Smalley wrote:
> On Tue, 2010-02-02 at 15:22 +0100, Guido Trentalancia wrote:
> Patch mangled by your mail client, probably because you signed it.
> Read and follow the instructions in Documentation/email-clients.txt, or
> switch to another client.  In the case of Evolution, for example, you
> set the paragraph style to Preformat and then use Insert->Text File to
> insert the patch into the message.  To test, email it to yourself, save
> the email message and try applying it.

That's really odd. I have followed the advice in
Documentation/email-clients.txt which you quoted... I don't know what
else to do. Perhaps, I can send the final version as an attachment to
the list and then you can forward that to the kernel mailing list ?

> You want a "---" line before the diffstat output so that it doesn't get
> included in the git log.

That's fine. I'll add such a line between the description and the
diffstat output.

> Did you give up on addressing the initial SID issue or are you saving
> that for a later, separate patch?
> 
> Technically, security_mls_enabled() does not return True or False; it
> returns 1 or 0.

Yes, of course, I was just following your style since the next function
comments "boolean" (read "integer to be interpreted as a boolean").
However I have now changed the comment.

> Your if (args->oldp->mls_enabled...)else if...else block is hard to read
> with the comment placement.  I'd move them within the conditional block
> and use { } for all three clauses for ease of reading.

That's what I did, but then checkpatch.pl was complaining about the {}
block with a single statement (in disagreement with CodingStyle, so it's
an inconsistency in the script with respect to the guidelines). I can do
that easily, but then we'll get a warning !

Please let me know about the oops for ebitmap_destroy(). Do you think it
is due to the initial SID issue rather than to calling mls_destroy() for
a standard policy ? I wasn't saving that for a separate patch, it's just
that we did not discuss that further...

Regards,

Guido



--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
  2010-02-02 16:29 Guido Trentalancia
@ 2010-02-02 16:52 ` Christopher J. PeBenito
  0 siblings, 0 replies; 33+ messages in thread
From: Christopher J. PeBenito @ 2010-02-02 16:52 UTC (permalink / raw)
  To: Guido Trentalancia; +Cc: Stephen Smalley, selinux

On Tue, 2010-02-02 at 17:29 +0100, Guido Trentalancia wrote:
> Stephen,
> 
> the latest patch for runtime switching of different policy types fails
> with:
> 
> SELinux: Switching between standard and MLS/MCS policy...

I have a nit on this message.  There is no concept of MCS in the kernel.
MCS is just a specific policy configuration of MLS.  If you feel the
need to have a message it should probably just say something about
enabling/disabling MLS support, not a "switching between policies"
message, since its already in the middle of a policy load.


-- 
Chris PeBenito
Tresys Technology, LLC
(410) 290-1411 x150



--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
  2010-02-02 14:22 Guido Trentalancia
@ 2010-02-02 16:44 ` Stephen Smalley
  2010-02-02 16:58   ` Guido Trentalancia
  2010-02-02 18:28   ` Guido Trentalancia
  0 siblings, 2 replies; 33+ messages in thread
From: Stephen Smalley @ 2010-02-02 16:44 UTC (permalink / raw)
  To: Guido Trentalancia; +Cc: selinux

On Tue, 2010-02-02 at 15:22 +0100, Guido Trentalancia wrote:
> Author: Guido Trentalancia <guido@trentalancia.com>
> Date:   Mon Feb 02 14:23:05 2010 +0100
> 
>     Allow runtime switching between different policy types (e.g. from a MLS/MCS
>     policy to a non-MLS/non-MCS policy or viceversa).
> 
>     Signed-off-by: Guido Trentalancia <guido@trentalancia.com>

Patch mangled by your mail client, probably because you signed it.
Read and follow the instructions in Documentation/email-clients.txt, or
switch to another client.  In the case of Evolution, for example, you
set the paragraph style to Preformat and then use Insert->Text File to
insert the patch into the message.  To test, email it to yourself, save
the email message and try applying it.

You want a "---" line before the diffstat output so that it doesn't get
included in the git log.

Did you give up on addressing the initial SID issue or are you saving
that for a later, separate patch?

Technically, security_mls_enabled() does not return True or False; it
returns 1 or 0.

Your if (args->oldp->mls_enabled...)else if...else block is hard to read
with the comment placement.  I'd move them within the conditional block
and use { } for all three clauses for ease of reading.

-- 
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 majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
@ 2010-02-02 16:29 Guido Trentalancia
  2010-02-02 16:52 ` Christopher J. PeBenito
  0 siblings, 1 reply; 33+ messages in thread
From: Guido Trentalancia @ 2010-02-02 16:29 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: selinux

Stephen,

the latest patch for runtime switching of different policy types fails
with:

SELinux: Switching between standard and MLS/MCS policy...
SELinux:  permission module_request in class system not defined in
policy
SELinux: the above unknown classes and permissions will be allowed
BUG: unable to handle kernel NULL pointer dereference at 000002ff
IP: [<c05190d2>] ebitmap_destroy+0x12/0x30
*pde = 00000000 
Oops: 0000 [#1] 
last sysfs file: /sys/devices/virtual/block/dm-2/range
Modules linked in: hangcheck_timer softdog ppdev lp ipv6 microcode ne
8390p ext2 snd_ens1371 snd_seq_midi snd_seq_midi_event snd_rawmidi
snd_ac97_codec ac97_bus snd_pcm snd_seq parport_pc snd_timer
snd_seq_device parport snd floppy soundcore pcspkr snd_page_alloc
i2c_piix4 sr_mod i2c_core cdrom sha256_generic aes_i586 aes_generic

Pid: 2858, comm: load_policy Not tainted (2.6.32.7 #1)  
EIP: 0060:[<c05190d2>] EFLAGS: 00010206 CPU: 0
EIP is at ebitmap_destroy+0x12/0x30
EAX: 000002ff EBX: 00000000 ECX: 00000000 EDX: 00000000
ESI: c7097cb8 EDI: c7097ca4 EBP: 00000000 ESP: c7097c60
 DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 0068
Process load_policy (pid: 2858, ti=c7097000 task=c736c000
task.ti=c7097000)
Stack:
 00000000 00000000 c0521831 c107bbc0 c048c5ce 00000000 c0803734 c08034f8
<0> 00000020 ffffffff c3dde000 00000020 00000000 00000020 00000202
c219afc0
<0> 00000040 00000000 00000000 00000000 00000000 000001a0 000002ff
c7097ed8
Call Trace:
 [<c0521831>] ? convert_context+0x271/0x350
 [<c048c5ce>] ? __slab_alloc+0x24e/0x540
 [<c0519eb7>] ? sidtab_insert+0xb7/0x1a0
 [<c0520345>] ? security_load_policy+0x265/0x430
 [<c05215c0>] ? convert_context+0x0/0x350
 [<c0519bd0>] ? sidtab_map+0x40/0x70
 [<c05203eb>] ? security_load_policy+0x30b/0x430
 [<c0479c99>] ? __do_fault+0x1f9/0x360
 [<c047a4ba>] ? handle_mm_fault+0x13a/0x550
 [<c041c245>] ? do_page_fault+0xe5/0x2f0
 [<c0404b73>] ? do_IRQ+0x43/0xb0
 [<c041c160>] ? do_page_fault+0x0/0x2f0
 [<c0708506>] ? error_code+0x5e/0x64
 [<c051007b>] ? selinux_inode_rename+0x16b/0x1c0
 [<c051773d>] ? sel_write_load+0xbd/0x630
 [<c047cc4c>] ? vma_link+0x3c/0x50
 [<c0513637>] ? selinux_file_permission+0xe7/0x140
 [<c050a9ac>] ? security_file_permission+0xc/0x10
 [<c0490b24>] ? rw_verify_area+0x64/0xd0
 [<c0517680>] ? sel_write_load+0x0/0x630
 [<c0490c38>] ? vfs_write+0xa8/0x160
 [<c04913a1>] ? sys_write+0x41/0x70
 [<c0402ee4>] ? sysenter_do_call+0x12/0x22
Code: c0 5e c3 8d b6 00 00 00 00 8b 09 eb 9a 8d 74 26 00 5b 31 c0 5e c3
8d 76 00 56 85 c0 53 89 c6 74 22 8b 00 85 c0 75 04 eb 0d 89 d8 <8b> 18
e8 c7 31 f7 ff 85 db 75 f3 c7 46 04 00 00 00 00 c7 06 00 
EIP: [<c05190d2>] ebitmap_destroy+0x12/0x30 SS:ESP 0068:c7097c60
CR2: 00000000000002ff
---[ end trace 17c3aaaa15b3b444 ]---

I suspect, we'd better reintroduce some of my changes so that the
parameter struct policydb is passed when calling
[mls_,o]context_destroy() and sidtab_destroy()... In fact, it seems like
it isn't that safe to always execute mls_context_destroy() even for a
policy which isn't MLS/MCS !

At the end, it wasn't a bad idea to have more general functions (you
never know, in the future we might find them convenient for other
purposes and logically they are more correct, because those function
should be general for any policy, not necessarily the active policy).
You mentioned about the need to change all the family of functions to
accept that extra parameter, I think this is not necessary both from a
logical point of view and a coherency point of view: we can just change
the *context_destroy() and sidtab_destroy() functions and we'll have a
working patch and a more general set of functions.

The test above has been executed on kernel 2.6.32.7 although I am sure
things won't change much with the next branch of the 2.6 security tree.

Please let me know.

Regards,

Guido Trentalancia


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
@ 2010-02-02 14:22 Guido Trentalancia
  2010-02-02 16:44 ` Stephen Smalley
  0 siblings, 1 reply; 33+ messages in thread
From: Guido Trentalancia @ 2010-02-02 14:22 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: selinux

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

Author: Guido Trentalancia <guido@trentalancia.com>
Date:   Mon Feb 02 14:23:05 2010 +0100

    Allow runtime switching between different policy types (e.g. from a MLS/MCS
    policy to a non-MLS/non-MCS policy or viceversa).

    Signed-off-by: Guido Trentalancia <guido@trentalancia.com>

 security/selinux/include/security.h |    3 -
 security/selinux/selinuxfs.c        |    3 -
 security/selinux/ss/context.h       |    9 +--
 security/selinux/ss/mls.c           |   26 ++++-----
 security/selinux/ss/mls.h           |    2 
 security/selinux/ss/mls_types.h     |    5 +
 security/selinux/ss/policydb.c      |   24 +-------
 security/selinux/ss/policydb.h      |    4 +
 security/selinux/ss/services.c      |   73 +++++++++++++++++++++++---
 9 files changed, 100 insertions(+), 49 deletions(-)

diff -pruN security-testing-2.6/security/selinux/include/security.h security-testing-2.6-new/security/selinux/include/security.h
--- security-testing-2.6/security/selinux/include/security.h	2010-01-29 02:02:47.737045258 +0100
+++ security-testing-2.6-new/security/selinux/include/security.h	2010-02-01 23:12:28.898233272 +0100
@@ -57,7 +57,6 @@
 struct netlbl_lsm_secattr;
 
 extern int selinux_enabled;
-extern int selinux_mls_enabled;
 
 /* Policy capabilities */
 enum {
@@ -80,6 +79,8 @@ extern int selinux_policycap_openperm;
 /* limitation of boundary depth  */
 #define POLICYDB_BOUNDS_MAXDEPTH	4
 
+int security_mls_enabled(void);
+
 int security_load_policy(void *data, size_t len);
 
 int security_policycap_supported(unsigned int req_cap);
diff -pruN security-testing-2.6/security/selinux/selinuxfs.c security-testing-2.6-new/security/selinux/selinuxfs.c
--- security-testing-2.6/security/selinux/selinuxfs.c	2010-01-29 02:02:47.738046835 +0100
+++ security-testing-2.6-new/security/selinux/selinuxfs.c	2010-02-01 22:06:21.709234039 +0100
@@ -282,7 +282,8 @@ static ssize_t sel_read_mls(struct file 
 	char tmpbuf[TMPBUFLEN];
 	ssize_t length;
 
-	length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_mls_enabled);
+	length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
+			   security_mls_enabled());
 	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
 }
 
diff -pruN security-testing-2.6/security/selinux/ss/context.h security-testing-2.6-new/security/selinux/ss/context.h
--- security-testing-2.6/security/selinux/ss/context.h	2010-01-29 01:06:42.160060332 +0100
+++ security-testing-2.6-new/security/selinux/ss/context.h	2010-02-01 23:13:35.857235582 +0100
@@ -41,7 +41,7 @@ static inline int mls_context_cpy(struct
 {
 	int rc;
 
-	if (!selinux_mls_enabled)
+	if (!security_mls_enabled())
 		return 0;
 
 	dst->range.level[0].sens = src->range.level[0].sens;
@@ -64,7 +64,7 @@ static inline int mls_context_cpy_low(st
 {
 	int rc;
 
-	if (!selinux_mls_enabled)
+	if (!security_mls_enabled())
 		return 0;
 
 	dst->range.level[0].sens = src->range.level[0].sens;
@@ -82,7 +82,7 @@ out:
 
 static inline int mls_context_cmp(struct context *c1, struct context *c2)
 {
-	if (!selinux_mls_enabled)
+	if (!security_mls_enabled())
 		return 1;
 
 	return ((c1->range.level[0].sens == c2->range.level[0].sens) &&
@@ -93,9 +93,6 @@ static inline int mls_context_cmp(struct
 
 static inline void mls_context_destroy(struct context *c)
 {
-	if (!selinux_mls_enabled)
-		return;
-
 	ebitmap_destroy(&c->range.level[0].cat);
 	ebitmap_destroy(&c->range.level[1].cat);
 	mls_context_init(c);
diff -pruN security-testing-2.6/security/selinux/ss/mls.c security-testing-2.6-new/security/selinux/ss/mls.c
--- security-testing-2.6/security/selinux/ss/mls.c	2010-01-29 02:02:47.739046177 +0100
+++ security-testing-2.6-new/security/selinux/ss/mls.c	2010-02-01 22:15:48.062233721 +0100
@@ -39,7 +39,7 @@ int mls_compute_context_len(struct conte
 	struct ebitmap *e;
 	struct ebitmap_node *node;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;
 
 	len = 1; /* for the beginning ":" */
@@ -93,7 +93,7 @@ void mls_sid_to_context(struct context *
 	struct ebitmap *e;
 	struct ebitmap_node *node;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return;
 
 	scontextp = *scontext;
@@ -200,7 +200,7 @@ int mls_context_isvalid(struct policydb 
 {
 	struct user_datum *usrdatum;
 
-	if (!selinux_mls_enabled)
+	if (!p->mls_enabled)
 		return 1;
 
 	if (!mls_range_isvalid(p, &c->range))
@@ -253,7 +253,7 @@ int mls_context_to_sid(struct policydb *
 	struct cat_datum *catdatum, *rngdatum;
 	int l, rc = -EINVAL;
 
-	if (!selinux_mls_enabled) {
+	if (!pol->mls_enabled) {
 		if (def_sid != SECSID_NULL && oldc)
 			*scontext += strlen(*scontext)+1;
 		return 0;
@@ -387,7 +387,7 @@ int mls_from_string(char *str, struct co
 	char *tmpstr, *freestr;
 	int rc;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return -EINVAL;
 
 	/* we need freestr because mls_context_to_sid will change
@@ -407,7 +407,7 @@ int mls_from_string(char *str, struct co
 /*
  * Copies the MLS range `range' into `context'.
  */
-static inline int mls_range_set(struct context *context,
+int mls_range_set(struct context *context,
 				struct mls_range *range)
 {
 	int l, rc = 0;
@@ -427,7 +427,7 @@ static inline int mls_range_set(struct c
 int mls_setup_user_range(struct context *fromcon, struct user_datum *user,
 			 struct context *usercon)
 {
-	if (selinux_mls_enabled) {
+	if (policydb.mls_enabled) {
 		struct mls_level *fromcon_sen = &(fromcon->range.level[0]);
 		struct mls_level *fromcon_clr = &(fromcon->range.level[1]);
 		struct mls_level *user_low = &(user->range.level[0]);
@@ -477,7 +477,7 @@ int mls_convert_context(struct policydb 
 	struct ebitmap_node *node;
 	int l, i;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;
 
 	for (l = 0; l < 2; l++) {
@@ -516,7 +516,7 @@ int mls_compute_sid(struct context *scon
 	struct range_trans rtr;
 	struct mls_range *r;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;
 
 	switch (specified) {
@@ -559,7 +559,7 @@ int mls_compute_sid(struct context *scon
 void mls_export_netlbl_lvl(struct context *context,
 			   struct netlbl_lsm_secattr *secattr)
 {
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return;
 
 	secattr->attr.mls.lvl = context->range.level[0].sens - 1;
@@ -579,7 +579,7 @@ void mls_export_netlbl_lvl(struct contex
 void mls_import_netlbl_lvl(struct context *context,
 			   struct netlbl_lsm_secattr *secattr)
 {
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return;
 
 	context->range.level[0].sens = secattr->attr.mls.lvl + 1;
@@ -601,7 +601,7 @@ int mls_export_netlbl_cat(struct context
 {
 	int rc;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;
 
 	rc = ebitmap_netlbl_export(&context->range.level[0].cat,
@@ -629,7 +629,7 @@ int mls_import_netlbl_cat(struct context
 {
 	int rc;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;
 
 	rc = ebitmap_netlbl_import(&context->range.level[0].cat,
diff -pruN security-testing-2.6/security/selinux/ss/mls.h security-testing-2.6-new/security/selinux/ss/mls.h
--- security-testing-2.6/security/selinux/ss/mls.h	2010-01-29 01:06:42.168051431 +0100
+++ security-testing-2.6-new/security/selinux/ss/mls.h	2010-02-01 23:17:31.025223083 +0100
@@ -39,6 +39,8 @@ int mls_context_to_sid(struct policydb *
 
 int mls_from_string(char *str, struct context *context, gfp_t gfp_mask);
 
+int mls_range_set(struct context *context, struct mls_range *range);
+
 int mls_convert_context(struct policydb *oldp,
 			struct policydb *newp,
 			struct context *context);
diff -pruN security-testing-2.6/security/selinux/ss/mls_types.h security-testing-2.6-new/security/selinux/ss/mls_types.h
--- security-testing-2.6/security/selinux/ss/mls_types.h	2010-01-29 01:06:42.168051431 +0100
+++ security-testing-2.6-new/security/selinux/ss/mls_types.h	2010-02-01 22:23:11.799224771 +0100
@@ -15,6 +15,7 @@
 #define _SS_MLS_TYPES_H_
 
 #include "security.h"
+#include "ebitmap.h"
 
 struct mls_level {
 	u32 sens;		/* sensitivity */
@@ -27,7 +28,7 @@ struct mls_range {
 
 static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2)
 {
-	if (!selinux_mls_enabled)
+	if (!security_mls_enabled())
 		return 1;
 
 	return ((l1->sens == l2->sens) &&
@@ -36,7 +37,7 @@ static inline int mls_level_eq(struct ml
 
 static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2)
 {
-	if (!selinux_mls_enabled)
+	if (!security_mls_enabled())
 		return 1;
 
 	return ((l1->sens >= l2->sens) &&
diff -pruN security-testing-2.6/security/selinux/ss/policydb.c security-testing-2.6-new/security/selinux/ss/policydb.c
--- security-testing-2.6/security/selinux/ss/policydb.c	2010-01-29 02:02:47.740046077 +0100
+++ security-testing-2.6-new/security/selinux/ss/policydb.c	2010-02-01 22:12:18.601226073 +0100
@@ -52,8 +52,6 @@ static char *symtab_name[SYM_NUM] = {
 };
 #endif
 
-int selinux_mls_enabled;
-
 static unsigned int symtab_sizes[SYM_NUM] = {
 	2,
 	32,
@@ -455,7 +453,7 @@ static int policydb_index_others(struct 
 
 	printk(KERN_DEBUG "SELinux:  %d users, %d roles, %d types, %d bools",
 	       p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim);
-	if (selinux_mls_enabled)
+	if (p->mls_enabled)
 		printk(", %d sens, %d cats", p->p_levels.nprim,
 		       p->p_cats.nprim);
 	printk("\n");
@@ -1717,14 +1715,12 @@ int policydb_read(struct policydb *p, vo
 	int i, j, rc;
 	__le32 buf[4];
 	u32 nodebuf[8];
-	u32 len, len2, config, nprim, nel, nel2;
+	u32 len, len2, nprim, nel, nel2;
 	char *policydb_str;
 	struct policydb_compat_info *info;
 	struct range_trans *rt;
 	struct mls_range *r;
 
-	config = 0;
-
 	rc = policydb_init(p);
 	if (rc)
 		goto out;
@@ -1772,7 +1768,7 @@ int policydb_read(struct policydb *p, vo
 	kfree(policydb_str);
 	policydb_str = NULL;
 
-	/* Read the version, config, and table sizes. */
+	/* Read the version and table sizes. */
 	rc = next_entry(buf, fp, sizeof(u32)*4);
 	if (rc < 0)
 		goto bad;
@@ -1787,13 +1783,7 @@ int policydb_read(struct policydb *p, vo
 	}
 
 	if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) {
-		if (ss_initialized && !selinux_mls_enabled) {
-			printk(KERN_ERR "SELinux: Cannot switch between non-MLS"
-				" and MLS policies\n");
-			goto bad;
-		}
-		selinux_mls_enabled = 1;
-		config |= POLICYDB_CONFIG_MLS;
+		p->mls_enabled = 1;
 
 		if (p->policyvers < POLICYDB_VERSION_MLS) {
 			printk(KERN_ERR "SELinux: security policydb version %d "
@@ -1801,12 +1791,6 @@ int policydb_read(struct policydb *p, vo
 				p->policyvers);
 			goto bad;
 		}
-	} else {
-		if (ss_initialized && selinux_mls_enabled) {
-			printk(KERN_ERR "SELinux: Cannot switch between MLS and"
-				" non-MLS policies\n");
-			goto bad;
-		}
 	}
 	p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN);
 	p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);
diff -pruN security-testing-2.6/security/selinux/ss/policydb.h security-testing-2.6-new/security/selinux/ss/policydb.h
--- security-testing-2.6/security/selinux/ss/policydb.h	2010-01-29 02:02:47.740046077 +0100
+++ security-testing-2.6-new/security/selinux/ss/policydb.h	2010-02-01 20:47:08.352232380 +0100
@@ -27,6 +27,8 @@
 #include "symtab.h"
 #include "avtab.h"
 #include "sidtab.h"
+#include "ebitmap.h"
+#include "mls_types.h"
 #include "context.h"
 #include "constraint.h"
 
@@ -185,6 +187,8 @@ struct genfs {
 
 /* The policy database */
 struct policydb {
+	int mls_enabled;
+
 	/* symbol tables */
 	struct symtab symtab[SYM_NUM];
 #define p_commons symtab[SYM_COMMONS]
diff -pruN security-testing-2.6/security/selinux/ss/services.c security-testing-2.6-new/security/selinux/ss/services.c
--- security-testing-2.6/security/selinux/ss/services.c	2010-01-29 02:02:47.742042805 +0100
+++ security-testing-2.6-new/security/selinux/ss/services.c	2010-02-02 14:28:05.222993305 +0100
@@ -26,6 +26,10 @@
  *
  *  Added support for bounds domain and audit messaged on masked permissions
  *
+ * Updated: Guido Trentalancia <guido@trentalancia.com>
+ *
+ *  Added support for runtime switching of the policy type
+ *
  * Copyright (C) 2008, 2009 NEC Corporation
  * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P.
  * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
@@ -232,6 +236,16 @@ static void map_decision(u16 tclass, str
 	}
 }
 
+/*
+ * Returns a boolean value.
+ * True: if the currently active policy is MLS or MCS
+ * False: if the currently active policy is a standard policy
+ * 	  without MLS/MCS support
+ */
+int security_mls_enabled(void)
+{
+	return policydb.mls_enabled;
+}
 
 /*
  * Return the boolean value of a constraint expression
@@ -1547,6 +1561,8 @@ static int convert_context(u32 key,
 {
 	struct convert_context_args *args;
 	struct context oldc;
+	struct ocontext *oc;
+	struct mls_range *range;
 	struct role_datum *role;
 	struct type_datum *typdatum;
 	struct user_datum *usrdatum;
@@ -1614,9 +1630,42 @@ static int convert_context(u32 key,
 		goto bad;
 	c->type = typdatum->value;
 
-	rc = mls_convert_context(args->oldp, args->newp, c);
-	if (rc)
-		goto bad;
+	/* Convert the MLS/MCS fields if dealing with MLS/MCS policies */
+	if (args->oldp->mls_enabled && args->newp->mls_enabled) {
+		rc = mls_convert_context(args->oldp, args->newp, c);
+		if (rc)
+			goto bad;
+	}
+
+	/*
+	 * Switching between MLS/MCS and non-MLS/non-MCS policy:
+	 * free any storage used by the MLS fields in the
+	 * context for all existing entries in the sidtab.
+	 */
+	else if (args->oldp->mls_enabled && !args->newp->mls_enabled)
+		mls_context_destroy(c);
+
+	/*
+	 * Switching between non-MLS/non-MCS and MLS/MCS policy:
+	 * ensure that the MLS fields of the context for all
+	 * existing entries in the sidtab are filled in with a
+	 * suitable default value, likely taken from one of the
+	 * initial SIDs.
+	 */
+	else if (!args->oldp->mls_enabled && args->newp->mls_enabled) {
+		oc = args->newp->ocontexts[OCON_ISID];
+		while (oc && oc->sid[0] != SECINITSID_UNLABELED)
+			oc = oc->next;
+		if (!oc) {
+			printk(KERN_ERR "SELinux:  unable to look up"
+				" the initial SIDs list\n");
+			goto bad;
+		}
+		range = &oc->context[0].range;
+		rc = mls_range_set(c, range);
+		if (rc)
+			goto bad;
+	}
 
 	/* Check the validity of the new context. */
 	if (!policydb_context_isvalid(args->newp, c)) {
@@ -1712,6 +1761,14 @@ int security_load_policy(void *data, siz
 	if (policydb_read(&newpolicydb, fp))
 		return -EINVAL;
 
+	/* If switching between different policy types, log it */
+	if (policydb.mls_enabled && !newpolicydb.mls_enabled)
+		printk(KERN_INFO "SELinux: Switching between MLS/MCS"
+			" and standard policy...\n");
+	else if (!policydb.mls_enabled && newpolicydb.mls_enabled)
+		printk(KERN_INFO "SELinux: Switching between standard"
+			" and MLS/MCS policy...\n");
+
 	if (sidtab_init(&newsidtab)) {
 		policydb_destroy(&newpolicydb);
 		return -ENOMEM;
@@ -1741,8 +1798,12 @@ int security_load_policy(void *data, siz
 	args.oldp = &policydb;
 	args.newp = &newpolicydb;
 	rc = sidtab_map(&newsidtab, convert_context, &args);
-	if (rc)
+	if (rc) {
+		printk(KERN_ERR "SELinux:  unable to convert the internal"
+			" representation of contexts in the new SID"
+			" table\n");
 		goto err;
+	}
 
 	/* Save the old policydb and SID table to free later. */
 	memcpy(&oldpolicydb, &policydb, sizeof policydb);
@@ -2338,7 +2399,7 @@ int security_sid_mls_copy(u32 sid, u32 m
 	u32 len;
 	int rc = 0;
 
-	if (!ss_initialized || !selinux_mls_enabled) {
+	if (!ss_initialized || !policydb.mls_enabled) {
 		*new_sid = sid;
 		goto out;
 	}
@@ -2439,7 +2500,7 @@ int security_net_peersid_resolve(u32 nlb
 	/* we don't need to check ss_initialized here since the only way both
 	 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the
 	 * security server was initialized and ss_initialized was true */
-	if (!selinux_mls_enabled) {
+	if (!policydb.mls_enabled) {
 		*peer_sid = SECSID_NULL;
 		return 0;
 	}


[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 5186 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
@ 2010-02-01 22:36 Guido Trentalancia
  2010-02-04 19:12 ` Eric Paris
  0 siblings, 1 reply; 33+ messages in thread
From: Guido Trentalancia @ 2010-02-01 22:36 UTC (permalink / raw)
  To: sds; +Cc: selinux, eparis, jmorris


[-- Attachment #1.1: Type: text/plain, Size: 17677 bytes --]

Stephen,

my reply follows your quoted text.

>On Mon, 2010-02-01 at 22:49 +0100, Guido Trentalancia wrote:
>> +	if (!args->oldp->mls_enabled && args->newp->mls_enabled) {
>> +		oc = args->newp->ocontexts[OCON_ISID];
>> +		while (oc && oc->sid[0] != SECINITSID_UNLABELED)
>> +			oc = oc->next;
>
>Just in case, I'd test if (!oc) and bail with an error.

if (!oc) {
                        printk(KERN_ERR "SELinux:  unable to look up"
                                " the initial SIDs listn");
                        goto bad;
                }

>> +		range = &oc->context[0].range;
>> +		rc = mls_range_set(c, range);
>> +		if (rc) {
>> +			if (context_struct_to_string(&oldc, &s, &len))
>> +				return -ENOMEM;
>> +			context_destroy(&oldc);
>> +			context_destroy(c);
>> +			c->str = s;
>> +			c->len = len;
>> +			printk(KERN_ERR "SELinux:  Failed to set"
>> +				" the MLS/MCS range for context"
>> +				" %sn", c->str);
>> +			goto out;
>
>goto bad ?

Ok, goto bad. It improves readability.

Final version follows. You don't like to appear as any of Acked-by, Signed-off-by or Reviewed-by ? Nobody else commented, I would say it's ready to be submitted then (has been reviewed, checks fine, builds fine, diffstat included and I will have a kernel ready in a few minutes for a final test just in case).

Author: Guido Trentalancia <guido@trentalancia.com>
Date:   Mon Feb 01 23:29:52 2010 +0100

    Allow runtime switching between different policy types (e.g. from a MLS/MCS
    policy to a non-MLS/non-MCS policy or viceversa).

    Signed-off-by: Guido Trentalancia <guido@trentalancia.com>

 security/selinux/include/security.h |    3 -
 security/selinux/selinuxfs.c        |    3 -
 security/selinux/ss/.policydb.c.swp |binary
 security/selinux/ss/context.h       |    9 +--
 security/selinux/ss/mls.c           |   26 ++++-----
 security/selinux/ss/mls.h           |    2
 security/selinux/ss/mls_types.h     |    5 +
 security/selinux/ss/policydb.c      |   24 +-------
 security/selinux/ss/policydb.h      |    4 +
 security/selinux/ss/services.c      |   74 +++++++++++++++++++++++---
 10 files changed, 101 insertions(+), 49 deletions(-)

diff -pruN security-testing-2.6/security/selinux/include/security.h security-testing-2.6-new/security/selinux/include/security.h
--- security-testing-2.6/security/selinux/include/security.h	2010-01-29 02:02:47.737045258 +0100
+++ security-testing-2.6-new/security/selinux/include/security.h	2010-02-01 23:12:28.898233272 +0100
@@ -57,7 +57,6 @@
 struct netlbl_lsm_secattr;

 extern int selinux_enabled;
-extern int selinux_mls_enabled;

 /* Policy capabilities */
 enum {
@@ -80,6 +79,8 @@ extern int selinux_policycap_openperm;
 /* limitation of boundary depth  */
 #define POLICYDB_BOUNDS_MAXDEPTH	4

+int security_mls_enabled(void);
+
 int security_load_policy(void *data, size_t len);

 int security_policycap_supported(unsigned int req_cap);
diff -pruN security-testing-2.6/security/selinux/selinuxfs.c security-testing-2.6-new/security/selinux/selinuxfs.c
--- security-testing-2.6/security/selinux/selinuxfs.c	2010-01-29 02:02:47.738046835 +0100
+++ security-testing-2.6-new/security/selinux/selinuxfs.c	2010-02-01 22:06:21.709234039 +0100
@@ -282,7 +282,8 @@ static ssize_t sel_read_mls(struct file
 	char tmpbuf[TMPBUFLEN];
 	ssize_t length;

-	length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_mls_enabled);
+	length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
+			   security_mls_enabled());
 	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
 }

diff -pruN security-testing-2.6/security/selinux/ss/context.h security-testing-2.6-new/security/selinux/ss/context.h
--- security-testing-2.6/security/selinux/ss/context.h	2010-01-29 01:06:42.160060332 +0100
+++ security-testing-2.6-new/security/selinux/ss/context.h	2010-02-01 23:13:35.857235582 +0100
@@ -41,7 +41,7 @@ static inline int mls_context_cpy(struct
 {
 	int rc;

-	if (!selinux_mls_enabled)
+	if (!security_mls_enabled())
 		return 0;

 	dst->range.level[0].sens = src->range.level[0].sens;
@@ -64,7 +64,7 @@ static inline int mls_context_cpy_low(st
 {
 	int rc;

-	if (!selinux_mls_enabled)
+	if (!security_mls_enabled())
 		return 0;

 	dst->range.level[0].sens = src->range.level[0].sens;
@@ -82,7 +82,7 @@ out:

 static inline int mls_context_cmp(struct context *c1, struct context *c2)
 {
-	if (!selinux_mls_enabled)
+	if (!security_mls_enabled())
 		return 1;

 	return ((c1->range.level[0].sens == c2->range.level[0].sens) &&
@@ -93,9 +93,6 @@ static inline int mls_context_cmp(struct

 static inline void mls_context_destroy(struct context *c)
 {
-	if (!selinux_mls_enabled)
-		return;
-
 	ebitmap_destroy(&c->range.level[0].cat);
 	ebitmap_destroy(&c->range.level[1].cat);
 	mls_context_init(c);
diff -pruN security-testing-2.6/security/selinux/ss/mls.c security-testing-2.6-new/security/selinux/ss/mls.c
--- security-testing-2.6/security/selinux/ss/mls.c	2010-01-29 02:02:47.739046177 +0100
+++ security-testing-2.6-new/security/selinux/ss/mls.c	2010-02-01 22:15:48.062233721 +0100
@@ -39,7 +39,7 @@ int mls_compute_context_len(struct conte
 	struct ebitmap *e;
 	struct ebitmap_node *node;

-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;

 	len = 1; /* for the beginning ":" */
@@ -93,7 +93,7 @@ void mls_sid_to_context(struct context *
 	struct ebitmap *e;
 	struct ebitmap_node *node;

-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return;

 	scontextp = *scontext;
@@ -200,7 +200,7 @@ int mls_context_isvalid(struct policydb
 {
 	struct user_datum *usrdatum;

-	if (!selinux_mls_enabled)
+	if (!p->mls_enabled)
 		return 1;

 	if (!mls_range_isvalid(p, &c->range))
@@ -253,7 +253,7 @@ int mls_context_to_sid(struct policydb *
 	struct cat_datum *catdatum, *rngdatum;
 	int l, rc = -EINVAL;

-	if (!selinux_mls_enabled) {
+	if (!pol->mls_enabled) {
 		if (def_sid != SECSID_NULL && oldc)
 			*scontext += strlen(*scontext)+1;
 		return 0;
@@ -387,7 +387,7 @@ int mls_from_string(char *str, struct co
 	char *tmpstr, *freestr;
 	int rc;

-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return -EINVAL;

 	/* we need freestr because mls_context_to_sid will change
@@ -407,7 +407,7 @@ int mls_from_string(char *str, struct co
 /*
  * Copies the MLS range `range' into `context'.
  */
-static inline int mls_range_set(struct context *context,
+int mls_range_set(struct context *context,
 				struct mls_range *range)
 {
 	int l, rc = 0;
@@ -427,7 +427,7 @@ static inline int mls_range_set(struct c
 int mls_setup_user_range(struct context *fromcon, struct user_datum *user,
 			 struct context *usercon)
 {
-	if (selinux_mls_enabled) {
+	if (policydb.mls_enabled) {
 		struct mls_level *fromcon_sen = &(fromcon->range.level[0]);
 		struct mls_level *fromcon_clr = &(fromcon->range.level[1]);
 		struct mls_level *user_low = &(user->range.level[0]);
@@ -477,7 +477,7 @@ int mls_convert_context(struct policydb
 	struct ebitmap_node *node;
 	int l, i;

-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;

 	for (l = 0; l < 2; l++) {
@@ -516,7 +516,7 @@ int mls_compute_sid(struct context *scon
 	struct range_trans rtr;
 	struct mls_range *r;

-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;

 	switch (specified) {
@@ -559,7 +559,7 @@ int mls_compute_sid(struct context *scon
 void mls_export_netlbl_lvl(struct context *context,
 			   struct netlbl_lsm_secattr *secattr)
 {
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return;

 	secattr->attr.mls.lvl = context->range.level[0].sens - 1;
@@ -579,7 +579,7 @@ void mls_export_netlbl_lvl(struct contex
 void mls_import_netlbl_lvl(struct context *context,
 			   struct netlbl_lsm_secattr *secattr)
 {
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return;

 	context->range.level[0].sens = secattr->attr.mls.lvl + 1;
@@ -601,7 +601,7 @@ int mls_export_netlbl_cat(struct context
 {
 	int rc;

-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;

 	rc = ebitmap_netlbl_export(&context->range.level[0].cat,
@@ -629,7 +629,7 @@ int mls_import_netlbl_cat(struct context
 {
 	int rc;

-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;

 	rc = ebitmap_netlbl_import(&context->range.level[0].cat,
diff -pruN security-testing-2.6/security/selinux/ss/mls.h security-testing-2.6-new/security/selinux/ss/mls.h
--- security-testing-2.6/security/selinux/ss/mls.h	2010-01-29 01:06:42.168051431 +0100
+++ security-testing-2.6-new/security/selinux/ss/mls.h	2010-02-01 23:17:31.025223083 +0100
@@ -39,6 +39,8 @@ int mls_context_to_sid(struct policydb *

 int mls_from_string(char *str, struct context *context, gfp_t gfp_mask);

+int mls_range_set(struct context *context, struct mls_range *range);
+
 int mls_convert_context(struct policydb *oldp,
 			struct policydb *newp,
 			struct context *context);
diff -pruN security-testing-2.6/security/selinux/ss/mls_types.h security-testing-2.6-new/security/selinux/ss/mls_types.h
--- security-testing-2.6/security/selinux/ss/mls_types.h	2010-01-29 01:06:42.168051431 +0100
+++ security-testing-2.6-new/security/selinux/ss/mls_types.h	2010-02-01 22:23:11.799224771 +0100
@@ -15,6 +15,7 @@
 #define _SS_MLS_TYPES_H_

 #include "security.h"
+#include "ebitmap.h"

 struct mls_level {
 	u32 sens;		/* sensitivity */
@@ -27,7 +28,7 @@ struct mls_range {

 static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2)
 {
-	if (!selinux_mls_enabled)
+	if (!security_mls_enabled())
 		return 1;

 	return ((l1->sens == l2->sens) &&
@@ -36,7 +37,7 @@ static inline int mls_level_eq(struct ml

 static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2)
 {
-	if (!selinux_mls_enabled)
+	if (!security_mls_enabled())
 		return 1;

 	return ((l1->sens >= l2->sens) &&
diff -pruN security-testing-2.6/security/selinux/ss/policydb.c security-testing-2.6-new/security/selinux/ss/policydb.c
--- security-testing-2.6/security/selinux/ss/policydb.c	2010-01-29 02:02:47.740046077 +0100
+++ security-testing-2.6-new/security/selinux/ss/policydb.c	2010-02-01 22:12:18.601226073 +0100
@@ -52,8 +52,6 @@ static char *symtab_name[SYM_NUM] = {
 };
 #endif

-int selinux_mls_enabled;
-
 static unsigned int symtab_sizes[SYM_NUM] = {
 	2,
 	32,
@@ -455,7 +453,7 @@ static int policydb_index_others(struct

 	printk(KERN_DEBUG "SELinux:  %d users, %d roles, %d types, %d bools",
 	       p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim);
-	if (selinux_mls_enabled)
+	if (p->mls_enabled)
 		printk(", %d sens, %d cats", p->p_levels.nprim,
 		       p->p_cats.nprim);
 	printk("n");
@@ -1717,14 +1715,12 @@ int policydb_read(struct policydb *p, vo
 	int i, j, rc;
 	__le32 buf[4];
 	u32 nodebuf[8];
-	u32 len, len2, config, nprim, nel, nel2;
+	u32 len, len2, nprim, nel, nel2;
 	char *policydb_str;
 	struct policydb_compat_info *info;
 	struct range_trans *rt;
 	struct mls_range *r;

-	config = 0;
-
 	rc = policydb_init(p);
 	if (rc)
 		goto out;
@@ -1772,7 +1768,7 @@ int policydb_read(struct policydb *p, vo
 	kfree(policydb_str);
 	policydb_str = NULL;

-	/* Read the version, config, and table sizes. */
+	/* Read the version and table sizes. */
 	rc = next_entry(buf, fp, sizeof(u32)*4);
 	if (rc < 0)
 		goto bad;
@@ -1787,13 +1783,7 @@ int policydb_read(struct policydb *p, vo
 	}

 	if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) {
-		if (ss_initialized && !selinux_mls_enabled) {
-			printk(KERN_ERR "SELinux: Cannot switch between non-MLS"
-				" and MLS policiesn");
-			goto bad;
-		}
-		selinux_mls_enabled = 1;
-		config |= POLICYDB_CONFIG_MLS;
+		p->mls_enabled = 1;

 		if (p->policyvers < POLICYDB_VERSION_MLS) {
 			printk(KERN_ERR "SELinux: security policydb version %d "
@@ -1801,12 +1791,6 @@ int policydb_read(struct policydb *p, vo
 				p->policyvers);
 			goto bad;
 		}
-	} else {
-		if (ss_initialized && selinux_mls_enabled) {
-			printk(KERN_ERR "SELinux: Cannot switch between MLS and"
-				" non-MLS policiesn");
-			goto bad;
-		}
 	}
 	p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN);
 	p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);
diff -pruN security-testing-2.6/security/selinux/ss/policydb.h security-testing-2.6-new/security/selinux/ss/policydb.h
--- security-testing-2.6/security/selinux/ss/policydb.h	2010-01-29 02:02:47.740046077 +0100
+++ security-testing-2.6-new/security/selinux/ss/policydb.h	2010-02-01 20:47:08.352232380 +0100
@@ -27,6 +27,8 @@
 #include "symtab.h"
 #include "avtab.h"
 #include "sidtab.h"
+#include "ebitmap.h"
+#include "mls_types.h"
 #include "context.h"
 #include "constraint.h"

@@ -185,6 +187,8 @@ struct genfs {

 /* The policy database */
 struct policydb {
+	int mls_enabled;
+
 	/* symbol tables */
 	struct symtab symtab[SYM_NUM];
 #define p_commons symtab[SYM_COMMONS]
diff -pruN security-testing-2.6/security/selinux/ss/services.c security-testing-2.6-new/security/selinux/ss/services.c
--- security-testing-2.6/security/selinux/ss/services.c	2010-01-29 02:02:47.742042805 +0100
+++ security-testing-2.6-new/security/selinux/ss/services.c	2010-02-01 23:28:02.338227931 +0100
@@ -26,6 +26,10 @@
  *
  *  Added support for bounds domain and audit messaged on masked permissions
  *
+ * Updated: Guido Trentalancia <guido@trentalancia.com>
+ *
+ *  Added support for runtime switching of the policy type
+ *
  * Copyright (C) 2008, 2009 NEC Corporation
  * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P.
  * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
@@ -232,6 +236,16 @@ static void map_decision(u16 tclass, str
 	}
 }

+/*
+ * Returns a boolean value.
+ * True: if the specified policy is MLS or MCS
+ * False: if the specified policy is a standard policy
+ * 	  without MLS/MCS support
+ */
+int security_mls_enabled(void)
+{
+	return policydb.mls_enabled;
+}

 /*
  * Return the boolean value of a constraint expression
@@ -1547,6 +1561,8 @@ static int convert_context(u32 key,
 {
 	struct convert_context_args *args;
 	struct context oldc;
+	struct ocontext *oc;
+	struct mls_range *range;
 	struct role_datum *role;
 	struct type_datum *typdatum;
 	struct user_datum *usrdatum;
@@ -1614,9 +1630,43 @@ static int convert_context(u32 key,
 		goto bad;
 	c->type = typdatum->value;

-	rc = mls_convert_context(args->oldp, args->newp, c);
-	if (rc)
-		goto bad;
+	/* Convert the MLS/MCS fields if dealing with MLS/MCS policies */
+	if (args->oldp->mls_enabled
+	    && args->newp->mls_enabled) {
+		rc = mls_convert_context(args->oldp, args->newp, c);
+		if (rc)
+			goto bad;
+	}
+
+	/*
+	 * Switching between MLS/MCS and non-MLS/non-MCS policy:
+	 * free any storage used by the MLS fields in the
+	 * context for all existing entries in the sidtab.
+	 */
+	if (args->oldp->mls_enabled && !args->newp->mls_enabled)
+		mls_context_destroy(c);
+
+	/*
+	 * Switching between non-MLS/non-MCS and MLS/MCS policy:
+	 * ensure that the MLS fields of the context for all
+	 * existing entries in the sidtab are filled in with a
+	 * suitable default value, likely taken from one of the
+	 * initial SIDs.
+	 */
+	if (!args->oldp->mls_enabled && args->newp->mls_enabled) {
+		oc = args->newp->ocontexts[OCON_ISID];
+		while (oc && oc->sid[0] != SECINITSID_UNLABELED)
+			oc = oc->next;
+		if (!oc) {
+			printk(KERN_ERR "SELinux:  unable to look up"
+				" the initial SIDs listn");
+			goto bad;
+		}
+		range = &oc->context[0].range;
+		rc = mls_range_set(c, range);
+		if (rc)
+			goto bad;
+	}

 	/* Check the validity of the new context. */
 	if (!policydb_context_isvalid(args->newp, c)) {
@@ -1712,6 +1762,14 @@ int security_load_policy(void *data, siz
 	if (policydb_read(&newpolicydb, fp))
 		return -EINVAL;

+	/* If switching between different policy types, log it */
+	if (policydb.mls_enabled && !newpolicydb.mls_enabled)
+		printk(KERN_INFO "SELinux: Switching between MLS/MCS"
+			" and standard policy...n");
+	else if (!policydb.mls_enabled && newpolicydb.mls_enabled)
+		printk(KERN_INFO "SELinux: Switching between standard"
+			" and MLS/MCS policy...n");
+
 	if (sidtab_init(&newsidtab)) {
 		policydb_destroy(&newpolicydb);
 		return -ENOMEM;
@@ -1741,8 +1799,12 @@ int security_load_policy(void *data, siz
 	args.oldp = &policydb;
 	args.newp = &newpolicydb;
 	rc = sidtab_map(&newsidtab, convert_context, &args);
-	if (rc)
+	if (rc) {
+		printk(KERN_ERR "SELinux:  unable to convert the internal"
+			" representation of contexts in the new SID"
+			" tablen");
 		goto err;
+	}

 	/* Save the old policydb and SID table to free later. */
 	memcpy(&oldpolicydb, &policydb, sizeof policydb);
@@ -2338,7 +2400,7 @@ int security_sid_mls_copy(u32 sid, u32 m
 	u32 len;
 	int rc = 0;

-	if (!ss_initialized || !selinux_mls_enabled) {
+	if (!ss_initialized || !policydb.mls_enabled) {
 		*new_sid = sid;
 		goto out;
 	}
@@ -2439,7 +2501,7 @@ int security_net_peersid_resolve(u32 nlb
 	/* we don't need to check ss_initialized here since the only way both
 	 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the
 	 * security server was initialized and ss_initialized was true */
-	if (!selinux_mls_enabled) {
+	if (!policydb.mls_enabled) {
 		*peer_sid = SECSID_NULL;
 		return 0;
 	}

[-- Attachment #2: switch-policy.patch --]
[-- Type: application/octet-stream, Size: 15911 bytes --]

Author: Guido Trentalancia <guido@trentalancia.com>
Date:   Mon Feb 01 23:29:52 2010 +0100

    Allow runtime switching between different policy types (e.g. from a MLS/MCS
    policy to a non-MLS/non-MCS policy or viceversa).

    Signed-off-by: Guido Trentalancia <guido@trentalancia.com>

 security/selinux/include/security.h |    3 -
 security/selinux/selinuxfs.c        |    3 -
 security/selinux/ss/.policydb.c.swp |binary
 security/selinux/ss/context.h       |    9 +--
 security/selinux/ss/mls.c           |   26 ++++-----
 security/selinux/ss/mls.h           |    2
 security/selinux/ss/mls_types.h     |    5 +
 security/selinux/ss/policydb.c      |   24 +-------
 security/selinux/ss/policydb.h      |    4 +
 security/selinux/ss/services.c      |   74 +++++++++++++++++++++++---
 10 files changed, 101 insertions(+), 49 deletions(-)

diff -pruN security-testing-2.6/security/selinux/include/security.h security-testing-2.6-new/security/selinux/include/security.h
--- security-testing-2.6/security/selinux/include/security.h	2010-01-29 02:02:47.737045258 +0100
+++ security-testing-2.6-new/security/selinux/include/security.h	2010-02-01 23:12:28.898233272 +0100
@@ -57,7 +57,6 @@
 struct netlbl_lsm_secattr;
 
 extern int selinux_enabled;
-extern int selinux_mls_enabled;
 
 /* Policy capabilities */
 enum {
@@ -80,6 +79,8 @@ extern int selinux_policycap_openperm;
 /* limitation of boundary depth  */
 #define POLICYDB_BOUNDS_MAXDEPTH	4
 
+int security_mls_enabled(void);
+
 int security_load_policy(void *data, size_t len);
 
 int security_policycap_supported(unsigned int req_cap);
diff -pruN security-testing-2.6/security/selinux/selinuxfs.c security-testing-2.6-new/security/selinux/selinuxfs.c
--- security-testing-2.6/security/selinux/selinuxfs.c	2010-01-29 02:02:47.738046835 +0100
+++ security-testing-2.6-new/security/selinux/selinuxfs.c	2010-02-01 22:06:21.709234039 +0100
@@ -282,7 +282,8 @@ static ssize_t sel_read_mls(struct file 
 	char tmpbuf[TMPBUFLEN];
 	ssize_t length;
 
-	length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_mls_enabled);
+	length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
+			   security_mls_enabled());
 	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
 }
 
diff -pruN security-testing-2.6/security/selinux/ss/context.h security-testing-2.6-new/security/selinux/ss/context.h
--- security-testing-2.6/security/selinux/ss/context.h	2010-01-29 01:06:42.160060332 +0100
+++ security-testing-2.6-new/security/selinux/ss/context.h	2010-02-01 23:13:35.857235582 +0100
@@ -41,7 +41,7 @@ static inline int mls_context_cpy(struct
 {
 	int rc;
 
-	if (!selinux_mls_enabled)
+	if (!security_mls_enabled())
 		return 0;
 
 	dst->range.level[0].sens = src->range.level[0].sens;
@@ -64,7 +64,7 @@ static inline int mls_context_cpy_low(st
 {
 	int rc;
 
-	if (!selinux_mls_enabled)
+	if (!security_mls_enabled())
 		return 0;
 
 	dst->range.level[0].sens = src->range.level[0].sens;
@@ -82,7 +82,7 @@ out:
 
 static inline int mls_context_cmp(struct context *c1, struct context *c2)
 {
-	if (!selinux_mls_enabled)
+	if (!security_mls_enabled())
 		return 1;
 
 	return ((c1->range.level[0].sens == c2->range.level[0].sens) &&
@@ -93,9 +93,6 @@ static inline int mls_context_cmp(struct
 
 static inline void mls_context_destroy(struct context *c)
 {
-	if (!selinux_mls_enabled)
-		return;
-
 	ebitmap_destroy(&c->range.level[0].cat);
 	ebitmap_destroy(&c->range.level[1].cat);
 	mls_context_init(c);
diff -pruN security-testing-2.6/security/selinux/ss/mls.c security-testing-2.6-new/security/selinux/ss/mls.c
--- security-testing-2.6/security/selinux/ss/mls.c	2010-01-29 02:02:47.739046177 +0100
+++ security-testing-2.6-new/security/selinux/ss/mls.c	2010-02-01 22:15:48.062233721 +0100
@@ -39,7 +39,7 @@ int mls_compute_context_len(struct conte
 	struct ebitmap *e;
 	struct ebitmap_node *node;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;
 
 	len = 1; /* for the beginning ":" */
@@ -93,7 +93,7 @@ void mls_sid_to_context(struct context *
 	struct ebitmap *e;
 	struct ebitmap_node *node;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return;
 
 	scontextp = *scontext;
@@ -200,7 +200,7 @@ int mls_context_isvalid(struct policydb 
 {
 	struct user_datum *usrdatum;
 
-	if (!selinux_mls_enabled)
+	if (!p->mls_enabled)
 		return 1;
 
 	if (!mls_range_isvalid(p, &c->range))
@@ -253,7 +253,7 @@ int mls_context_to_sid(struct policydb *
 	struct cat_datum *catdatum, *rngdatum;
 	int l, rc = -EINVAL;
 
-	if (!selinux_mls_enabled) {
+	if (!pol->mls_enabled) {
 		if (def_sid != SECSID_NULL && oldc)
 			*scontext += strlen(*scontext)+1;
 		return 0;
@@ -387,7 +387,7 @@ int mls_from_string(char *str, struct co
 	char *tmpstr, *freestr;
 	int rc;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return -EINVAL;
 
 	/* we need freestr because mls_context_to_sid will change
@@ -407,7 +407,7 @@ int mls_from_string(char *str, struct co
 /*
  * Copies the MLS range `range' into `context'.
  */
-static inline int mls_range_set(struct context *context,
+int mls_range_set(struct context *context,
 				struct mls_range *range)
 {
 	int l, rc = 0;
@@ -427,7 +427,7 @@ static inline int mls_range_set(struct c
 int mls_setup_user_range(struct context *fromcon, struct user_datum *user,
 			 struct context *usercon)
 {
-	if (selinux_mls_enabled) {
+	if (policydb.mls_enabled) {
 		struct mls_level *fromcon_sen = &(fromcon->range.level[0]);
 		struct mls_level *fromcon_clr = &(fromcon->range.level[1]);
 		struct mls_level *user_low = &(user->range.level[0]);
@@ -477,7 +477,7 @@ int mls_convert_context(struct policydb 
 	struct ebitmap_node *node;
 	int l, i;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;
 
 	for (l = 0; l < 2; l++) {
@@ -516,7 +516,7 @@ int mls_compute_sid(struct context *scon
 	struct range_trans rtr;
 	struct mls_range *r;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;
 
 	switch (specified) {
@@ -559,7 +559,7 @@ int mls_compute_sid(struct context *scon
 void mls_export_netlbl_lvl(struct context *context,
 			   struct netlbl_lsm_secattr *secattr)
 {
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return;
 
 	secattr->attr.mls.lvl = context->range.level[0].sens - 1;
@@ -579,7 +579,7 @@ void mls_export_netlbl_lvl(struct contex
 void mls_import_netlbl_lvl(struct context *context,
 			   struct netlbl_lsm_secattr *secattr)
 {
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return;
 
 	context->range.level[0].sens = secattr->attr.mls.lvl + 1;
@@ -601,7 +601,7 @@ int mls_export_netlbl_cat(struct context
 {
 	int rc;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;
 
 	rc = ebitmap_netlbl_export(&context->range.level[0].cat,
@@ -629,7 +629,7 @@ int mls_import_netlbl_cat(struct context
 {
 	int rc;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;
 
 	rc = ebitmap_netlbl_import(&context->range.level[0].cat,
diff -pruN security-testing-2.6/security/selinux/ss/mls.h security-testing-2.6-new/security/selinux/ss/mls.h
--- security-testing-2.6/security/selinux/ss/mls.h	2010-01-29 01:06:42.168051431 +0100
+++ security-testing-2.6-new/security/selinux/ss/mls.h	2010-02-01 23:17:31.025223083 +0100
@@ -39,6 +39,8 @@ int mls_context_to_sid(struct policydb *
 
 int mls_from_string(char *str, struct context *context, gfp_t gfp_mask);
 
+int mls_range_set(struct context *context, struct mls_range *range);
+
 int mls_convert_context(struct policydb *oldp,
 			struct policydb *newp,
 			struct context *context);
diff -pruN security-testing-2.6/security/selinux/ss/mls_types.h security-testing-2.6-new/security/selinux/ss/mls_types.h
--- security-testing-2.6/security/selinux/ss/mls_types.h	2010-01-29 01:06:42.168051431 +0100
+++ security-testing-2.6-new/security/selinux/ss/mls_types.h	2010-02-01 22:23:11.799224771 +0100
@@ -15,6 +15,7 @@
 #define _SS_MLS_TYPES_H_
 
 #include "security.h"
+#include "ebitmap.h"
 
 struct mls_level {
 	u32 sens;		/* sensitivity */
@@ -27,7 +28,7 @@ struct mls_range {
 
 static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2)
 {
-	if (!selinux_mls_enabled)
+	if (!security_mls_enabled())
 		return 1;
 
 	return ((l1->sens == l2->sens) &&
@@ -36,7 +37,7 @@ static inline int mls_level_eq(struct ml
 
 static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2)
 {
-	if (!selinux_mls_enabled)
+	if (!security_mls_enabled())
 		return 1;
 
 	return ((l1->sens >= l2->sens) &&
diff -pruN security-testing-2.6/security/selinux/ss/policydb.c security-testing-2.6-new/security/selinux/ss/policydb.c
--- security-testing-2.6/security/selinux/ss/policydb.c	2010-01-29 02:02:47.740046077 +0100
+++ security-testing-2.6-new/security/selinux/ss/policydb.c	2010-02-01 22:12:18.601226073 +0100
@@ -52,8 +52,6 @@ static char *symtab_name[SYM_NUM] = {
 };
 #endif
 
-int selinux_mls_enabled;
-
 static unsigned int symtab_sizes[SYM_NUM] = {
 	2,
 	32,
@@ -455,7 +453,7 @@ static int policydb_index_others(struct 
 
 	printk(KERN_DEBUG "SELinux:  %d users, %d roles, %d types, %d bools",
 	       p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim);
-	if (selinux_mls_enabled)
+	if (p->mls_enabled)
 		printk(", %d sens, %d cats", p->p_levels.nprim,
 		       p->p_cats.nprim);
 	printk("\n");
@@ -1717,14 +1715,12 @@ int policydb_read(struct policydb *p, vo
 	int i, j, rc;
 	__le32 buf[4];
 	u32 nodebuf[8];
-	u32 len, len2, config, nprim, nel, nel2;
+	u32 len, len2, nprim, nel, nel2;
 	char *policydb_str;
 	struct policydb_compat_info *info;
 	struct range_trans *rt;
 	struct mls_range *r;
 
-	config = 0;
-
 	rc = policydb_init(p);
 	if (rc)
 		goto out;
@@ -1772,7 +1768,7 @@ int policydb_read(struct policydb *p, vo
 	kfree(policydb_str);
 	policydb_str = NULL;
 
-	/* Read the version, config, and table sizes. */
+	/* Read the version and table sizes. */
 	rc = next_entry(buf, fp, sizeof(u32)*4);
 	if (rc < 0)
 		goto bad;
@@ -1787,13 +1783,7 @@ int policydb_read(struct policydb *p, vo
 	}
 
 	if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) {
-		if (ss_initialized && !selinux_mls_enabled) {
-			printk(KERN_ERR "SELinux: Cannot switch between non-MLS"
-				" and MLS policies\n");
-			goto bad;
-		}
-		selinux_mls_enabled = 1;
-		config |= POLICYDB_CONFIG_MLS;
+		p->mls_enabled = 1;
 
 		if (p->policyvers < POLICYDB_VERSION_MLS) {
 			printk(KERN_ERR "SELinux: security policydb version %d "
@@ -1801,12 +1791,6 @@ int policydb_read(struct policydb *p, vo
 				p->policyvers);
 			goto bad;
 		}
-	} else {
-		if (ss_initialized && selinux_mls_enabled) {
-			printk(KERN_ERR "SELinux: Cannot switch between MLS and"
-				" non-MLS policies\n");
-			goto bad;
-		}
 	}
 	p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN);
 	p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);
diff -pruN security-testing-2.6/security/selinux/ss/policydb.h security-testing-2.6-new/security/selinux/ss/policydb.h
--- security-testing-2.6/security/selinux/ss/policydb.h	2010-01-29 02:02:47.740046077 +0100
+++ security-testing-2.6-new/security/selinux/ss/policydb.h	2010-02-01 20:47:08.352232380 +0100
@@ -27,6 +27,8 @@
 #include "symtab.h"
 #include "avtab.h"
 #include "sidtab.h"
+#include "ebitmap.h"
+#include "mls_types.h"
 #include "context.h"
 #include "constraint.h"
 
@@ -185,6 +187,8 @@ struct genfs {
 
 /* The policy database */
 struct policydb {
+	int mls_enabled;
+
 	/* symbol tables */
 	struct symtab symtab[SYM_NUM];
 #define p_commons symtab[SYM_COMMONS]
diff -pruN security-testing-2.6/security/selinux/ss/services.c security-testing-2.6-new/security/selinux/ss/services.c
--- security-testing-2.6/security/selinux/ss/services.c	2010-01-29 02:02:47.742042805 +0100
+++ security-testing-2.6-new/security/selinux/ss/services.c	2010-02-01 23:28:02.338227931 +0100
@@ -26,6 +26,10 @@
  *
  *  Added support for bounds domain and audit messaged on masked permissions
  *
+ * Updated: Guido Trentalancia <guido@trentalancia.com>
+ *
+ *  Added support for runtime switching of the policy type
+ *
  * Copyright (C) 2008, 2009 NEC Corporation
  * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P.
  * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
@@ -232,6 +236,16 @@ static void map_decision(u16 tclass, str
 	}
 }
 
+/*
+ * Returns a boolean value.
+ * True: if the specified policy is MLS or MCS
+ * False: if the specified policy is a standard policy
+ * 	  without MLS/MCS support
+ */
+int security_mls_enabled(void)
+{
+	return policydb.mls_enabled;
+}
 
 /*
  * Return the boolean value of a constraint expression
@@ -1547,6 +1561,8 @@ static int convert_context(u32 key,
 {
 	struct convert_context_args *args;
 	struct context oldc;
+	struct ocontext *oc;
+	struct mls_range *range;
 	struct role_datum *role;
 	struct type_datum *typdatum;
 	struct user_datum *usrdatum;
@@ -1614,9 +1630,43 @@ static int convert_context(u32 key,
 		goto bad;
 	c->type = typdatum->value;
 
-	rc = mls_convert_context(args->oldp, args->newp, c);
-	if (rc)
-		goto bad;
+	/* Convert the MLS/MCS fields if dealing with MLS/MCS policies */
+	if (args->oldp->mls_enabled
+	    && args->newp->mls_enabled) {
+		rc = mls_convert_context(args->oldp, args->newp, c);
+		if (rc)
+			goto bad;
+	}
+
+	/*
+	 * Switching between MLS/MCS and non-MLS/non-MCS policy:
+	 * free any storage used by the MLS fields in the
+	 * context for all existing entries in the sidtab.
+	 */
+	if (args->oldp->mls_enabled && !args->newp->mls_enabled)
+		mls_context_destroy(c);
+
+	/*
+	 * Switching between non-MLS/non-MCS and MLS/MCS policy:
+	 * ensure that the MLS fields of the context for all
+	 * existing entries in the sidtab are filled in with a
+	 * suitable default value, likely taken from one of the
+	 * initial SIDs.
+	 */
+	if (!args->oldp->mls_enabled && args->newp->mls_enabled) {
+		oc = args->newp->ocontexts[OCON_ISID];
+		while (oc && oc->sid[0] != SECINITSID_UNLABELED)
+			oc = oc->next;
+		if (!oc) {
+			printk(KERN_ERR "SELinux:  unable to look up"
+				" the initial SIDs list\n");
+			goto bad;
+		}
+		range = &oc->context[0].range;
+		rc = mls_range_set(c, range);
+		if (rc)
+			goto bad;
+	}
 
 	/* Check the validity of the new context. */
 	if (!policydb_context_isvalid(args->newp, c)) {
@@ -1712,6 +1762,14 @@ int security_load_policy(void *data, siz
 	if (policydb_read(&newpolicydb, fp))
 		return -EINVAL;
 
+	/* If switching between different policy types, log it */
+	if (policydb.mls_enabled && !newpolicydb.mls_enabled)
+		printk(KERN_INFO "SELinux: Switching between MLS/MCS"
+			" and standard policy...\n");
+	else if (!policydb.mls_enabled && newpolicydb.mls_enabled)
+		printk(KERN_INFO "SELinux: Switching between standard"
+			" and MLS/MCS policy...\n");
+
 	if (sidtab_init(&newsidtab)) {
 		policydb_destroy(&newpolicydb);
 		return -ENOMEM;
@@ -1741,8 +1799,12 @@ int security_load_policy(void *data, siz
 	args.oldp = &policydb;
 	args.newp = &newpolicydb;
 	rc = sidtab_map(&newsidtab, convert_context, &args);
-	if (rc)
+	if (rc) {
+		printk(KERN_ERR "SELinux:  unable to convert the internal"
+			" representation of contexts in the new SID"
+			" table\n");
 		goto err;
+	}
 
 	/* Save the old policydb and SID table to free later. */
 	memcpy(&oldpolicydb, &policydb, sizeof policydb);
@@ -2338,7 +2400,7 @@ int security_sid_mls_copy(u32 sid, u32 m
 	u32 len;
 	int rc = 0;
 
-	if (!ss_initialized || !selinux_mls_enabled) {
+	if (!ss_initialized || !policydb.mls_enabled) {
 		*new_sid = sid;
 		goto out;
 	}
@@ -2439,7 +2501,7 @@ int security_net_peersid_resolve(u32 nlb
 	/* we don't need to check ss_initialized here since the only way both
 	 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the
 	 * security server was initialized and ss_initialized was true */
-	if (!selinux_mls_enabled) {
+	if (!policydb.mls_enabled) {
 		*peer_sid = SECSID_NULL;
 		return 0;
 	}

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
  2010-02-01 21:49 Guido Trentalancia
@ 2010-02-01 22:09 ` Stephen Smalley
  0 siblings, 0 replies; 33+ messages in thread
From: Stephen Smalley @ 2010-02-01 22:09 UTC (permalink / raw)
  To: Guido Trentalancia; +Cc: selinux, eparis, jmorris

On Mon, 2010-02-01 at 22:49 +0100, Guido Trentalancia wrote:
> Stephen,
> 
> yes you are right. There is no need to include policydb.h from security.h.
> 
> Please have a further look at the attached revised patch, while I do some testing of the resulting compiled kernel. I hope I did not miss any amendment.
> 
> If it is fine and nobody else has comments or suggestions to make, then we should probably post it to the kernel mailing list with your Acked-by or Reviewed-by line.
> 
> Best regards,
> 
> Guido
> 
> Author: Guido Trentalancia <guido@trentalancia.com>
> Date:   Mon Feb 01 22:34:16 2010 +0100
> 
>     Allow runtime switching between different policy types (e.g. from a MLS/MCS
>     policy to a non-MLS/non-MCS policy or viceversa).
> 
>     Signed-off-by: Guido Trentalancia <guido@trentalancia.com>
> 
> diff -pruN security-testing-2.6/security/selinux/include/security.h security-testing-2.6-new/security/selinux/include/security.h
> --- security-testing-2.6/security/selinux/include/security.h	2010-01-29 02:02:47.737045258 +0100
> +++ security-testing-2.6-new/security/selinux/include/security.h	2010-02-01 22:06:38.053225052 +0100
> @@ -57,7 +57,7 @@
>  struct netlbl_lsm_secattr;
>  
>  extern int selinux_enabled;
> -extern int selinux_mls_enabled;
> +extern struct policydb policydb;

Oops.

> diff -pruN security-testing-2.6/security/selinux/ss/constraint.h security-testing-2.6-new/security/selinux/ss/constraint.h
> --- security-testing-2.6/security/selinux/ss/constraint.h	2010-01-29 01:06:42.160060332 +0100
> +++ security-testing-2.6-new/security/selinux/ss/constraint.h	2010-02-01 20:50:19.860227025 +0100
> @@ -12,6 +12,7 @@
>   *
>   * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
>   */
> +
>  #ifndef _SS_CONSTRAINT_H_
>  #define _SS_CONSTRAINT_H_

Avoid extraneous whitespace changes.

> diff -pruN security-testing-2.6/security/selinux/ss/context.h security-testing-2.6-new/security/selinux/ss/context.h
> --- security-testing-2.6/security/selinux/ss/context.h	2010-01-29 01:06:42.160060332 +0100
> +++ security-testing-2.6-new/security/selinux/ss/context.h	2010-02-01 22:22:33.090234587 +0100
> @@ -12,6 +12,7 @@
>   *
>   * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
>   */
> +
>  #ifndef _SS_CONTEXT_H_
>  #define _SS_CONTEXT_H_
>  

Ditto.


> diff -pruN security-testing-2.6/security/selinux/ss/mls.h security-testing-2.6-new/security/selinux/ss/mls.h
> --- security-testing-2.6/security/selinux/ss/mls.h	2010-01-29 01:06:42.168051431 +0100
> +++ security-testing-2.6-new/security/selinux/ss/mls.h	2010-02-01 18:57:42.693221952 +0100
> @@ -24,6 +24,8 @@
>  #include "context.h"
>  #include "policydb.h"
>  
> +extern struct policydb policydb;

This shouldn't be needed.  Whatever needs the extern decl can #include
"services.h".

> @@ -1614,9 +1630,48 @@ static int convert_context(u32 key,
>  		goto bad;
>  	c->type = typdatum->value;
>  
> -	rc = mls_convert_context(args->oldp, args->newp, c);
> -	if (rc)
> -		goto bad;
> +	/* Convert the MLS/MCS fields if dealing with MLS/MCS policies */
> +	if (args->oldp->mls_enabled
> +	    && args->newp->mls_enabled) {
> +		rc = mls_convert_context(args->oldp, args->newp, c);
> +		if (rc)
> +			goto bad;
> +	}
> +
> +	/*
> +	 * Switching between MLS/MCS and non-MLS/non-MCS policy:
> +	 * free any storage used by the MLS fields in the
> +	 * context for all existing entries in the sidtab.
> +	 */
> +	if (args->oldp->mls_enabled && !args->newp->mls_enabled)
> +		mls_context_destroy(c);
> +
> +	/*
> +	 * Switching between non-MLS/non-MCS and MLS/MCS policy:
> +	 * ensure that the MLS fields of the context for all
> +	 * existing entries in the sidtab are filled in with a
> +	 * suitable default value, likely taken from one of the
> +	 * initial SIDs.
> +	 */
> +	if (!args->oldp->mls_enabled && args->newp->mls_enabled) {
> +		oc = args->newp->ocontexts[OCON_ISID];
> +		while (oc && oc->sid[0] != SECINITSID_UNLABELED)
> +			oc = oc->next;

Just in case, I'd test if (!oc) and bail with an error.

> +		range = &oc->context[0].range;
> +		rc = mls_range_set(c, range);
> +		if (rc) {
> +			if (context_struct_to_string(&oldc, &s, &len))
> +				return -ENOMEM;
> +			context_destroy(&oldc);
> +			context_destroy(c);
> +			c->str = s;
> +			c->len = len;
> +			printk(KERN_ERR "SELinux:  Failed to set"
> +				" the MLS/MCS range for context"
> +				" %sn", c->str);
> +			goto out;

goto bad ?

> +		}
> +	}
>  
>  	/* Check the validity of the new context. */
>  	if (!policydb_context_isvalid(args->newp, c)) {

> diff -pruN security-testing-2.6/security/selinux/ss/services.h security-testing-2.6-new/security/selinux/ss/services.h
> --- security-testing-2.6/security/selinux/ss/services.h	2010-01-29 01:06:42.174044406 +0100
> +++ security-testing-2.6-new/security/selinux/ss/services.h	2010-02-01 18:26:32.682234915 +0100
> @@ -3,6 +3,7 @@
>   *
>   * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
>   */
> +
>  #ifndef _SS_SERVICES_H_
>  #define _SS_SERVICES_H_

Whitespace change.

> diff -pruN security-testing-2.6/security/selinux/ss/sidtab.h security-testing-2.6-new/security/selinux/ss/sidtab.h
> --- security-testing-2.6/security/selinux/ss/sidtab.h	2010-01-29 01:06:42.175047659 +0100
> +++ security-testing-2.6-new/security/selinux/ss/sidtab.h	2010-02-01 20:38:09.350520786 +0100
> @@ -51,4 +51,3 @@ void sidtab_shutdown(struct sidtab *s);
>  
>  #endif	/* _SS_SIDTAB_H_ */
>  
> -

Whitespace change.

> diff -pruN security-testing-2.6/security/selinux/ss/symtab.h security-testing-2.6-new/security/selinux/ss/symtab.h
> --- security-testing-2.6/security/selinux/ss/symtab.h	2010-01-29 01:06:42.176055661 +0100
> +++ security-testing-2.6-new/security/selinux/ss/symtab.h	2010-02-01 20:50:54.661232717 +0100
> @@ -6,6 +6,7 @@
>   *
>   * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
>   */
> +
>  #ifndef _SS_SYMTAB_H_
>  #define _SS_SYMTAB_H_

Ditto.

-- 
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 majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
@ 2010-02-01 21:56 Guido Trentalancia
  0 siblings, 0 replies; 33+ messages in thread
From: Guido Trentalancia @ 2010-02-01 21:56 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: selinux, eparis, jmorris

Diffstat output of switch-policy.patch

 security/selinux/include/security.h |    4 -
 security/selinux/selinuxfs.c        |    3
 security/selinux/ss/constraint.h    |    1
 security/selinux/ss/context.h       |   10 +--
 security/selinux/ss/mls.c           |   26 ++++----
 security/selinux/ss/mls.h           |    4 +
 security/selinux/ss/mls_types.h     |    5 -
 security/selinux/ss/policydb.c      |   24 +------
 security/selinux/ss/policydb.h      |    4 +
 security/selinux/ss/services.c      |   79 ++++++++++++++++++++++++--
 security/selinux/ss/services.h      |    1
 security/selinux/ss/sidtab.h        |    1
 security/selinux/ss/symtab.h        |    1
 13 files changed, 113 insertions(+), 50 deletions(-)
 


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
@ 2010-02-01 21:49 Guido Trentalancia
  2010-02-01 22:09 ` Stephen Smalley
  0 siblings, 1 reply; 33+ messages in thread
From: Guido Trentalancia @ 2010-02-01 21:49 UTC (permalink / raw)
  To: sds; +Cc: selinux, eparis, jmorris


[-- Attachment #1.1: Type: text/plain, Size: 18572 bytes --]

Stephen,

yes you are right. There is no need to include policydb.h from security.h.

Please have a further look at the attached revised patch, while I do some testing of the resulting compiled kernel. I hope I did not miss any amendment.

If it is fine and nobody else has comments or suggestions to make, then we should probably post it to the kernel mailing list with your Acked-by or Reviewed-by line.

Best regards,

Guido

Author: Guido Trentalancia <guido@trentalancia.com>
Date:   Mon Feb 01 22:34:16 2010 +0100

    Allow runtime switching between different policy types (e.g. from a MLS/MCS
    policy to a non-MLS/non-MCS policy or viceversa).

    Signed-off-by: Guido Trentalancia <guido@trentalancia.com>

diff -pruN security-testing-2.6/security/selinux/include/security.h security-testing-2.6-new/security/selinux/include/security.h
--- security-testing-2.6/security/selinux/include/security.h	2010-01-29 02:02:47.737045258 +0100
+++ security-testing-2.6-new/security/selinux/include/security.h	2010-02-01 22:06:38.053225052 +0100
@@ -57,7 +57,7 @@
 struct netlbl_lsm_secattr;

 extern int selinux_enabled;
-extern int selinux_mls_enabled;
+extern struct policydb policydb;

 /* Policy capabilities */
 enum {
@@ -80,6 +80,8 @@ extern int selinux_policycap_openperm;
 /* limitation of boundary depth  */
 #define POLICYDB_BOUNDS_MAXDEPTH	4

+int security_mls_enabled(void);
+
 int security_load_policy(void *data, size_t len);

 int security_policycap_supported(unsigned int req_cap);
diff -pruN security-testing-2.6/security/selinux/selinuxfs.c security-testing-2.6-new/security/selinux/selinuxfs.c
--- security-testing-2.6/security/selinux/selinuxfs.c	2010-01-29 02:02:47.738046835 +0100
+++ security-testing-2.6-new/security/selinux/selinuxfs.c	2010-02-01 22:06:21.709234039 +0100
@@ -282,7 +282,8 @@ static ssize_t sel_read_mls(struct file
 	char tmpbuf[TMPBUFLEN];
 	ssize_t length;

-	length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_mls_enabled);
+	length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
+			   security_mls_enabled());
 	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
 }

diff -pruN security-testing-2.6/security/selinux/ss/constraint.h security-testing-2.6-new/security/selinux/ss/constraint.h
--- security-testing-2.6/security/selinux/ss/constraint.h	2010-01-29 01:06:42.160060332 +0100
+++ security-testing-2.6-new/security/selinux/ss/constraint.h	2010-02-01 20:50:19.860227025 +0100
@@ -12,6 +12,7 @@
  *
  * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
  */
+
 #ifndef _SS_CONSTRAINT_H_
 #define _SS_CONSTRAINT_H_

diff -pruN security-testing-2.6/security/selinux/ss/context.h security-testing-2.6-new/security/selinux/ss/context.h
--- security-testing-2.6/security/selinux/ss/context.h	2010-01-29 01:06:42.160060332 +0100
+++ security-testing-2.6-new/security/selinux/ss/context.h	2010-02-01 22:22:33.090234587 +0100
@@ -12,6 +12,7 @@
  *
  * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
  */
+
 #ifndef _SS_CONTEXT_H_
 #define _SS_CONTEXT_H_

@@ -41,7 +42,7 @@ static inline int mls_context_cpy(struct
 {
 	int rc;

-	if (!selinux_mls_enabled)
+	if (!security_mls_enabled())
 		return 0;

 	dst->range.level[0].sens = src->range.level[0].sens;
@@ -64,7 +65,7 @@ static inline int mls_context_cpy_low(st
 {
 	int rc;

-	if (!selinux_mls_enabled)
+	if (!security_mls_enabled())
 		return 0;

 	dst->range.level[0].sens = src->range.level[0].sens;
@@ -82,7 +83,7 @@ out:

 static inline int mls_context_cmp(struct context *c1, struct context *c2)
 {
-	if (!selinux_mls_enabled)
+	if (!security_mls_enabled())
 		return 1;

 	return ((c1->range.level[0].sens == c2->range.level[0].sens) &&
@@ -93,9 +94,6 @@ static inline int mls_context_cmp(struct

 static inline void mls_context_destroy(struct context *c)
 {
-	if (!selinux_mls_enabled)
-		return;
-
 	ebitmap_destroy(&c->range.level[0].cat);
 	ebitmap_destroy(&c->range.level[1].cat);
 	mls_context_init(c);
diff -pruN security-testing-2.6/security/selinux/ss/mls.c security-testing-2.6-new/security/selinux/ss/mls.c
--- security-testing-2.6/security/selinux/ss/mls.c	2010-01-29 02:02:47.739046177 +0100
+++ security-testing-2.6-new/security/selinux/ss/mls.c	2010-02-01 22:15:48.062233721 +0100
@@ -39,7 +39,7 @@ int mls_compute_context_len(struct conte
 	struct ebitmap *e;
 	struct ebitmap_node *node;

-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;

 	len = 1; /* for the beginning ":" */
@@ -93,7 +93,7 @@ void mls_sid_to_context(struct context *
 	struct ebitmap *e;
 	struct ebitmap_node *node;

-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return;

 	scontextp = *scontext;
@@ -200,7 +200,7 @@ int mls_context_isvalid(struct policydb
 {
 	struct user_datum *usrdatum;

-	if (!selinux_mls_enabled)
+	if (!p->mls_enabled)
 		return 1;

 	if (!mls_range_isvalid(p, &c->range))
@@ -253,7 +253,7 @@ int mls_context_to_sid(struct policydb *
 	struct cat_datum *catdatum, *rngdatum;
 	int l, rc = -EINVAL;

-	if (!selinux_mls_enabled) {
+	if (!pol->mls_enabled) {
 		if (def_sid != SECSID_NULL && oldc)
 			*scontext += strlen(*scontext)+1;
 		return 0;
@@ -387,7 +387,7 @@ int mls_from_string(char *str, struct co
 	char *tmpstr, *freestr;
 	int rc;

-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return -EINVAL;

 	/* we need freestr because mls_context_to_sid will change
@@ -407,7 +407,7 @@ int mls_from_string(char *str, struct co
 /*
  * Copies the MLS range `range' into `context'.
  */
-static inline int mls_range_set(struct context *context,
+int mls_range_set(struct context *context,
 				struct mls_range *range)
 {
 	int l, rc = 0;
@@ -427,7 +427,7 @@ static inline int mls_range_set(struct c
 int mls_setup_user_range(struct context *fromcon, struct user_datum *user,
 			 struct context *usercon)
 {
-	if (selinux_mls_enabled) {
+	if (policydb.mls_enabled) {
 		struct mls_level *fromcon_sen = &(fromcon->range.level[0]);
 		struct mls_level *fromcon_clr = &(fromcon->range.level[1]);
 		struct mls_level *user_low = &(user->range.level[0]);
@@ -477,7 +477,7 @@ int mls_convert_context(struct policydb
 	struct ebitmap_node *node;
 	int l, i;

-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;

 	for (l = 0; l < 2; l++) {
@@ -516,7 +516,7 @@ int mls_compute_sid(struct context *scon
 	struct range_trans rtr;
 	struct mls_range *r;

-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;

 	switch (specified) {
@@ -559,7 +559,7 @@ int mls_compute_sid(struct context *scon
 void mls_export_netlbl_lvl(struct context *context,
 			   struct netlbl_lsm_secattr *secattr)
 {
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return;

 	secattr->attr.mls.lvl = context->range.level[0].sens - 1;
@@ -579,7 +579,7 @@ void mls_export_netlbl_lvl(struct contex
 void mls_import_netlbl_lvl(struct context *context,
 			   struct netlbl_lsm_secattr *secattr)
 {
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return;

 	context->range.level[0].sens = secattr->attr.mls.lvl + 1;
@@ -601,7 +601,7 @@ int mls_export_netlbl_cat(struct context
 {
 	int rc;

-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;

 	rc = ebitmap_netlbl_export(&context->range.level[0].cat,
@@ -629,7 +629,7 @@ int mls_import_netlbl_cat(struct context
 {
 	int rc;

-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;

 	rc = ebitmap_netlbl_import(&context->range.level[0].cat,
diff -pruN security-testing-2.6/security/selinux/ss/mls.h security-testing-2.6-new/security/selinux/ss/mls.h
--- security-testing-2.6/security/selinux/ss/mls.h	2010-01-29 01:06:42.168051431 +0100
+++ security-testing-2.6-new/security/selinux/ss/mls.h	2010-02-01 18:57:42.693221952 +0100
@@ -24,6 +24,8 @@
 #include "context.h"
 #include "policydb.h"

+extern struct policydb policydb;
+
 int mls_compute_context_len(struct context *context);
 void mls_sid_to_context(struct context *context, char **scontext);
 int mls_context_isvalid(struct policydb *p, struct context *c);
@@ -39,6 +41,8 @@ int mls_context_to_sid(struct policydb *

 int mls_from_string(char *str, struct context *context, gfp_t gfp_mask);

+int mls_range_set(struct context *context, struct mls_range *range);
+
 int mls_convert_context(struct policydb *oldp,
 			struct policydb *newp,
 			struct context *context);
diff -pruN security-testing-2.6/security/selinux/ss/mls_types.h security-testing-2.6-new/security/selinux/ss/mls_types.h
--- security-testing-2.6/security/selinux/ss/mls_types.h	2010-01-29 01:06:42.168051431 +0100
+++ security-testing-2.6-new/security/selinux/ss/mls_types.h	2010-02-01 22:23:11.799224771 +0100
@@ -15,6 +15,7 @@
 #define _SS_MLS_TYPES_H_

 #include "security.h"
+#include "ebitmap.h"

 struct mls_level {
 	u32 sens;		/* sensitivity */
@@ -27,7 +28,7 @@ struct mls_range {

 static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2)
 {
-	if (!selinux_mls_enabled)
+	if (!security_mls_enabled())
 		return 1;

 	return ((l1->sens == l2->sens) &&
@@ -36,7 +37,7 @@ static inline int mls_level_eq(struct ml

 static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2)
 {
-	if (!selinux_mls_enabled)
+	if (!security_mls_enabled())
 		return 1;

 	return ((l1->sens >= l2->sens) &&
diff -pruN security-testing-2.6/security/selinux/ss/policydb.c security-testing-2.6-new/security/selinux/ss/policydb.c
--- security-testing-2.6/security/selinux/ss/policydb.c	2010-01-29 02:02:47.740046077 +0100
+++ security-testing-2.6-new/security/selinux/ss/policydb.c	2010-02-01 22:12:18.601226073 +0100
@@ -52,8 +52,6 @@ static char *symtab_name[SYM_NUM] = {
 };
 #endif

-int selinux_mls_enabled;
-
 static unsigned int symtab_sizes[SYM_NUM] = {
 	2,
 	32,
@@ -455,7 +453,7 @@ static int policydb_index_others(struct

 	printk(KERN_DEBUG "SELinux:  %d users, %d roles, %d types, %d bools",
 	       p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim);
-	if (selinux_mls_enabled)
+	if (p->mls_enabled)
 		printk(", %d sens, %d cats", p->p_levels.nprim,
 		       p->p_cats.nprim);
 	printk("n");
@@ -1717,14 +1715,12 @@ int policydb_read(struct policydb *p, vo
 	int i, j, rc;
 	__le32 buf[4];
 	u32 nodebuf[8];
-	u32 len, len2, config, nprim, nel, nel2;
+	u32 len, len2, nprim, nel, nel2;
 	char *policydb_str;
 	struct policydb_compat_info *info;
 	struct range_trans *rt;
 	struct mls_range *r;

-	config = 0;
-
 	rc = policydb_init(p);
 	if (rc)
 		goto out;
@@ -1772,7 +1768,7 @@ int policydb_read(struct policydb *p, vo
 	kfree(policydb_str);
 	policydb_str = NULL;

-	/* Read the version, config, and table sizes. */
+	/* Read the version and table sizes. */
 	rc = next_entry(buf, fp, sizeof(u32)*4);
 	if (rc < 0)
 		goto bad;
@@ -1787,13 +1783,7 @@ int policydb_read(struct policydb *p, vo
 	}

 	if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) {
-		if (ss_initialized && !selinux_mls_enabled) {
-			printk(KERN_ERR "SELinux: Cannot switch between non-MLS"
-				" and MLS policiesn");
-			goto bad;
-		}
-		selinux_mls_enabled = 1;
-		config |= POLICYDB_CONFIG_MLS;
+		p->mls_enabled = 1;

 		if (p->policyvers < POLICYDB_VERSION_MLS) {
 			printk(KERN_ERR "SELinux: security policydb version %d "
@@ -1801,12 +1791,6 @@ int policydb_read(struct policydb *p, vo
 				p->policyvers);
 			goto bad;
 		}
-	} else {
-		if (ss_initialized && selinux_mls_enabled) {
-			printk(KERN_ERR "SELinux: Cannot switch between MLS and"
-				" non-MLS policiesn");
-			goto bad;
-		}
 	}
 	p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN);
 	p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);
diff -pruN security-testing-2.6/security/selinux/ss/policydb.h security-testing-2.6-new/security/selinux/ss/policydb.h
--- security-testing-2.6/security/selinux/ss/policydb.h	2010-01-29 02:02:47.740046077 +0100
+++ security-testing-2.6-new/security/selinux/ss/policydb.h	2010-02-01 20:47:08.352232380 +0100
@@ -27,6 +27,8 @@
 #include "symtab.h"
 #include "avtab.h"
 #include "sidtab.h"
+#include "ebitmap.h"
+#include "mls_types.h"
 #include "context.h"
 #include "constraint.h"

@@ -185,6 +187,8 @@ struct genfs {

 /* The policy database */
 struct policydb {
+	int mls_enabled;
+
 	/* symbol tables */
 	struct symtab symtab[SYM_NUM];
 #define p_commons symtab[SYM_COMMONS]
diff -pruN security-testing-2.6/security/selinux/ss/services.c security-testing-2.6-new/security/selinux/ss/services.c
--- security-testing-2.6/security/selinux/ss/services.c	2010-01-29 02:02:47.742042805 +0100
+++ security-testing-2.6-new/security/selinux/ss/services.c	2010-02-01 22:41:08.730228020 +0100
@@ -26,6 +26,10 @@
  *
  *  Added support for bounds domain and audit messaged on masked permissions
  *
+ * Updated: Guido Trentalancia <guido@trentalancia.com>
+ *
+ *  Added support for runtime switching of the policy type
+ *
  * Copyright (C) 2008, 2009 NEC Corporation
  * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P.
  * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
@@ -232,6 +236,16 @@ static void map_decision(u16 tclass, str
 	}
 }

+/*
+ * Returns a boolean value.
+ * True: if the specified policy is MLS or MCS
+ * False: if the specified policy is a standard policy
+ * 	  without MLS/MCS support
+ */
+int security_mls_enabled(void)
+{
+	return policydb.mls_enabled;
+}

 /*
  * Return the boolean value of a constraint expression
@@ -1547,6 +1561,8 @@ static int convert_context(u32 key,
 {
 	struct convert_context_args *args;
 	struct context oldc;
+	struct ocontext *oc;
+	struct mls_range *range;
 	struct role_datum *role;
 	struct type_datum *typdatum;
 	struct user_datum *usrdatum;
@@ -1614,9 +1630,48 @@ static int convert_context(u32 key,
 		goto bad;
 	c->type = typdatum->value;

-	rc = mls_convert_context(args->oldp, args->newp, c);
-	if (rc)
-		goto bad;
+	/* Convert the MLS/MCS fields if dealing with MLS/MCS policies */
+	if (args->oldp->mls_enabled
+	    && args->newp->mls_enabled) {
+		rc = mls_convert_context(args->oldp, args->newp, c);
+		if (rc)
+			goto bad;
+	}
+
+	/*
+	 * Switching between MLS/MCS and non-MLS/non-MCS policy:
+	 * free any storage used by the MLS fields in the
+	 * context for all existing entries in the sidtab.
+	 */
+	if (args->oldp->mls_enabled && !args->newp->mls_enabled)
+		mls_context_destroy(c);
+
+	/*
+	 * Switching between non-MLS/non-MCS and MLS/MCS policy:
+	 * ensure that the MLS fields of the context for all
+	 * existing entries in the sidtab are filled in with a
+	 * suitable default value, likely taken from one of the
+	 * initial SIDs.
+	 */
+	if (!args->oldp->mls_enabled && args->newp->mls_enabled) {
+		oc = args->newp->ocontexts[OCON_ISID];
+		while (oc && oc->sid[0] != SECINITSID_UNLABELED)
+			oc = oc->next;
+		range = &oc->context[0].range;
+		rc = mls_range_set(c, range);
+		if (rc) {
+			if (context_struct_to_string(&oldc, &s, &len))
+				return -ENOMEM;
+			context_destroy(&oldc);
+			context_destroy(c);
+			c->str = s;
+			c->len = len;
+			printk(KERN_ERR "SELinux:  Failed to set"
+				" the MLS/MCS range for context"
+				" %sn", c->str);
+			goto out;
+		}
+	}

 	/* Check the validity of the new context. */
 	if (!policydb_context_isvalid(args->newp, c)) {
@@ -1712,6 +1767,14 @@ int security_load_policy(void *data, siz
 	if (policydb_read(&newpolicydb, fp))
 		return -EINVAL;

+	/* If switching between different policy types, log it */
+	if (policydb.mls_enabled && !newpolicydb.mls_enabled)
+		printk(KERN_INFO "SELinux: Switching between MLS/MCS"
+			" and standard policy...n");
+	else if (!policydb.mls_enabled && newpolicydb.mls_enabled)
+		printk(KERN_INFO "SELinux: Switching between standard"
+			" and MLS/MCS policy...n");
+
 	if (sidtab_init(&newsidtab)) {
 		policydb_destroy(&newpolicydb);
 		return -ENOMEM;
@@ -1741,8 +1804,12 @@ int security_load_policy(void *data, siz
 	args.oldp = &policydb;
 	args.newp = &newpolicydb;
 	rc = sidtab_map(&newsidtab, convert_context, &args);
-	if (rc)
+	if (rc) {
+		printk(KERN_ERR "SELinux:  unable to convert the internal"
+			" representation of contexts in the new SID"
+			" tablen");
 		goto err;
+	}

 	/* Save the old policydb and SID table to free later. */
 	memcpy(&oldpolicydb, &policydb, sizeof policydb);
@@ -2338,7 +2405,7 @@ int security_sid_mls_copy(u32 sid, u32 m
 	u32 len;
 	int rc = 0;

-	if (!ss_initialized || !selinux_mls_enabled) {
+	if (!ss_initialized || !policydb.mls_enabled) {
 		*new_sid = sid;
 		goto out;
 	}
@@ -2439,7 +2506,7 @@ int security_net_peersid_resolve(u32 nlb
 	/* we don't need to check ss_initialized here since the only way both
 	 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the
 	 * security server was initialized and ss_initialized was true */
-	if (!selinux_mls_enabled) {
+	if (!policydb.mls_enabled) {
 		*peer_sid = SECSID_NULL;
 		return 0;
 	}
diff -pruN security-testing-2.6/security/selinux/ss/services.h security-testing-2.6-new/security/selinux/ss/services.h
--- security-testing-2.6/security/selinux/ss/services.h	2010-01-29 01:06:42.174044406 +0100
+++ security-testing-2.6-new/security/selinux/ss/services.h	2010-02-01 18:26:32.682234915 +0100
@@ -3,6 +3,7 @@
  *
  * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
  */
+
 #ifndef _SS_SERVICES_H_
 #define _SS_SERVICES_H_

diff -pruN security-testing-2.6/security/selinux/ss/sidtab.h security-testing-2.6-new/security/selinux/ss/sidtab.h
--- security-testing-2.6/security/selinux/ss/sidtab.h	2010-01-29 01:06:42.175047659 +0100
+++ security-testing-2.6-new/security/selinux/ss/sidtab.h	2010-02-01 20:38:09.350520786 +0100
@@ -51,4 +51,3 @@ void sidtab_shutdown(struct sidtab *s);

 #endif	/* _SS_SIDTAB_H_ */

-
diff -pruN security-testing-2.6/security/selinux/ss/symtab.h security-testing-2.6-new/security/selinux/ss/symtab.h
--- security-testing-2.6/security/selinux/ss/symtab.h	2010-01-29 01:06:42.176055661 +0100
+++ security-testing-2.6-new/security/selinux/ss/symtab.h	2010-02-01 20:50:54.661232717 +0100
@@ -6,6 +6,7 @@
  *
  * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
  */
+
 #ifndef _SS_SYMTAB_H_
 #define _SS_SYMTAB_H_


[-- Attachment #2: switch-policy.patch --]
[-- Type: application/octet-stream, Size: 17669 bytes --]

Author: Guido Trentalancia <guido@trentalancia.com>
Date:   Mon Feb 01 22:34:16 2010 +0100

    Allow runtime switching between different policy types (e.g. from a MLS/MCS
    policy to a non-MLS/non-MCS policy or viceversa).

    Signed-off-by: Guido Trentalancia <guido@trentalancia.com>

diff -pruN security-testing-2.6/security/selinux/include/security.h security-testing-2.6-new/security/selinux/include/security.h
--- security-testing-2.6/security/selinux/include/security.h	2010-01-29 02:02:47.737045258 +0100
+++ security-testing-2.6-new/security/selinux/include/security.h	2010-02-01 22:06:38.053225052 +0100
@@ -57,7 +57,7 @@
 struct netlbl_lsm_secattr;
 
 extern int selinux_enabled;
-extern int selinux_mls_enabled;
+extern struct policydb policydb;
 
 /* Policy capabilities */
 enum {
@@ -80,6 +80,8 @@ extern int selinux_policycap_openperm;
 /* limitation of boundary depth  */
 #define POLICYDB_BOUNDS_MAXDEPTH	4
 
+int security_mls_enabled(void);
+
 int security_load_policy(void *data, size_t len);
 
 int security_policycap_supported(unsigned int req_cap);
diff -pruN security-testing-2.6/security/selinux/selinuxfs.c security-testing-2.6-new/security/selinux/selinuxfs.c
--- security-testing-2.6/security/selinux/selinuxfs.c	2010-01-29 02:02:47.738046835 +0100
+++ security-testing-2.6-new/security/selinux/selinuxfs.c	2010-02-01 22:06:21.709234039 +0100
@@ -282,7 +282,8 @@ static ssize_t sel_read_mls(struct file 
 	char tmpbuf[TMPBUFLEN];
 	ssize_t length;
 
-	length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_mls_enabled);
+	length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
+			   security_mls_enabled());
 	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
 }
 
diff -pruN security-testing-2.6/security/selinux/ss/constraint.h security-testing-2.6-new/security/selinux/ss/constraint.h
--- security-testing-2.6/security/selinux/ss/constraint.h	2010-01-29 01:06:42.160060332 +0100
+++ security-testing-2.6-new/security/selinux/ss/constraint.h	2010-02-01 20:50:19.860227025 +0100
@@ -12,6 +12,7 @@
  *
  * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
  */
+
 #ifndef _SS_CONSTRAINT_H_
 #define _SS_CONSTRAINT_H_
 
diff -pruN security-testing-2.6/security/selinux/ss/context.h security-testing-2.6-new/security/selinux/ss/context.h
--- security-testing-2.6/security/selinux/ss/context.h	2010-01-29 01:06:42.160060332 +0100
+++ security-testing-2.6-new/security/selinux/ss/context.h	2010-02-01 22:22:33.090234587 +0100
@@ -12,6 +12,7 @@
  *
  * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
  */
+
 #ifndef _SS_CONTEXT_H_
 #define _SS_CONTEXT_H_
 
@@ -41,7 +42,7 @@ static inline int mls_context_cpy(struct
 {
 	int rc;
 
-	if (!selinux_mls_enabled)
+	if (!security_mls_enabled())
 		return 0;
 
 	dst->range.level[0].sens = src->range.level[0].sens;
@@ -64,7 +65,7 @@ static inline int mls_context_cpy_low(st
 {
 	int rc;
 
-	if (!selinux_mls_enabled)
+	if (!security_mls_enabled())
 		return 0;
 
 	dst->range.level[0].sens = src->range.level[0].sens;
@@ -82,7 +83,7 @@ out:
 
 static inline int mls_context_cmp(struct context *c1, struct context *c2)
 {
-	if (!selinux_mls_enabled)
+	if (!security_mls_enabled())
 		return 1;
 
 	return ((c1->range.level[0].sens == c2->range.level[0].sens) &&
@@ -93,9 +94,6 @@ static inline int mls_context_cmp(struct
 
 static inline void mls_context_destroy(struct context *c)
 {
-	if (!selinux_mls_enabled)
-		return;
-
 	ebitmap_destroy(&c->range.level[0].cat);
 	ebitmap_destroy(&c->range.level[1].cat);
 	mls_context_init(c);
diff -pruN security-testing-2.6/security/selinux/ss/mls.c security-testing-2.6-new/security/selinux/ss/mls.c
--- security-testing-2.6/security/selinux/ss/mls.c	2010-01-29 02:02:47.739046177 +0100
+++ security-testing-2.6-new/security/selinux/ss/mls.c	2010-02-01 22:15:48.062233721 +0100
@@ -39,7 +39,7 @@ int mls_compute_context_len(struct conte
 	struct ebitmap *e;
 	struct ebitmap_node *node;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;
 
 	len = 1; /* for the beginning ":" */
@@ -93,7 +93,7 @@ void mls_sid_to_context(struct context *
 	struct ebitmap *e;
 	struct ebitmap_node *node;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return;
 
 	scontextp = *scontext;
@@ -200,7 +200,7 @@ int mls_context_isvalid(struct policydb 
 {
 	struct user_datum *usrdatum;
 
-	if (!selinux_mls_enabled)
+	if (!p->mls_enabled)
 		return 1;
 
 	if (!mls_range_isvalid(p, &c->range))
@@ -253,7 +253,7 @@ int mls_context_to_sid(struct policydb *
 	struct cat_datum *catdatum, *rngdatum;
 	int l, rc = -EINVAL;
 
-	if (!selinux_mls_enabled) {
+	if (!pol->mls_enabled) {
 		if (def_sid != SECSID_NULL && oldc)
 			*scontext += strlen(*scontext)+1;
 		return 0;
@@ -387,7 +387,7 @@ int mls_from_string(char *str, struct co
 	char *tmpstr, *freestr;
 	int rc;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return -EINVAL;
 
 	/* we need freestr because mls_context_to_sid will change
@@ -407,7 +407,7 @@ int mls_from_string(char *str, struct co
 /*
  * Copies the MLS range `range' into `context'.
  */
-static inline int mls_range_set(struct context *context,
+int mls_range_set(struct context *context,
 				struct mls_range *range)
 {
 	int l, rc = 0;
@@ -427,7 +427,7 @@ static inline int mls_range_set(struct c
 int mls_setup_user_range(struct context *fromcon, struct user_datum *user,
 			 struct context *usercon)
 {
-	if (selinux_mls_enabled) {
+	if (policydb.mls_enabled) {
 		struct mls_level *fromcon_sen = &(fromcon->range.level[0]);
 		struct mls_level *fromcon_clr = &(fromcon->range.level[1]);
 		struct mls_level *user_low = &(user->range.level[0]);
@@ -477,7 +477,7 @@ int mls_convert_context(struct policydb 
 	struct ebitmap_node *node;
 	int l, i;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;
 
 	for (l = 0; l < 2; l++) {
@@ -516,7 +516,7 @@ int mls_compute_sid(struct context *scon
 	struct range_trans rtr;
 	struct mls_range *r;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;
 
 	switch (specified) {
@@ -559,7 +559,7 @@ int mls_compute_sid(struct context *scon
 void mls_export_netlbl_lvl(struct context *context,
 			   struct netlbl_lsm_secattr *secattr)
 {
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return;
 
 	secattr->attr.mls.lvl = context->range.level[0].sens - 1;
@@ -579,7 +579,7 @@ void mls_export_netlbl_lvl(struct contex
 void mls_import_netlbl_lvl(struct context *context,
 			   struct netlbl_lsm_secattr *secattr)
 {
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return;
 
 	context->range.level[0].sens = secattr->attr.mls.lvl + 1;
@@ -601,7 +601,7 @@ int mls_export_netlbl_cat(struct context
 {
 	int rc;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;
 
 	rc = ebitmap_netlbl_export(&context->range.level[0].cat,
@@ -629,7 +629,7 @@ int mls_import_netlbl_cat(struct context
 {
 	int rc;
 
-	if (!selinux_mls_enabled)
+	if (!policydb.mls_enabled)
 		return 0;
 
 	rc = ebitmap_netlbl_import(&context->range.level[0].cat,
diff -pruN security-testing-2.6/security/selinux/ss/mls.h security-testing-2.6-new/security/selinux/ss/mls.h
--- security-testing-2.6/security/selinux/ss/mls.h	2010-01-29 01:06:42.168051431 +0100
+++ security-testing-2.6-new/security/selinux/ss/mls.h	2010-02-01 18:57:42.693221952 +0100
@@ -24,6 +24,8 @@
 #include "context.h"
 #include "policydb.h"
 
+extern struct policydb policydb;
+
 int mls_compute_context_len(struct context *context);
 void mls_sid_to_context(struct context *context, char **scontext);
 int mls_context_isvalid(struct policydb *p, struct context *c);
@@ -39,6 +41,8 @@ int mls_context_to_sid(struct policydb *
 
 int mls_from_string(char *str, struct context *context, gfp_t gfp_mask);
 
+int mls_range_set(struct context *context, struct mls_range *range);
+
 int mls_convert_context(struct policydb *oldp,
 			struct policydb *newp,
 			struct context *context);
diff -pruN security-testing-2.6/security/selinux/ss/mls_types.h security-testing-2.6-new/security/selinux/ss/mls_types.h
--- security-testing-2.6/security/selinux/ss/mls_types.h	2010-01-29 01:06:42.168051431 +0100
+++ security-testing-2.6-new/security/selinux/ss/mls_types.h	2010-02-01 22:23:11.799224771 +0100
@@ -15,6 +15,7 @@
 #define _SS_MLS_TYPES_H_
 
 #include "security.h"
+#include "ebitmap.h"
 
 struct mls_level {
 	u32 sens;		/* sensitivity */
@@ -27,7 +28,7 @@ struct mls_range {
 
 static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2)
 {
-	if (!selinux_mls_enabled)
+	if (!security_mls_enabled())
 		return 1;
 
 	return ((l1->sens == l2->sens) &&
@@ -36,7 +37,7 @@ static inline int mls_level_eq(struct ml
 
 static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2)
 {
-	if (!selinux_mls_enabled)
+	if (!security_mls_enabled())
 		return 1;
 
 	return ((l1->sens >= l2->sens) &&
diff -pruN security-testing-2.6/security/selinux/ss/policydb.c security-testing-2.6-new/security/selinux/ss/policydb.c
--- security-testing-2.6/security/selinux/ss/policydb.c	2010-01-29 02:02:47.740046077 +0100
+++ security-testing-2.6-new/security/selinux/ss/policydb.c	2010-02-01 22:12:18.601226073 +0100
@@ -52,8 +52,6 @@ static char *symtab_name[SYM_NUM] = {
 };
 #endif
 
-int selinux_mls_enabled;
-
 static unsigned int symtab_sizes[SYM_NUM] = {
 	2,
 	32,
@@ -455,7 +453,7 @@ static int policydb_index_others(struct 
 
 	printk(KERN_DEBUG "SELinux:  %d users, %d roles, %d types, %d bools",
 	       p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim);
-	if (selinux_mls_enabled)
+	if (p->mls_enabled)
 		printk(", %d sens, %d cats", p->p_levels.nprim,
 		       p->p_cats.nprim);
 	printk("\n");
@@ -1717,14 +1715,12 @@ int policydb_read(struct policydb *p, vo
 	int i, j, rc;
 	__le32 buf[4];
 	u32 nodebuf[8];
-	u32 len, len2, config, nprim, nel, nel2;
+	u32 len, len2, nprim, nel, nel2;
 	char *policydb_str;
 	struct policydb_compat_info *info;
 	struct range_trans *rt;
 	struct mls_range *r;
 
-	config = 0;
-
 	rc = policydb_init(p);
 	if (rc)
 		goto out;
@@ -1772,7 +1768,7 @@ int policydb_read(struct policydb *p, vo
 	kfree(policydb_str);
 	policydb_str = NULL;
 
-	/* Read the version, config, and table sizes. */
+	/* Read the version and table sizes. */
 	rc = next_entry(buf, fp, sizeof(u32)*4);
 	if (rc < 0)
 		goto bad;
@@ -1787,13 +1783,7 @@ int policydb_read(struct policydb *p, vo
 	}
 
 	if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) {
-		if (ss_initialized && !selinux_mls_enabled) {
-			printk(KERN_ERR "SELinux: Cannot switch between non-MLS"
-				" and MLS policies\n");
-			goto bad;
-		}
-		selinux_mls_enabled = 1;
-		config |= POLICYDB_CONFIG_MLS;
+		p->mls_enabled = 1;
 
 		if (p->policyvers < POLICYDB_VERSION_MLS) {
 			printk(KERN_ERR "SELinux: security policydb version %d "
@@ -1801,12 +1791,6 @@ int policydb_read(struct policydb *p, vo
 				p->policyvers);
 			goto bad;
 		}
-	} else {
-		if (ss_initialized && selinux_mls_enabled) {
-			printk(KERN_ERR "SELinux: Cannot switch between MLS and"
-				" non-MLS policies\n");
-			goto bad;
-		}
 	}
 	p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN);
 	p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);
diff -pruN security-testing-2.6/security/selinux/ss/policydb.h security-testing-2.6-new/security/selinux/ss/policydb.h
--- security-testing-2.6/security/selinux/ss/policydb.h	2010-01-29 02:02:47.740046077 +0100
+++ security-testing-2.6-new/security/selinux/ss/policydb.h	2010-02-01 20:47:08.352232380 +0100
@@ -27,6 +27,8 @@
 #include "symtab.h"
 #include "avtab.h"
 #include "sidtab.h"
+#include "ebitmap.h"
+#include "mls_types.h"
 #include "context.h"
 #include "constraint.h"
 
@@ -185,6 +187,8 @@ struct genfs {
 
 /* The policy database */
 struct policydb {
+	int mls_enabled;
+
 	/* symbol tables */
 	struct symtab symtab[SYM_NUM];
 #define p_commons symtab[SYM_COMMONS]
diff -pruN security-testing-2.6/security/selinux/ss/services.c security-testing-2.6-new/security/selinux/ss/services.c
--- security-testing-2.6/security/selinux/ss/services.c	2010-01-29 02:02:47.742042805 +0100
+++ security-testing-2.6-new/security/selinux/ss/services.c	2010-02-01 22:41:08.730228020 +0100
@@ -26,6 +26,10 @@
  *
  *  Added support for bounds domain and audit messaged on masked permissions
  *
+ * Updated: Guido Trentalancia <guido@trentalancia.com>
+ *
+ *  Added support for runtime switching of the policy type
+ *
  * Copyright (C) 2008, 2009 NEC Corporation
  * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P.
  * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
@@ -232,6 +236,16 @@ static void map_decision(u16 tclass, str
 	}
 }
 
+/*
+ * Returns a boolean value.
+ * True: if the specified policy is MLS or MCS
+ * False: if the specified policy is a standard policy
+ * 	  without MLS/MCS support
+ */
+int security_mls_enabled(void)
+{
+	return policydb.mls_enabled;
+}
 
 /*
  * Return the boolean value of a constraint expression
@@ -1547,6 +1561,8 @@ static int convert_context(u32 key,
 {
 	struct convert_context_args *args;
 	struct context oldc;
+	struct ocontext *oc;
+	struct mls_range *range;
 	struct role_datum *role;
 	struct type_datum *typdatum;
 	struct user_datum *usrdatum;
@@ -1614,9 +1630,48 @@ static int convert_context(u32 key,
 		goto bad;
 	c->type = typdatum->value;
 
-	rc = mls_convert_context(args->oldp, args->newp, c);
-	if (rc)
-		goto bad;
+	/* Convert the MLS/MCS fields if dealing with MLS/MCS policies */
+	if (args->oldp->mls_enabled
+	    && args->newp->mls_enabled) {
+		rc = mls_convert_context(args->oldp, args->newp, c);
+		if (rc)
+			goto bad;
+	}
+
+	/*
+	 * Switching between MLS/MCS and non-MLS/non-MCS policy:
+	 * free any storage used by the MLS fields in the
+	 * context for all existing entries in the sidtab.
+	 */
+	if (args->oldp->mls_enabled && !args->newp->mls_enabled)
+		mls_context_destroy(c);
+
+	/*
+	 * Switching between non-MLS/non-MCS and MLS/MCS policy:
+	 * ensure that the MLS fields of the context for all
+	 * existing entries in the sidtab are filled in with a
+	 * suitable default value, likely taken from one of the
+	 * initial SIDs.
+	 */
+	if (!args->oldp->mls_enabled && args->newp->mls_enabled) {
+		oc = args->newp->ocontexts[OCON_ISID];
+		while (oc && oc->sid[0] != SECINITSID_UNLABELED)
+			oc = oc->next;
+		range = &oc->context[0].range;
+		rc = mls_range_set(c, range);
+		if (rc) {
+			if (context_struct_to_string(&oldc, &s, &len))
+				return -ENOMEM;
+			context_destroy(&oldc);
+			context_destroy(c);
+			c->str = s;
+			c->len = len;
+			printk(KERN_ERR "SELinux:  Failed to set"
+				" the MLS/MCS range for context"
+				" %s\n", c->str);
+			goto out;
+		}
+	}
 
 	/* Check the validity of the new context. */
 	if (!policydb_context_isvalid(args->newp, c)) {
@@ -1712,6 +1767,14 @@ int security_load_policy(void *data, siz
 	if (policydb_read(&newpolicydb, fp))
 		return -EINVAL;
 
+	/* If switching between different policy types, log it */
+	if (policydb.mls_enabled && !newpolicydb.mls_enabled)
+		printk(KERN_INFO "SELinux: Switching between MLS/MCS"
+			" and standard policy...\n");
+	else if (!policydb.mls_enabled && newpolicydb.mls_enabled)
+		printk(KERN_INFO "SELinux: Switching between standard"
+			" and MLS/MCS policy...\n");
+
 	if (sidtab_init(&newsidtab)) {
 		policydb_destroy(&newpolicydb);
 		return -ENOMEM;
@@ -1741,8 +1804,12 @@ int security_load_policy(void *data, siz
 	args.oldp = &policydb;
 	args.newp = &newpolicydb;
 	rc = sidtab_map(&newsidtab, convert_context, &args);
-	if (rc)
+	if (rc) {
+		printk(KERN_ERR "SELinux:  unable to convert the internal"
+			" representation of contexts in the new SID"
+			" table\n");
 		goto err;
+	}
 
 	/* Save the old policydb and SID table to free later. */
 	memcpy(&oldpolicydb, &policydb, sizeof policydb);
@@ -2338,7 +2405,7 @@ int security_sid_mls_copy(u32 sid, u32 m
 	u32 len;
 	int rc = 0;
 
-	if (!ss_initialized || !selinux_mls_enabled) {
+	if (!ss_initialized || !policydb.mls_enabled) {
 		*new_sid = sid;
 		goto out;
 	}
@@ -2439,7 +2506,7 @@ int security_net_peersid_resolve(u32 nlb
 	/* we don't need to check ss_initialized here since the only way both
 	 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the
 	 * security server was initialized and ss_initialized was true */
-	if (!selinux_mls_enabled) {
+	if (!policydb.mls_enabled) {
 		*peer_sid = SECSID_NULL;
 		return 0;
 	}
diff -pruN security-testing-2.6/security/selinux/ss/services.h security-testing-2.6-new/security/selinux/ss/services.h
--- security-testing-2.6/security/selinux/ss/services.h	2010-01-29 01:06:42.174044406 +0100
+++ security-testing-2.6-new/security/selinux/ss/services.h	2010-02-01 18:26:32.682234915 +0100
@@ -3,6 +3,7 @@
  *
  * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
  */
+
 #ifndef _SS_SERVICES_H_
 #define _SS_SERVICES_H_
 
diff -pruN security-testing-2.6/security/selinux/ss/sidtab.h security-testing-2.6-new/security/selinux/ss/sidtab.h
--- security-testing-2.6/security/selinux/ss/sidtab.h	2010-01-29 01:06:42.175047659 +0100
+++ security-testing-2.6-new/security/selinux/ss/sidtab.h	2010-02-01 20:38:09.350520786 +0100
@@ -51,4 +51,3 @@ void sidtab_shutdown(struct sidtab *s);
 
 #endif	/* _SS_SIDTAB_H_ */
 
-
diff -pruN security-testing-2.6/security/selinux/ss/symtab.h security-testing-2.6-new/security/selinux/ss/symtab.h
--- security-testing-2.6/security/selinux/ss/symtab.h	2010-01-29 01:06:42.176055661 +0100
+++ security-testing-2.6-new/security/selinux/ss/symtab.h	2010-02-01 20:50:54.661232717 +0100
@@ -6,6 +6,7 @@
  *
  * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
  */
+
 #ifndef _SS_SYMTAB_H_
 #define _SS_SYMTAB_H_
 

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
  2010-02-01 19:59 Guido Trentalancia
@ 2010-02-01 20:22 ` Stephen Smalley
  0 siblings, 0 replies; 33+ messages in thread
From: Stephen Smalley @ 2010-02-01 20:22 UTC (permalink / raw)
  To: Guido Trentalancia; +Cc: selinux

On Mon, 2010-02-01 at 20:59 +0100, Guido Trentalancia wrote:
> Stephen,
> 
> I have amended most changes to the patch, according to your feedback and here is a track:
> 
> The only function that has been made "standard" from "static inline"
> is mls_range_set which I am using in ss/services.c. Its return value
> is now being checked for robustness, an appropriate KERN_ERR is
> generated in case something goes wrong and the appropriate return code
> is fed back to the caller.

No, out of memory doesn't warrant a KERN_ERR.  Just handle it like other
errors in the same function and we'll get an out of memory error passed
back to userspace.

> The new field of structure policydb has been named mls_enabled and a
> new function security_mls_enabled has been created (and declared in
> the main global header file security.h).
> 
> The comment style in services.c has been changed accordingly to the
> CodingStyle (checkpatch.pl no longer complains).
> 
> External declarations have been removed from .c files (selinuxfs.c)
> and moved to the global header file security.h.
> 
> Missing function declarations have been added to the global include
> files rather than importing header files from ss.
> 
> The unused variable config has been removed from ss/policydb.c.
> 
> The "n" problem is due to a problem in my mailer. The attached file
> does not have the missing control character "".

No attachment was present.

> Issues:
> 
> - security.h now defines security_mls_enabled() and this function
> takes struct policydb * as parameter but this structure is not visible
> to security.h; I overcome this problem by declaring the parameter void
> *.

You shouldn't pass any argument to the function.  It is just:
	int security_mls_enabled(void)
	{
		return policydb.mls_enabled;
	}

The policydb structure is never used outside of the security server
(ss/).

> - when trying to build, I get the following compilation errors now:
> 
>   CC      security/selinux/ss/sidtab.o
> In file included from security/selinux/ss/mls_types.h:20,
>                  from security/selinux/ss/context.h:21,
>                  from security/selinux/ss/sidtab.h:11,
>                  from security/selinux/ss/sidtab.c:13:
> security/selinux/ss/policydb.h:97: error: field 'range' has incomplete type
> security/selinux/ss/policydb.h:98: error: field 'dfltlevel' has incomplete type
> In file included from security/selinux/ss/mls_types.h:20,
>                  from security/selinux/ss/context.h:21,
>                  from security/selinux/ss/sidtab.h:11,
>                  from security/selinux/ss/sidtab.c:13:
> security/selinux/ss/policydb.h:156: error: array type has incomplete element type
> In file included from security/selinux/ss/mls_types.h:20,
>                  from security/selinux/ss/context.h:21,
>                  from security/selinux/ss/sidtab.h:11,
>                  from security/selinux/ss/sidtab.c:13:
> security/selinux/ss/policydb.h:265: warning: 'struct sidtab' declared inside parameter list
> security/selinux/ss/policydb.h:265: warning: its scope is only this definition or declaration, which is probably not what you want
> 
> Note that policydb.h includes symtab.h, avtab.h, sidtab.h, ebitmap.h, mls_types.h, context.h, constraint.h.
> 
> So there must be something wrong in mls_types.h, that's why I moved the inline functions to a separate .c file.
> 
> What do you say ?

You must have introduced a dependency cycle in the headers through your
patch.  I'd have to see it to know for sure.

-- 
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 majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
@ 2010-02-01 19:59 Guido Trentalancia
  2010-02-01 20:22 ` Stephen Smalley
  0 siblings, 1 reply; 33+ messages in thread
From: Guido Trentalancia @ 2010-02-01 19:59 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: selinux

Stephen,

I have amended most changes to the patch, according to your feedback and here is a track:

The only function that has been made "standard" from "static inline" is mls_range_set which I am using in ss/services.c. Its return value is now being checked for robustness, an appropriate KERN_ERR is generated in case something goes wrong and the appropriate return code is fed back to the caller.

The new field of structure policydb has been named mls_enabled and a new function security_mls_enabled has been created (and declared in the main global header file security.h).

The comment style in services.c has been changed accordingly to the CodingStyle (checkpatch.pl no longer complains).

External declarations have been removed from .c files (selinuxfs.c) and moved to the global header file security.h.

Missing function declarations have been added to the global include files rather than importing header files from ss.

The unused variable config has been removed from ss/policydb.c.

The "n" problem is due to a problem in my mailer. The attached file does not have the missing control character "".

Issues:

- security.h now defines security_mls_enabled() and this function takes struct policydb * as parameter but this structure is not visible to security.h; I overcome this problem by declaring the parameter void *.

- when trying to build, I get the following compilation errors now:

  CC      security/selinux/ss/sidtab.o
In file included from security/selinux/ss/mls_types.h:20,
                 from security/selinux/ss/context.h:21,
                 from security/selinux/ss/sidtab.h:11,
                 from security/selinux/ss/sidtab.c:13:
security/selinux/ss/policydb.h:97: error: field 'range' has incomplete type
security/selinux/ss/policydb.h:98: error: field 'dfltlevel' has incomplete type
In file included from security/selinux/ss/mls_types.h:20,
                 from security/selinux/ss/context.h:21,
                 from security/selinux/ss/sidtab.h:11,
                 from security/selinux/ss/sidtab.c:13:
security/selinux/ss/policydb.h:156: error: array type has incomplete element type
In file included from security/selinux/ss/mls_types.h:20,
                 from security/selinux/ss/context.h:21,
                 from security/selinux/ss/sidtab.h:11,
                 from security/selinux/ss/sidtab.c:13:
security/selinux/ss/policydb.h:265: warning: 'struct sidtab' declared inside parameter list
security/selinux/ss/policydb.h:265: warning: its scope is only this definition or declaration, which is probably not what you want

Note that policydb.h includes symtab.h, avtab.h, sidtab.h, ebitmap.h, mls_types.h, context.h, constraint.h.

So there must be something wrong in mls_types.h, that's why I moved the inline functions to a separate .c file.

What do you say ?

Regards,

Guido 


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
  2010-02-01 18:25 Guido Trentalancia
@ 2010-02-01 19:15 ` Stephen Smalley
  0 siblings, 0 replies; 33+ messages in thread
From: Stephen Smalley @ 2010-02-01 19:15 UTC (permalink / raw)
  To: Guido Trentalancia; +Cc: selinux, eparis, jmorris

On Mon, 2010-02-01 at 19:25 +0100, Guido Trentalancia wrote:
> Stephen,
> 
> thanks very much for your last comment. I always forgot to talk about that, despite my intention was to discuss it... It's just that there were many tiny details to discuss.
> 
> > ocontexts[OCON_ISID] is a list of initial SIDs and their 
> > contexts. Your current code takes the MLS range from 
> > whatever happens to be the first entry in the list and uses 
> > that for all of the contexts.
> 
> At the beginning I was scanning for "unlabeled" in oc->u.name with
> strcmp(), but then I wasn't sure about adding extra complexity to the
> code and I left that out waiting for your comments.
> 
> At present, for the latest reference policy the first initial SID is
> "kernel", which surely isn't the best match, but as I already told you
> I was waiting for some feedback on details.
> 
> I will introduce your piece of code (assuming there is always going to
> be an entry for SECINITSID_UNLABELED in the list).
> 
> By the way, is there any drawback in loading the initial SIDs again
> from security_load_policy() using the appropriate function that you
> mentioned ?

policydb_load_isids() is only called from security_load_policy() in the
initial policy load case (!ss_initialized) to initially populate the SID
table from the policy.

In the policy reload case, we instead clone the existing SID table,
convert the entries, and ignore the initial SID entries in the policy
file.  If you were to try to call policydb_load_isids() as is, you'd end
up duplicating SID entries with the cloned table, which should yield an
EEXIST error from sidtab_insert().  I suppose you could call
policydb_load_isids() first, change clone_sid() to skip initial SIDs,
and change convert_context() to skip initial SIDs.

As I recall, we didn't support reloading them at runtime because:
a) They were only to support system initialization in the first place,
and
b) We couldn't really guarantee that any changes to them would be
retroactively applied, and
c) We don't really support dynamic extension of them.

We don't presently support any changes to the set of initial SIDs other
than their contexts; see the third item under:
http://selinuxproject.org/page/Kernel_Development

Support for dynamic discovery of classes and permissions is in 2.6.33.

-- 
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 majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
@ 2010-02-01 18:25 Guido Trentalancia
  2010-02-01 19:15 ` Stephen Smalley
  0 siblings, 1 reply; 33+ messages in thread
From: Guido Trentalancia @ 2010-02-01 18:25 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: selinux, eparis, jmorris

Stephen,

thanks very much for your last comment. I always forgot to talk about that, despite my intention was to discuss it... It's just that there were many tiny details to discuss.

> ocontexts[OCON_ISID] is a list of initial SIDs and their 
> contexts. Your current code takes the MLS range from 
> whatever happens to be the first entry in the list and uses 
> that for all of the contexts.

At the beginning I was scanning for "unlabeled" in oc->u.name with strcmp(), but then I wasn't sure about adding extra complexity to the code and I left that out waiting for your comments.

At present, for the latest reference policy the first initial SID is "kernel", which surely isn't the best match, but as I already told you I was waiting for some feedback on details.

I will introduce your piece of code (assuming there is always going to be an entry for SECINITSID_UNLABELED in the list).

By the way, is there any drawback in loading the initial SIDs again from security_load_policy() using the appropriate function that you mentioned ?

Regards,

Guido 


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
  2010-02-01 16:36 Guido Trentalancia
@ 2010-02-01 17:41 ` Stephen Smalley
  0 siblings, 0 replies; 33+ messages in thread
From: Stephen Smalley @ 2010-02-01 17:41 UTC (permalink / raw)
  To: Guido Trentalancia; +Cc: selinux, eparis, jmorris

On Mon, 2010-02-01 at 17:36 +0100, Guido Trentalancia wrote:
> Excellent Stephen, very timely !
> 
> I am now going to make the necessary amendments and then I will post a proposed final patch that you can eventually review again or otherwise just add an Acked-by or Reviewed-by line and I will forward it to the kernel mailing list.
> 
> Of course comments from other list members are always welcome.
> 
> A few notes on your comments...
> 
> > Avoid adding extern declarations to .c files - they are
> > discouraged. The current code isn't pristine in this
> > regard, but let's not make it worse.
> 
> You are right, I did check with checkpatch.pl, but because selinuxfs.c hasn't got its own header file, I wasn't sure on how to deal with the warning. Shall I create an header file specifically for it or otherwise try to reuse other global header files ?

In this case, you would just add a function prototype for a new
security_mls_enabled() function to include/security.h, implement it in
ss/services.c, and call it from selinuxfs.c.

> > I wouldn't take these functions to their own .c file, and 
> > if you do so, then "inline" no longer makes sense.  But 
> > why did you do so?  It will add overhead to make them 
> > out-of-line with no obvious benefit.
> 
> I was getting compilation errors. Perhaps you can give it a try.

That's a problem with your patch, not with the existing code.  Keep the
functions as static inline functions in their .h files.

> > This seems inconsistent with the other functions - here 
> > you pass the policydb as an argument rather than just 
> > using the active policydb. If that were truly necessary, 
> > I'd argue for passing the policydb to all of the 
> > functions for consistency.  But I think in fact that we 
> > can drop this !mls_enabled check altogether, given that 
> > the context is fully initialized by context_init() and 
> > thus the ebitmap_destroy() calls should be safe 
> > regardless of whether or not MLS is enabled.
> 
> The policydb being passed to the modified functions is not necessarily the same as the active policy. Otherwise there was no point of making the modifications. To be more precise, consider the code-paths from security_load_policy() when you need to destroy the old policy and the old sidtab which are no longer active !
> So, shall I remove completely the check ? That would make
> mls_context_destroy() execute even for standard policies...

Yes, that should cause no harm.

> > Same deal - don't take these to their own .c file without 
> > justification.
> 
> As already explained, I moved those functions to a separate .c file
> because there were compilation error (gcc 4.4.1).

The current code compiles fine, so that would be a problem with your
patch.  Don't move the functions to a separate .c file.  static inline
is fine.  If you have a compilation problem, post the details.

> > Is that supposed to be "n" aka newline rather than just 
> > "n"?
> 
> Yes, of course "n". It's weird because if you look at the attached file, everything is normal ! Something went wrong with the "cut-n-paste" from gedit to Mozilla, I shall probably file a bug report !...

Read Documentation/email-clients.txt, particularly about thunderbird if
you are using it.

-- 
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 majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload
@ 2010-02-01 16:36 Guido Trentalancia
  2010-02-01 17:41 ` Stephen Smalley
  0 siblings, 1 reply; 33+ messages in thread
From: Guido Trentalancia @ 2010-02-01 16:36 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: selinux, eparis, jmorris

Excellent Stephen, very timely !

I am now going to make the necessary amendments and then I will post a proposed final patch that you can eventually review again or otherwise just add an Acked-by or Reviewed-by line and I will forward it to the kernel mailing list.

Of course comments from other list members are always welcome.

A few notes on your comments...

> Avoid adding extern declarations to .c files - they are
> discouraged. The current code isn't pristine in this
> regard, but let's not make it worse.

You are right, I did check with checkpatch.pl, but because selinuxfs.c hasn't got its own header file, I wasn't sure on how to deal with the warning. Shall I create an header file specifically for it or otherwise try to reuse other global header files ?

> I wouldn't take these functions to their own .c file, and 
> if you do so, then "inline" no longer makes sense.  But 
> why did you do so?  It will add overhead to make them 
> out-of-line with no obvious benefit.

I was getting compilation errors. Perhaps you can give it a try.

> This seems inconsistent with the other functions - here 
> you pass the policydb as an argument rather than just 
> using the active policydb. If that were truly necessary, 
> I'd argue for passing the policydb to all of the 
> functions for consistency.  But I think in fact that we 
> can drop this !mls_enabled check altogether, given that 
> the context is fully initialized by context_init() and 
> thus the ebitmap_destroy() calls should be safe 
> regardless of whether or not MLS is enabled.

The policydb being passed to the modified functions is not necessarily the same as the active policy. Otherwise there was no point of making the modifications. To be more precise, consider the code-paths from security_load_policy() when you need to destroy the old policy and the old sidtab which are no longer active !
So, shall I remove completely the check ? That would make mls_context_destroy() execute even for standard policies...

> Same deal - don't take these to their own .c file without 
> justification.

As already explained, I moved those functions to a separate .c file because there were compilation error (gcc 4.4.1).

> Is that supposed to be "n" aka newline rather than just 
> "n"?

Yes, of course "n". It's weird because if you look at the attached file, everything is normal ! Something went wrong with the "cut-n-paste" from gedit to Mozilla, I shall probably file a bug report !...

That's it for the moment. I'll be back in a short while, after the patch has been amended.

Best regards,

Guido 


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2010-02-04 19:37 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-01-31 22:43 [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload Guido Trentalancia
2010-02-01 15:28 ` Stephen Smalley
2010-02-01 15:37   ` Stephen Smalley
2010-02-01 18:16 ` Stephen Smalley
2010-02-02 22:28   ` Guido Trentalancia
2010-02-03 15:48     ` Stephen Smalley
2010-02-01 16:36 Guido Trentalancia
2010-02-01 17:41 ` Stephen Smalley
2010-02-01 18:25 Guido Trentalancia
2010-02-01 19:15 ` Stephen Smalley
2010-02-01 19:59 Guido Trentalancia
2010-02-01 20:22 ` Stephen Smalley
2010-02-01 21:49 Guido Trentalancia
2010-02-01 22:09 ` Stephen Smalley
2010-02-01 21:56 Guido Trentalancia
2010-02-01 22:36 Guido Trentalancia
2010-02-04 19:12 ` Eric Paris
2010-02-02 14:22 Guido Trentalancia
2010-02-02 16:44 ` Stephen Smalley
2010-02-02 16:58   ` Guido Trentalancia
2010-02-02 17:34     ` Stephen Smalley
2010-02-02 17:49       ` Guido Trentalancia
2010-02-02 19:01         ` Stephen Smalley
2010-02-02 18:28   ` Guido Trentalancia
2010-02-02 19:03     ` Stephen Smalley
2010-02-02 19:11       ` Stephen Smalley
2010-02-02 16:29 Guido Trentalancia
2010-02-02 16:52 ` Christopher J. PeBenito
2010-02-03 15:40 Guido Trentalancia
2010-02-03 15:53 ` Stephen Smalley
2010-02-03 22:07 ` James Morris
2010-02-04 19:27 Guido Trentalancia
2010-02-04 19:37 ` Eric Paris

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.