All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] libsepol: Add support for multiple target OSes
@ 2009-09-15 16:15 pjnuzzi
  2009-09-15 16:37 ` [PATCH 2/3] checkpolicy: " pjnuzzi
  2009-09-16 13:58 ` [PATCH 1/3] libsepol: " Joshua Brindle
  0 siblings, 2 replies; 13+ messages in thread
From: pjnuzzi @ 2009-09-15 16:15 UTC (permalink / raw)
  To: selinux; +Cc: Stephen Smalley

Add support for multiple target OSes to libsepol where
the particular target OS is selected using a new -t target option to
checkpolicy.  The default target remains SELinux.  A new target and
support is introduced for Xen.  The target OS is identified in the
policy image by using different policy string identifiers in the header.
The policy string identifiers have been changed to variable length which
could break file(1) parsing if a string longer than 8 characters is
introduced into libsepol.  This modification will not affect the output
from file(1) but future changes to policy strings could.  For SELinux,
the string identifier remains "SE Linux".  For Xen, the string
identifier is "XenFlask".  The latent support for just "Flask" in the
policy reading code that was introduced for FMAC is dropped; a separate
identifier for Solaris (e.g. "SolFlask") will be introduced later using
this new target mechanism if needed.  The same support can easily be
extended for other OSes.

Based on the selected target, the source and binary policies may be
parsed differently.  For SELinux vs. Xen, the current difference is the
interpretation of object context records.  New object context records
for object contexts for pirqs, iomem ranges, ioport ranges, and pci
devices are enabled if building for the Xen target.  The SELinux object
context records other than initial SIDs are disabled if building for the
Xen target.  checkpolicy will generate an error if an attempt is made to
build a policy that has invalid object context records for the selected
target, and libsepol will likewise reject a binary policy if its object
context records are invalid for the target identified by its string
identifier.

No changes are required to the SELinux kernel code to support this
change; the SELinux kernel will continue to accept only policies with
the "SE Linux" identifier.  A patch for the Xen Flask module will be
submitted after this patch to enable it to accept policies built with
either string identifier (for compatibility with existing policies),
where the new object context record support will only be enabled if the
policy was built for the Xen target.

Support for selecting the target platform for libsemanage will be added
later. 

Signed-off-by: Paul Nuzzi <pjnuzzi@tycho.ncsc.mil>

---
 libsepol/include/sepol/policydb/policydb.h |   28 +++-
 libsepol/src/expand.c                      |   85 +++++++++++-
 libsepol/src/policydb.c                    |  197
++++++++++++++++++++++++-----
 libsepol/src/policydb_internal.h           |    1
 libsepol/src/write.c                       |   90 ++++++++++++-
 5 files changed, 359 insertions(+), 42 deletions(-)

diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h
index 0105cf4..2013238 100644
--- a/libsepol/include/sepol/policydb/policydb.h
+++ b/libsepol/include/sepol/policydb/policydb.h
@@ -276,6 +276,16 @@ typedef struct ocontext {
 			uint32_t addr[4]; /* network order */
 			uint32_t mask[4]; /* network order */
 		} node6;	/* IPv6 node information */
+		uint32_t device;
+		uint16_t pirq;
+		struct {
+			uint32_t low_iomem;
+			uint32_t high_iomem;
+		} iomem;
+		struct {
+			uint32_t low_ioport;
+			uint32_t high_ioport;
+		} ioport;
 	} u;
 	union {
 		uint32_t sclass;	/* security class for genfs */
@@ -313,6 +323,17 @@ typedef struct genfs {
 #define OCON_NODE6 6		/* IPv6 nodes */
 #define OCON_NUM   7
 
+/* object context array indices for Xen */
+#define OCON_ISID    0    /* initial SIDs */
+#define OCON_PIRQ    1    /* physical irqs */
+#define OCON_IOPORT  2    /* io ports */
+#define OCON_IOMEM   3    /* io memory */
+#define OCON_DEVICE  4    /* pci devices */
+#define OCON_DUMMY1  5    /* reserved */
+#define OCON_DUMMY2  6    /* reserved */
+#define OCON_NUM     7
+
+
 /* section: module information */
 
 /* scope_index_t holds all of the symbols that are in scope in a
@@ -400,6 +421,7 @@ typedef struct policydb {
 	uint32_t policy_type;
 	char *name;
 	char *version;
+	uint32_t target_type;
 
 	/* Set when the policydb is modified such that writing is unsupported */
 	int unsupported_format;
@@ -593,6 +615,7 @@ extern int avrule_read_list(policydb_t * p, avrule_t ** avrules,
 			    struct policy_file *fp);
 
 extern int policydb_write(struct policydb *p, struct policy_file *pf);
+extern int policydb_set_target_platform(policydb_t *p, int platform);
 
 #define PERM_SYMTAB_SIZE 32
 
@@ -651,9 +674,12 @@ extern int policydb_write(struct policydb *p, struct policy_file *pf);
 
 #define POLICYDB_MAGIC SELINUX_MAGIC
 #define POLICYDB_STRING "SE Linux"
-#define POLICYDB_ALT_STRING "Flask"
+#define POLICYDB_XEN_STRING "XenFlask"
 #define POLICYDB_MOD_MAGIC SELINUX_MOD_MAGIC
 #define POLICYDB_MOD_STRING "SE Linux Module"
+#define SEPOL_TARGET_SELINUX 0
+#define SEPOL_TARGET_XEN     1
+
 
 #endif				/* _POLICYDB_H_ */
 
diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
index e9cd986..38e2481 100644
--- a/libsepol/src/expand.c
+++ b/libsepol/src/expand.c
@@ -1819,9 +1819,9 @@ static int context_copy(context_struct_t * dst, context_struct_t * src,
 	return mls_context_cpy(dst, src);
 }
 
-static int ocontext_copy(expand_state_t * state)
+static int ocontext_copy_xen(expand_state_t *state)
 {
-	unsigned int i, j;
+	unsigned int i;
 	ocontext_t *c, *n, *l;
 
 	for (i = 0; i < OCON_NUM; i++) {
@@ -1833,11 +1833,63 @@ static int ocontext_copy(expand_state_t * state)
 				return -1;
 			}
 			memset(n, 0, sizeof(ocontext_t));
-			if (l) {
+			if (l)
 				l->next = n;
-			} else {
+			else
 				state->out->ocontexts[i] = n;
+			l = n;
+			if (context_copy(&n->context[0], &c->context[0],
+				state)) {
+				ERR(state->handle, "Out of memory!");
+				return -1;
+			}
+			switch (i) {
+			case OCON_ISID:
+				n->sid[0] = c->sid[0];
+				break;
+			case OCON_PIRQ:
+				n->u.pirq = c->u.pirq;
+				break;
+			case OCON_IOPORT:
+				n->u.ioport.low_ioport = c->u.ioport.low_ioport;
+				n->u.ioport.high_ioport =
+					c->u.ioport.high_ioport;
+				break;
+			case OCON_IOMEM:
+				n->u.iomem.low_iomem  = c->u.iomem.low_iomem;
+				n->u.iomem.high_iomem = c->u.iomem.high_iomem;
+				break;
+			case OCON_DEVICE:
+				n->u.device = c->u.device;
+				break;
+			default:
+				/* shouldn't get here */
+				ERR(state->handle, "Unknown ocontext");
+				return -1;
+			}
+		}
+	}
+	return 0;
+}
+
+static int ocontext_copy_selinux(expand_state_t *state)
+{
+	unsigned int i, j;
+	ocontext_t *c, *n, *l;
+
+	for (i = 0; i < OCON_NUM; i++) {
+		l = NULL;
+		for (c = state->base->ocontexts[i]; c; c = c->next) {
+			n = malloc(sizeof(ocontext_t));
+			if (!n) {
+				ERR(state->handle, "Out of memory!");
+				return -1;
 			}
+			memset(n, 0, sizeof(ocontext_t));
+			if (l)
+				l->next = n;
+			else
+				state->out->ocontexts[i] = n;
 			l = n;
 			if (context_copy(&n->context[0], &c->context[0], state)) {
 				ERR(state->handle, "Out of memory!");
@@ -1885,13 +1937,31 @@ static int ocontext_copy(expand_state_t * state)
 				break;
 			default:
 				/* shouldn't get here */
-				assert(0);
+				ERR(state->handle, "Unknown ocontext");
+				return -1;
 			}
 		}
 	}
 	return 0;
 }
 
+static int ocontext_copy(expand_state_t *state, uint32_t target)
+{
+	int rc = -1;
+	switch (target) {
+	case SEPOL_TARGET_SELINUX:
+		rc = ocontext_copy_selinux(state);
+		break;
+	case SEPOL_TARGET_XEN:
+		rc = ocontext_copy_xen(state);
+		break;
+	default:
+		ERR(state->handle, "Unknown target");
+		return -1;
+	}
+	return rc;
+}
+
 static int genfs_copy(expand_state_t * state)
 {
 	ocontext_t *c, *newc, *l;
@@ -2418,6 +2488,9 @@ int expand_module(sepol_handle_t * handle,
 	out->mls = base->mls;
 	out->handle_unknown = base->handle_unknown;
 
+	/* Copy target from base to out */
+	out->target_type = base->target_type;
+
 	/* Copy policy capabilities */
 	if (ebitmap_cpy(&out->policycaps, &base->policycaps)) {
 		ERR(handle, "Out of memory!");
@@ -2576,7 +2649,7 @@ int expand_module(sepol_handle_t * handle,
 	evaluate_conds(state.out);
 
 	/* copy ocontexts */
-	if (ocontext_copy(&state))
+	if (ocontext_copy(&state, out->target_type))
 		goto cleanup;
 
 	/* copy genfs */
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index 85ddefc..3d9bfe0 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -54,6 +54,9 @@
 #include "debug.h"
 #include "mls.h"
 
+#define POLICYDB_TARGET_SZ   ARRAY_SIZE(policydb_target_strings)
+char *policydb_target_strings[] = { POLICYDB_STRING, POLICYDB_XEN_STRING };
+
 /* These need to be updated if SYM_NUM or OCON_NUM changes */
 static struct policydb_compat_info policydb_compat[] = {
 	{
@@ -1079,9 +1082,13 @@ void policydb_destroy(policydb_t * p)
 			c = c->next;
 			context_destroy(&ctmp->context[0]);
 			context_destroy(&ctmp->context[1]);
-			if (i == OCON_ISID || i == OCON_FS || i == OCON_NETIF
-			    || i == OCON_FSUSE)
+			if (i == OCON_ISID)
+				free(ctmp->u.name);
+			if (p->target_type == SEPOL_TARGET_SELINUX &&
+				(i == OCON_FS || i == OCON_NETIF ||
+				i == OCON_FSUSE))
 				free(ctmp->u.name);
+
 			free(ctmp);
 		}
 	}
@@ -2102,7 +2109,88 @@ int role_allow_read(role_allow_t ** r, struct policy_file *fp)
 	return 0;
 }
 
-static int ocontext_read(struct policydb_compat_info *info,
+static int ocontext_read_xen(struct policydb_compat_info *info,
+	policydb_t *p, struct policy_file *fp)
+{
+	unsigned int i, j;
+	size_t nel;
+	ocontext_t *l, *c;
+	uint32_t buf[8];
+	int rc;
+
+	for (i = 0; i < info->ocon_num; i++) {
+		rc = next_entry(buf, fp, sizeof(uint32_t));
+		if (rc < 0)
+			return -1;
+		nel = le32_to_cpu(buf[0]);
+		l = NULL;
+		for (j = 0; j < nel; j++) {
+			c = calloc(1, sizeof(ocontext_t));
+			if (!c)
+				return -1;
+			if (l)
+				l->next = c;
+			else
+				p->ocontexts[i] = c;
+			l = c;
+			switch (i) {
+			case OCON_ISID:
+				rc = next_entry(buf, fp, sizeof(uint32_t));
+				if (rc < 0)
+					return -1;
+				c->sid[0] = le32_to_cpu(buf[0]);
+				if (context_read_and_validate
+				    (&c->context[0], p, fp))
+					return -1;
+				break;
+			case OCON_PIRQ:
+				rc = next_entry(buf, fp, sizeof(uint32_t));
+				if (rc < 0)
+					return -1;
+				c->u.pirq = le32_to_cpu(buf[0]);
+				if (context_read_and_validate
+				    (&c->context[0], p, fp))
+					return -1;
+				break;
+			case OCON_IOPORT:
+				rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
+				if (rc < 0)
+					return -1;
+				c->u.ioport.low_ioport = le32_to_cpu(buf[0]);
+				c->u.ioport.high_ioport = le32_to_cpu(buf[1]);
+				if (context_read_and_validate
+				    (&c->context[0], p, fp))
+					return -1;
+				break;
+			case OCON_IOMEM:
+				rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
+				if (rc < 0)
+					return -1;
+				c->u.iomem.low_iomem = le32_to_cpu(buf[0]);
+				c->u.iomem.high_iomem = le32_to_cpu(buf[1]);
+				if (context_read_and_validate
+				    (&c->context[0], p, fp))
+					return -1;
+				break;
+			case OCON_DEVICE:
+				rc = next_entry(buf, fp, sizeof(uint32_t));
+				if (rc < 0)
+					return -1;
+				c->u.device = le32_to_cpu(buf[0]);
+				if (context_read_and_validate
+				    (&c->context[0], p, fp))
+					return -1;
+				break;
+			default:
+				/* should never get here */
+				ERR(fp->handle, "Unknown Xen ocontext");
+				return -1;
+			}
+		}
+	}
+	return 0;
+}
+static int ocontext_read_selinux(struct policydb_compat_info *info,
 			 policydb_t * p, struct policy_file *fp)
 {
 	unsigned int i, j;
@@ -2197,23 +2285,25 @@ static int ocontext_read(struct policydb_compat_info *info,
 					return -1;
 				break;
 			case OCON_NODE6:{
-					int k;
-
-					rc = next_entry(buf, fp,
-							sizeof(uint32_t) * 8);
-					if (rc < 0)
-						return -1;
-					for (k = 0; k < 4; k++)
-						c->u.node6.addr[k] = buf[k]; /* network order */
-					for (k = 0; k < 4; k++)
-						c->u.node6.mask[k] = buf[k + 4]; /* network order */
-					if (context_read_and_validate
-					    (&c->context[0], p, fp))
-						return -1;
-					break;
+				int k;
+
+				rc = next_entry(buf, fp, sizeof(uint32_t) * 8);
+				if (rc < 0)
+					return -1;
+				for (k = 0; k < 4; k++)
+					 /* network order */
+					c->u.node6.addr[k] = buf[k];
+				for (k = 0; k < 4; k++)
+					/* network order */
+					c->u.node6.mask[k] = buf[k + 4];
+				if (context_read_and_validate
+				    (&c->context[0], p, fp))
+					return -1;
+				break;
 				}
 			default:{
-					assert(0);	/* should never get here */
+				ERR(fp->handle, "Unknown SELinux ocontext");
+				return -1;
 				}
 			}
 		}
@@ -2221,6 +2311,23 @@ static int ocontext_read(struct policydb_compat_info *info,
 	return 0;
 }
 
+static int ocontext_read(struct policydb_compat_info *info,
+	policydb_t *p, struct policy_file *fp)
+{
+	int rc = -1;
+	switch (p->target_type) {
+	case SEPOL_TARGET_SELINUX:
+		rc = ocontext_read_selinux(info, p, fp);
+		break;
+	case SEPOL_TARGET_XEN:
+		rc = ocontext_read_xen(info, p, fp);
+		break;
+	default:
+		ERR(fp->handle, "Unknown target");
+	}
+	return rc;
+}
+
 static int genfs_read(policydb_t * p, struct policy_file *fp)
 {
 	uint32_t buf[1];
@@ -3070,7 +3177,7 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose)
 	unsigned int i, j, r_policyvers;
 	uint32_t buf[5], config;
 	size_t len, nprim, nel;
-	char *policydb_str, *target_str = NULL, *alt_target_str = NULL;
+	char *policydb_str;
 	struct policydb_compat_info *info;
 	unsigned int policy_type, bufindex;
 	ebitmap_node_t *tnode;
@@ -3087,11 +3194,8 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose)
 
 	if (buf[0] == POLICYDB_MAGIC) {
 		policy_type = POLICY_KERN;
-		target_str = POLICYDB_STRING;
-		alt_target_str = POLICYDB_ALT_STRING;
 	} else if (buf[0] == POLICYDB_MOD_MAGIC) {
 		policy_type = POLICY_MOD;
-		target_str = POLICYDB_MOD_STRING;
 	} else {
 		ERR(fp->handle, "policydb magic number %#08x does not "
 		    "match expected magic number %#08x or %#08x",
@@ -3100,10 +3204,8 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose)
 	}
 
 	len = buf[1];
-	if (len != strlen(target_str) &&
-	    (!alt_target_str || len != strlen(alt_target_str))) {
-		ERR(fp->handle, "policydb string length %zu does not match "
-		    "expected length %zu", len, strlen(target_str));
+	if (len > 32) {
+		ERR(fp->handle, "policydb string length too long ");
 		return POLICYDB_ERROR;
 	}
 
@@ -3120,13 +3222,31 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose)
 		return POLICYDB_ERROR;
 	}
 	policydb_str[len] = 0;
-	if (strcmp(policydb_str, target_str) &&
-	    (!alt_target_str || strcmp(policydb_str, alt_target_str))) {
-		ERR(fp->handle, "policydb string %s does not match "
-		    "my string %s", policydb_str, target_str);
-		free(policydb_str);
-		return POLICYDB_ERROR;
+
+	if (policy_type == POLICY_KERN) {
+		for (i = 0; i < POLICYDB_TARGET_SZ; i++) {
+			if ((strcmp(policydb_str, policydb_target_strings[i])
+				== 0)) {
+				policydb_set_target_platform(p, i);
+				break;
+			}
+		}
+
+		if (i == POLICYDB_TARGET_SZ) {
+			ERR(fp->handle, "cannot find a valid target for policy "
+				"string %s", policydb_str);
+			free(policydb_str);
+			return POLICYDB_ERROR;
+		}
+	} else {
+		if (strcmp(policydb_str, POLICYDB_MOD_STRING)) {
+			ERR(fp->handle, "invalid string identifier %s",
+				policydb_str);
+			free(policydb_str);
+			return POLICYDB_ERROR;
+		}
 	}
+
 	/* Done with policydb_str. */
 	free(policydb_str);
 	policydb_str = NULL;
@@ -3391,3 +3511,16 @@ void policy_file_init(policy_file_t *pf)
 {
 	memset(pf, 0, sizeof(policy_file_t));
 }
+
+int policydb_set_target_platform(policydb_t *p, int platform)
+{
+	if (platform == SEPOL_TARGET_SELINUX)
+		p->target_type = SEPOL_TARGET_SELINUX;
+	else if (platform == SEPOL_TARGET_XEN)
+		p->target_type = SEPOL_TARGET_XEN;
+	else
+		return -1;
+
+	return 0;
+}
+
diff --git a/libsepol/src/policydb_internal.h b/libsepol/src/policydb_internal.h
index 1eb99e5..8a31506 100644
--- a/libsepol/src/policydb_internal.h
+++ b/libsepol/src/policydb_internal.h
@@ -6,4 +6,5 @@
 
 hidden_proto(sepol_policydb_create)
     hidden_proto(sepol_policydb_free)
+extern char *policydb_target_strings[];
 #endif
diff --git a/libsepol/src/write.c b/libsepol/src/write.c
index 66b35ec..a557c2e 100644
--- a/libsepol/src/write.c
+++ b/libsepol/src/write.c
@@ -1084,10 +1084,79 @@ static int (*write_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum,
 common_write, class_write, role_write, type_write, user_write,
 	    cond_write_bool, sens_write, cat_write,};
 
-static int ocontext_write(struct policydb_compat_info *info, policydb_t * p,
+static int ocontext_write_xen(struct policydb_compat_info *info, policydb_t *p,
 			  struct policy_file *fp)
 {
 	unsigned int i, j;
+	size_t nel, items;
+	uint32_t buf[32];
+	ocontext_t *c;
+	for (i = 0; i < info->ocon_num; i++) {
+		nel = 0;
+		for (c = p->ocontexts[i]; c; c = c->next)
+			nel++;
+		buf[0] = cpu_to_le32(nel);
+		items = put_entry(buf, sizeof(uint32_t), 1, fp);
+		if (items != 1)
+			return POLICYDB_ERROR;
+		for (c = p->ocontexts[i]; c; c = c->next) {
+			switch (i) {
+			case OCON_ISID:
+				buf[0] = cpu_to_le32(c->sid[0]);
+				items = put_entry(buf, sizeof(uint32_t), 1, fp);
+				if (items != 1)
+					return POLICYDB_ERROR;
+				if (context_write(p, &c->context[0], fp))
+					return POLICYDB_ERROR;
+				break;
+			case OCON_PIRQ:
+				buf[0] = cpu_to_le32(c->u.pirq);
+				items = put_entry(buf, sizeof(uint32_t), 1, fp);
+				if (items != 1)
+					return POLICYDB_ERROR;
+				if (context_write(p, &c->context[0], fp))
+					return POLICYDB_ERROR;
+				break;
+			case OCON_IOPORT:
+				buf[0] = c->u.ioport.low_ioport;
+				buf[1] = c->u.ioport.high_ioport;
+				for (j = 0; j < 2; j++)
+					buf[j] = cpu_to_le32(buf[j]);
+				items = put_entry(buf, sizeof(uint32_t), 2, fp);
+				if (items != 2)
+					return POLICYDB_ERROR;
+				if (context_write(p, &c->context[0], fp))
+					return POLICYDB_ERROR;
+				break;
+			case OCON_IOMEM:
+				buf[0] = c->u.iomem.low_iomem;
+				buf[1] = c->u.iomem.high_iomem;
+				for (j = 0; j < 2; j++)
+					buf[j] = cpu_to_le32(buf[j]);
+				items = put_entry(buf, sizeof(uint32_t), 2, fp);
+				if (items != 2)
+					return POLICYDB_ERROR;
+				if (context_write(p, &c->context[0], fp))
+					return POLICYDB_ERROR;
+				break;
+			case OCON_DEVICE:
+				buf[0] = cpu_to_le32(c->u.device);
+				items = put_entry(buf, sizeof(uint32_t), 1, fp);
+				if (items != 1)
+					return POLICYDB_ERROR;
+				if (context_write(p, &c->context[0], fp))
+					return POLICYDB_ERROR;
+				break;
+			}
+		}
+	}
+	return POLICYDB_SUCCESS;
+}
+
+static int ocontext_write_selinux(struct policydb_compat_info *info,
+	policydb_t *p, struct policy_file *fp)
+{
+	unsigned int i, j;
 	size_t nel, items, len;
 	uint32_t buf[32];
 	ocontext_t *c;
@@ -1176,6 +1245,21 @@ static int ocontext_write(struct policydb_compat_info *info, policydb_t * p,
 	return POLICYDB_SUCCESS;
 }
 
+static int ocontext_write(struct policydb_compat_info *info, policydb_t * p,
+	struct policy_file *fp)
+{
+	int rc = POLICYDB_ERROR;
+	switch (p->target_type) {
+	case SEPOL_TARGET_SELINUX:
+		rc = ocontext_write_selinux(info, p, fp);
+		break;
+	case SEPOL_TARGET_XEN:
+		rc = ocontext_write_xen(info, p, fp);
+		break;
+	}
+	return rc;
+}
+
 static int genfs_write(policydb_t * p, struct policy_file *fp)
 {
 	genfs_t *genfs;
@@ -1610,8 +1694,8 @@ int policydb_write(policydb_t * p, struct policy_file *fp)
 	items = 0;
 	if (p->policy_type == POLICY_KERN) {
 		buf[items++] = cpu_to_le32(POLICYDB_MAGIC);
-		len = strlen(POLICYDB_STRING);
-		policydb_str = POLICYDB_STRING;
+		len = strlen(policydb_target_strings[p->target_type]);
+		policydb_str = policydb_target_strings[p->target_type];
 	} else {
 		buf[items++] = cpu_to_le32(POLICYDB_MOD_MAGIC);
 		len = strlen(POLICYDB_MOD_STRING);



--
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 related	[flat|nested] 13+ messages in thread

* [PATCH 2/3] checkpolicy: Add support for multiple target OSes
  2009-09-15 16:15 [PATCH 1/3] libsepol: Add support for multiple target OSes pjnuzzi
@ 2009-09-15 16:37 ` pjnuzzi
  2009-09-15 16:40   ` [PATCH 3/3] sepolgen: " pjnuzzi
  2009-09-29 14:06   ` [PATCH 2/3] checkpolicy: " Paul Nuzzi
  2009-09-16 13:58 ` [PATCH 1/3] libsepol: " Joshua Brindle
  1 sibling, 2 replies; 13+ messages in thread
From: pjnuzzi @ 2009-09-15 16:37 UTC (permalink / raw)
  To: selinux; +Cc: Stephen Smalley

Add support for multiple target OSes by adding the -t target option to
checkpolicy.  Implemented the new Xen ocontext identifiers pirqcon,
pcidevicecon, iomemcon and ioportcon.  

Signed-off-by: Paul Nuzzi <pjnuzzi@tycho.ncsc.mil>

---
checkpolicy/checkpolicy.c   |   20 ++-
checkpolicy/policy_define.c |  262
++++++++++++++++++++++++++++++++++++++++++++
checkpolicy/policy_define.h |    4
checkpolicy/policy_parse.y  |   29 ++++
checkpolicy/policy_scan.l   |   10 +
5 files changed, 320 insertions(+), 5 deletions(-)

diff --git a/checkpolicy/checkpolicy.c b/checkpolicy/checkpolicy.c
index d7772d5..76d8ed3 100644
--- a/checkpolicy/checkpolicy.c
+++ b/checkpolicy/checkpolicy.c
@@ -100,7 +100,9 @@ unsigned int policyvers = POLICYDB_VERSION_MAX;
 void usage(char *progname)
 {
 	printf
-	    ("usage:  %s [-b] [-d] [-U handle_unknown (allow,deny,reject) [-M] [-c policyvers (%d-%d)] [-o output_file] [input_file]\n",
+	    ("usage:  %s [-b] [-d] [-U handle_unknown (allow,deny,reject) [-M]"
+	     "[-c policyvers (%d-%d)] [-o output_file] [-t platform]"
+	     "[input_file]\n",
 	     progname, POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
 	exit(1);
 }
@@ -381,7 +383,7 @@ int main(int argc, char **argv)
 	unsigned int protocol, port;
 	unsigned int binary = 0, debug = 0;
 	struct val_to_name v;
-	int ret, ch, fd;
+	int ret, ch, fd, target = SEPOL_TARGET_SELINUX;
 	unsigned int nel, uret;
 	struct stat sb;
 	void *map;
@@ -391,11 +393,22 @@ int main(int argc, char **argv)
 	int show_version = 0;
 	struct policy_file pf;
 
-	while ((ch = getopt(argc, argv, "o:dbU:MVc:")) != EOF) {
+	while ((ch = getopt(argc, argv, "o:t:dbU:MVc:")) != EOF) {
 		switch (ch) {
 		case 'o':
 			outfile = optarg;
 			break;
+		case 't':
+			if (!strcasecmp(optarg, "Xen"))
+				target = SEPOL_TARGET_XEN;
+			else if (!strcasecmp(optarg, "SELinux"))
+				target = SEPOL_TARGET_SELINUX;
+			else{
+				fprintf(stderr, "%s:  Unknown target platform:"
+					"%s\n", argv[0], optarg);
+				exit(1);
+			}
+			break;
 		case 'b':
 			binary = 1;
 			file = binfile;
@@ -528,6 +541,7 @@ int main(int argc, char **argv)
 			exit(1);
 		/* We build this as a base policy first since that is all the parser understands */
 		parse_policy.policy_type = POLICY_BASE;
+		policydb_set_target_platform(&parse_policy, target);
 
 		/* Let sepol know if we are dealing with MLS support */
 		parse_policy.mls = mlspol;
diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c
index 17b84ce..1e19bda 100644
--- a/checkpolicy/policy_define.c
+++ b/checkpolicy/policy_define.c
@@ -3372,12 +3372,254 @@ int define_fs_context(unsigned int major, unsigned int minor)
 	return 0;
 }
 
+int define_pirq_context(unsigned int pirq)
+{
+	ocontext_t *newc, *c, *l, *head;
+	char *id;
+
+	if (policydbp->target_type != SEPOL_TARGET_XEN) {
+		yyerror("pirqcon only supported for target Xen");
+		return -1;
+	}
+
+	if (pass == 1) {
+		id = (char *) queue_remove(id_queue);
+		free(id);
+		parse_security_context(NULL);
+		return 0;
+	}
+
+	newc = malloc(sizeof(ocontext_t));
+	if (!newc) {
+		yyerror("out of memory");
+		return -1;
+	}
+	memset(newc, 0, sizeof(ocontext_t));
+
+	newc->u.pirq = pirq;
+
+	if (parse_security_context(&newc->context[0])) {
+		free(newc);
+		return -1;
+	}
+
+	head = policydbp->ocontexts[OCON_PIRQ];
+	for (l = NULL, c = head; c; l = c, c = c->next) {
+		unsigned int pirq2;
+
+		pirq2 = c->u.pirq;
+		if (pirq == pirq2) {
+			yyerror2("duplicate pirqcon entry for %d ", pirq);
+			goto bad;
+		}
+	}
+
+	if (l)
+		l->next = newc;
+	else
+		policydbp->ocontexts[OCON_PIRQ] = newc;
+
+	return 0;
+
+bad:
+	free(newc);
+	return -1;
+}
+
+int define_iomem_context(unsigned long low, unsigned long high)
+{
+	ocontext_t *newc, *c, *l, *head;
+	char *id;
+
+	if (policydbp->target_type != SEPOL_TARGET_XEN) {
+		yyerror("iomemcon only supported for target Xen");
+		return -1;
+	}
+
+	if (pass == 1) {
+		id = (char *)queue_remove(id_queue);
+		free(id);
+		parse_security_context(NULL);
+		return 0;
+	}
+
+	newc = malloc(sizeof(ocontext_t));
+	if (!newc) {
+		yyerror("out of memory");
+		return -1;
+	}
+	memset(newc, 0, sizeof(ocontext_t));
+
+	newc->u.iomem.low_iomem  = low;
+	newc->u.iomem.high_iomem = high;
+
+	if (low > high) {
+		yyerror2("low memory 0x%x exceeds high memory 0x%x", low, high);
+		free(newc);
+		return -1;
+	}
+
+	if (parse_security_context(&newc->context[0])) {
+		free(newc);
+		return -1;
+	}
+
+	head = policydbp->ocontexts[OCON_IOMEM];
+	for (l = NULL, c = head; c; l = c, c = c->next) {
+		unsigned int low2, high2;
+
+		low2 = c->u.iomem.low_iomem;
+		high2 = c->u.iomem.high_iomem;
+		if (low <= high2 && low2 <= high) {
+			yyerror2("iomemcon entry for 0x%x-0x%x overlaps with "
+				"earlier entry 0x%x-0x%x", low, high,
+				low2, high2);
+			goto bad;
+		}
+	}
+
+	if (l)
+		l->next = newc;
+	else
+		policydbp->ocontexts[OCON_IOMEM] = newc;
+
+	return 0;
+
+bad:
+	free(newc);
+	return -1;
+}
+
+int define_ioport_context(unsigned long low, unsigned long high)
+{
+	ocontext_t *newc, *c, *l, *head;
+	char *id;
+
+	if (policydbp->target_type != SEPOL_TARGET_XEN) {
+		yyerror("ioportcon only supported for target Xen");
+		return -1;
+	}
+
+	if (pass == 1) {
+		id = (char *)queue_remove(id_queue);
+		free(id);
+		parse_security_context(NULL);
+		return 0;
+	}
+
+	newc = malloc(sizeof(ocontext_t));
+	if (!newc) {
+		yyerror("out of memory");
+		return -1;
+	}
+	memset(newc, 0, sizeof(ocontext_t));
+
+	newc->u.ioport.low_ioport  = low;
+	newc->u.ioport.high_ioport = high;
+
+	if (low > high) {
+		yyerror2("low ioport 0x%x exceeds high ioport 0x%x", low, high);
+		free(newc);
+		return -1;
+	}
+
+	if (parse_security_context(&newc->context[0])) {
+		free(newc);
+		return -1;
+	}
+
+	head = policydbp->ocontexts[OCON_IOPORT];
+	for (l = NULL, c = head; c; l = c, c = c->next) {
+		unsigned int low2, high2;
+
+		low2 = c->u.ioport.low_ioport;
+		high2 = c->u.ioport.high_ioport;
+		if (low <= high2 && low2 <= high) {
+			yyerror2("ioportcon entry for 0x%x-0x%x overlaps with"
+				"earlier entry 0x%x-0x%x", low, high,
+				low2, high2);
+			goto bad;
+		}
+	}
+
+	if (l)
+		l->next = newc;
+	else
+		policydbp->ocontexts[OCON_IOPORT] = newc;
+
+	return 0;
+
+bad:
+	free(newc);
+	return -1;
+}
+
+int define_pcidevice_context(unsigned long device)
+{
+	ocontext_t *newc, *c, *l, *head;
+	char *id;
+
+	if (policydbp->target_type != SEPOL_TARGET_XEN) {
+		yyerror("pcidevicecon only supported for target Xen");
+		return -1;
+	}
+
+	if (pass == 1) {
+		id = (char *) queue_remove(id_queue);
+		free(id);
+		parse_security_context(NULL);
+		return 0;
+	}
+
+	newc = malloc(sizeof(ocontext_t));
+	if (!newc) {
+		yyerror("out of memory");
+		return -1;
+	}
+	memset(newc, 0, sizeof(ocontext_t));
+
+	newc->u.device = device;
+
+	if (parse_security_context(&newc->context[0])) {
+		free(newc);
+		return -1;
+	}
+
+	head = policydbp->ocontexts[OCON_DEVICE];
+	for (l = NULL, c = head; c; l = c, c = c->next) {
+		unsigned int device2;
+
+		device2 = c->u.device;
+		if (device == device2) {
+			yyerror2("duplicate pcidevicecon entry for 0x%x ",
+				 device);
+			goto bad;
+		}
+	}
+
+	if (l)
+		l->next = newc;
+	else
+		policydbp->ocontexts[OCON_DEVICE] = newc;
+
+	return 0;
+
+bad:
+	free(newc);
+	return -1;
+}
+
 int define_port_context(unsigned int low, unsigned int high)
 {
 	ocontext_t *newc, *c, *l, *head;
 	unsigned int protocol;
 	char *id;
 
+	if (policydbp->target_type != SEPOL_TARGET_SELINUX) {
+		yyerror("portcon only supported for target SELinux");
+		return -1;
+	}
+
 	if (pass == 1) {
 		id = (char *)queue_remove(id_queue);
 		free(id);
@@ -3460,6 +3702,11 @@ int define_netif_context(void)
 {
 	ocontext_t *newc, *c, *head;
 
+	if (policydbp->target_type != SEPOL_TARGET_SELINUX) {
+		yyerror("netifcon only supported for target SELinux");
+		return -1;
+	}
+
 	if (pass == 1) {
 		free(queue_remove(id_queue));
 		parse_security_context(NULL);
@@ -3516,6 +3763,11 @@ int define_ipv4_node_context()
 	struct in_addr addr, mask;
 	ocontext_t *newc, *c, *l, *head;
 
+	if (policydbp->target_type != SEPOL_TARGET_SELINUX) {
+		yyerror("nodecon only supported for target SELinux");
+		return -1;
+	}
+
 	if (pass == 1) {
 		free(queue_remove(id_queue));
 		free(queue_remove(id_queue));
@@ -3597,6 +3849,11 @@ int define_ipv6_node_context(void)
 	struct in6_addr addr, mask;
 	ocontext_t *newc, *c, *l, *head;
 
+	if (policydbp->target_type != SEPOL_TARGET_SELINUX) {
+		yyerror("nodecon only supported by target SELinux");
+		return -1;
+	}
+
 	if (pass == 1) {
 		free(queue_remove(id_queue));
 		free(queue_remove(id_queue));
@@ -3677,6 +3934,11 @@ int define_fs_use(int behavior)
 {
 	ocontext_t *newc, *c, *head;
 
+	if (policydbp->target_type != SEPOL_TARGET_SELINUX) {
+		yyerror("unsupported target");
+		return -1;
+	}
+
 	if (pass == 1) {
 		free(queue_remove(id_queue));
 		parse_security_context(NULL);
diff --git a/checkpolicy/policy_define.h b/checkpolicy/policy_define.h
index b5a972e..5ac6667 100644
--- a/checkpolicy/policy_define.h
+++ b/checkpolicy/policy_define.h
@@ -39,6 +39,10 @@ int define_netif_context(void);
 int define_permissive(void);
 int define_polcap(void);
 int define_port_context(unsigned int low, unsigned int high);
+int define_pirq_context(unsigned int pirq);
+int define_iomem_context(unsigned long low, unsigned long high);
+int define_ioport_context(unsigned long low, unsigned long high);
+int define_pcidevice_context(unsigned long device);
 int define_range_trans(int class_specified);
 int define_role_allow(void);
 int define_role_trans(void);
diff --git a/checkpolicy/policy_parse.y b/checkpolicy/policy_parse.y
index 5ca7101..8d1bc37 100644
--- a/checkpolicy/policy_parse.y
+++ b/checkpolicy/policy_parse.y
@@ -123,6 +123,7 @@ typedef int (* require_func_t)();
 %token TARGET
 %token SAMEUSER
 %token FSCON PORTCON NETIFCON NODECON 
+%token PIRQCON IOMEMCON IOPORTCON PCIDEVICECON
 %token FSUSEXATTR FSUSETASK FSUSETRANS
 %token GENFSCON
 %token U1 U2 U3 R1 R2 R3 T1 T2 T3 L1 L2 H1 H2
@@ -154,7 +155,7 @@ base_policy             : { if (define_policy(pass, 0) == -1) return -1; }
 			  opt_mls te_rbac users opt_constraints 
                          { if (pass == 1) { if (policydb_index_bools(policydbp)) return -1;}
 			   else if (pass == 2) { if (policydb_index_others(NULL, policydbp, 0)) return -1;}}
-			  initial_sid_contexts opt_fs_contexts opt_fs_uses opt_genfs_contexts net_contexts 
+			  initial_sid_contexts opt_fs_contexts opt_fs_uses opt_genfs_contexts net_contexts opt_dev_contexts
 			;
 classes			: class_def 
 			| classes class_def
@@ -562,6 +563,32 @@ initial_sid_contexts	: initial_sid_context_def
 initial_sid_context_def	: SID identifier security_context_def
 			{if (define_initial_sid_context()) return -1;}
 			;
+opt_dev_contexts	: dev_contexts |
+			;
+dev_contexts		: dev_context_def
+			| dev_contexts dev_context_def
+			;
+dev_context_def		: pirq_context_def |
+			  iomem_context_def |
+			  ioport_context_def |
+			  pci_context_def
+			;
+pirq_context_def 	: PIRQCON number security_context_def
+		        {if (define_pirq_context($2)) return -1;}
+		        ;
+iomem_context_def	: IOMEMCON number security_context_def
+		        {if (define_iomem_context($2,$2)) return -1;}
+		        | IOMEMCON number '-' number security_context_def
+		        {if (define_iomem_context($2,$4)) return -1;}
+		        ;
+ioport_context_def	: IOPORTCON number security_context_def
+			{if (define_ioport_context($2,$2)) return -1;}
+			| IOPORTCON number '-' number security_context_def
+			{if (define_ioport_context($2,$4)) return -1;}
+			;
+pci_context_def  	: PCIDEVICECON number security_context_def
+		        {if (define_pcidevice_context($2)) return -1;}
+		        ;
 opt_fs_contexts         : fs_contexts 
                         |
                         ;
diff --git a/checkpolicy/policy_scan.l b/checkpolicy/policy_scan.l
index b55c659..48128a8 100644
--- a/checkpolicy/policy_scan.l
+++ b/checkpolicy/policy_scan.l
@@ -169,6 +169,14 @@ netifcon |
 NETIFCON			{ return(NETIFCON);}
 nodecon |                     
 NODECON				{ return(NODECON);}
+pirqcon |
+PIRQCON  		        { return(PIRQCON);}
+iomemcon |
+IOMEMCON            		{ return(IOMEMCON);}
+ioportcon |
+IOPORTCON           		{ return(IOPORTCON);}
+pcidevicecon |
+PCIDEVICECON           		{ return(PCIDEVICECON);}
 fs_use_xattr |
 FS_USE_XATTR			{ return(FSUSEXATTR);}
 fs_use_task |
@@ -209,7 +217,7 @@ permissive |
 PERMISSIVE			{ return(PERMISSIVE); }
 "/"({alnum}|[_\.\-/])*	        { return(PATH); }
 {letter}({alnum}|[_\-])*([\.]?({alnum}|[_\-]))*	{ return(IDENTIFIER); }
-{digit}+                        { return(NUMBER); }
+{digit}+|0x{hexval}+            { return(NUMBER); }
 {digit}{1,3}(\.{digit}{1,3}){3}    { return(IPV4_ADDR); }
 {hexval}{0,4}":"{hexval}{0,4}":"({hexval}|[:.])*  { return(IPV6_ADDR); }
 {digit}+(\.({alnum}|[_.])*)?    { return(VERSION_IDENTIFIER); }


--
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 related	[flat|nested] 13+ messages in thread

* [PATCH 3/3] sepolgen: Add support for multiple target OSes
  2009-09-15 16:37 ` [PATCH 2/3] checkpolicy: " pjnuzzi
@ 2009-09-15 16:40   ` pjnuzzi
  2009-09-29 14:06   ` [PATCH 2/3] checkpolicy: " Paul Nuzzi
  1 sibling, 0 replies; 13+ messages in thread
From: pjnuzzi @ 2009-09-15 16:40 UTC (permalink / raw)
  To: selinux; +Cc: Stephen Smalley

Add support to sepolgen for new Xen ocontext identifiers.

Signed-off-by: Paul Nuzzi <pjnuzzi@tycho.ncsc.mil>

---
sepolgen/src/sepolgen/refparser.py |   54
+++++++++++++++++++++++++++++++++++++
sepolgen/src/sepolgen/refpolicy.py |   35 +++++++++++++++++++++++
2 files changed, 89 insertions(+)

diff --git a/sepolgen/src/sepolgen/refparser.py b/sepolgen/src/sepolgen/refparser.py
index 65d1d90..23beb39 100644
--- a/sepolgen/src/sepolgen/refparser.py
+++ b/sepolgen/src/sepolgen/refparser.py
@@ -83,6 +83,10 @@ tokens = (
     'PORTCON',
     'NODECON',
     'NETIFCON',
+    'PIRQCON',
+    'IOMEMCON',
+    'IOPORTCON',
+    'PCIDEVICECON',
     #   object classes
     'CLASS',
     #   types and attributes
@@ -140,6 +144,10 @@ reserved = {
     'portcon' : 'PORTCON',
     'nodecon' : 'NODECON',
     'netifcon' : 'NETIFCON',
+    'pirqcon' : 'PIRQCON',
+    'iomemcon' : 'IOMEMCON',
+    'ioportcon' : 'IOPORTCON',
+    'pcidevicecon' : 'PCIDEVICECON',
     # object classes
     'class' : 'CLASS',
     # types and attributes
@@ -495,6 +503,10 @@ def p_policy_stmt(p):
                    | portcon
                    | nodecon
                    | netifcon
+                   | pirqcon
+                   | iomemcon
+                   | ioportcon
+                   | pcidevicecon
     '''
     if p[1]:
         p[0] = [p[1]]
@@ -631,6 +643,48 @@ def p_netifcon(p):
 
     p[0] = n
 
+def p_pirqcon(p):
+    'pirqcon : PIRQCON NUMBER context'
+    c = refpolicy.PirqCon()
+    c.pirq_number = p[2]
+    c.context = p[3]
+
+    p[0] = c
+
+def p_iomemcon(p):
+    '''iomemcon : IOMEMCON NUMBER context
+                | IOMEMCON NUMBER MINUS NUMBER context'''
+    c = refpolicy.IomemCon()
+    if len(p) == 4:
+        c.device_mem = p[2]
+        c.context = p[3]
+    else:
+        c.device_mem = p[2] + "-" + p[3]
+        c.context = p[4]
+
+    p[0] = c
+
+def p_ioportcon(p):
+    '''ioportcon : IOPORTCON NUMBER context
+                | IOPORTCON NUMBER MINUS NUMBER context'''
+    c = refpolicy.IoportCon()
+    if len(p) == 4:
+        c.ioport = p[2]
+        c.context = p[3]
+    else:
+        c.ioport = p[2] + "-" + p[3]
+        c.context = p[4]
+
+    p[0] = c
+
+def p_pcidevicecon(p):
+    'pcidevicecon : PCIDEVICECON NUMBER context'
+    c = refpolicy.PciDeviceCon()
+    c.device = p[2]
+    c.context = p[3]
+
+    p[0] = c
+
 def p_mls_range_def(p):
     '''mls_range_def : mls_level_def MINUS mls_level_def
                      | mls_level_def
diff --git a/sepolgen/src/sepolgen/refpolicy.py b/sepolgen/src/sepolgen/refpolicy.py
index 724b870..b138e3d 100644
--- a/sepolgen/src/sepolgen/refpolicy.py
+++ b/sepolgen/src/sepolgen/refpolicy.py
@@ -618,6 +618,41 @@ class NetifCon(Leaf):
     def to_string(self):
         return "netifcon %s %s %s" % (self.interface, str(self.interface_context),
                                    str(self.packet_context))
+class PirqCon(Leaf):
+    def __init__(self, parent=None):
+        Leaf.__init__(self, parent)
+        self.pirq_number = ""
+        self.context = None
+
+    def to_string(self):
+        return "pirqcon %s %s" % (self.pirq_number, str(self.context))
+
+class IomemCon(Leaf):
+    def __init__(self, parent=None):
+        Leaf.__init__(self, parent)
+        self.device_mem = ""
+        self.context = None
+
+    def to_string(self):
+        return "iomemcon %s %s" % (self.device_mem, str(self.context))
+
+class IoportCon(Leaf):
+    def __init__(self, parent=None):
+        Leaf.__init__(self, parent)
+        self.ioport = ""
+        self.context = None
+
+    def to_string(self):
+        return "ioportcon %s %s" % (self.ioport, str(self.context))
+
+class PciDeviceCon(Leaf):
+    def __init__(self, parent=None):
+        Leaf.__init__(self, parent)
+        self.device = ""
+        self.context = None
+
+    def to_string(self):
+        return "pcidevicecon %s %s" % (self.device, str(self.context))
 
 # Reference policy specific types
 


--
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 related	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/3] libsepol: Add support for multiple target OSes
  2009-09-15 16:15 [PATCH 1/3] libsepol: Add support for multiple target OSes pjnuzzi
  2009-09-15 16:37 ` [PATCH 2/3] checkpolicy: " pjnuzzi
@ 2009-09-16 13:58 ` Joshua Brindle
  2009-09-16 17:44   ` Paul Nuzzi
  2009-09-29 14:03   ` Paul Nuzzi
  1 sibling, 2 replies; 13+ messages in thread
From: Joshua Brindle @ 2009-09-16 13:58 UTC (permalink / raw)
  To: pjnuzzi; +Cc: selinux, Stephen Smalley



pjnuzzi wrote:

<snip>
> Signed-off-by: Paul Nuzzi<pjnuzzi@tycho.ncsc.mil>
>
> ---
>   libsepol/include/sepol/policydb/policydb.h |   28 +++-
>   libsepol/src/expand.c                      |   85 +++++++++++-
>   libsepol/src/policydb.c                    |  197
> ++++++++++++++++++++++++-----
>   libsepol/src/policydb_internal.h           |    1
>   libsepol/src/write.c                       |   90 ++++++++++++-
>   5 files changed, 359 insertions(+), 42 deletions(-)
>
> diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h
> index 0105cf4..2013238 100644
> --- a/libsepol/include/sepol/policydb/policydb.h
> +++ b/libsepol/include/sepol/policydb/policydb.h
> @@ -276,6 +276,16 @@ typedef struct ocontext {
>   			uint32_t addr[4]; /* network order */
>   			uint32_t mask[4]; /* network order */
>   		} node6;	/* IPv6 node information */
> +		uint32_t device;
> +		uint16_t pirq;
> +		struct {
> +			uint32_t low_iomem;
> +			uint32_t high_iomem;
> +		} iomem;
> +		struct {
> +			uint32_t low_ioport;
> +			uint32_t high_ioport;
> +		} ioport;
>    

I'd rather have separate ocontext structs for each system. That way it 
is very easy to understand which ones apply to which system and you 
don't get a crazy out of context ocontext struct.

>   	} u;
>   	union {
>   		uint32_t sclass;	/* security class for genfs */
> @@ -313,6 +323,17 @@ typedef struct genfs {
>   #define OCON_NODE6 6		/* IPv6 nodes */
>   #define OCON_NUM   7
>
> +/* object context array indices for Xen */
> +#define OCON_ISID    0    /* initial SIDs */
> +#define OCON_PIRQ    1    /* physical irqs */
> +#define OCON_IOPORT  2    /* io ports */
> +#define OCON_IOMEM   3    /* io memory */
> +#define OCON_DEVICE  4    /* pci devices */
> +#define OCON_DUMMY1  5    /* reserved */
> +#define OCON_DUMMY2  6    /* reserved */
> +#define OCON_NUM     7
> +
> +
>    

Should these be namespaced? What if <random other system> has io port 
objects? You'd have to align them with each other and you have a mess of 
keeping the numbers the same (you already do this with OCON_ISID)

Also we are relying on having the same number of OCON's which isn't good 
I don't think. As much as I hate the policydb_compat_info (read: alot) 
why aren't we using that to say how many ocons a xen policy really has?

>   /* section: module information */
>
>   /* scope_index_t holds all of the symbols that are in scope in a
> @@ -400,6 +421,7 @@ typedef struct policydb {
>   	uint32_t policy_type;
>   	char *name;
>   	char *version;
> +	uint32_t target_type;
>
>    

Really bad variable name. how about target_platform or something?

>   	/* Set when the policydb is modified such that writing is unsupported */
>   	int unsupported_format;
> @@ -593,6 +615,7 @@ extern int avrule_read_list(policydb_t * p, avrule_t ** avrules,
>   			    struct policy_file *fp);
>
>   extern int policydb_write(struct policydb *p, struct policy_file *pf);
> +extern int policydb_set_target_platform(policydb_t *p, int platform);
>
>   #define PERM_SYMTAB_SIZE 32
>
> @@ -651,9 +674,12 @@ extern int policydb_write(struct policydb *p, struct policy_file *pf);
>
>   #define POLICYDB_MAGIC SELINUX_MAGIC
>   #define POLICYDB_STRING "SE Linux"
> -#define POLICYDB_ALT_STRING "Flask"
> +#define POLICYDB_XEN_STRING "XenFlask"
>   #define POLICYDB_MOD_MAGIC SELINUX_MOD_MAGIC
>   #define POLICYDB_MOD_STRING "SE Linux Module"
> +#define SEPOL_TARGET_SELINUX 0
> +#define SEPOL_TARGET_XEN     1
> +
>
>   #endif				/* _POLICYDB_H_ */
>
> diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
> index e9cd986..38e2481 100644
> --- a/libsepol/src/expand.c
> +++ b/libsepol/src/expand.c
> @@ -1819,9 +1819,9 @@ static int context_copy(context_struct_t * dst, context_struct_t * src,
>   	return mls_context_cpy(dst, src);
>   }
>
> -static int ocontext_copy(expand_state_t * state)
> +static int ocontext_copy_xen(expand_state_t *state)
>   {
> -	unsigned int i, j;
> +	unsigned int i;
>   	ocontext_t *c, *n, *l;
>
>   	for (i = 0; i<  OCON_NUM; i++) {
> @@ -1833,11 +1833,63 @@ static int ocontext_copy(expand_state_t * state)
>   				return -1;
>   			}
>   			memset(n, 0, sizeof(ocontext_t));
> -			if (l) {
> +			if (l)
>   				l->next = n;
> -			} else {
> +			else
>    

whitespace changes.

>   				state->out->ocontexts[i] = n;
> +			l = n;
> +			if (context_copy(&n->context[0],&c->context[0],
> +				state)) {
> +				ERR(state->handle, "Out of memory!");
> +				return -1;
> +			}
> +			switch (i) {
> +			case OCON_ISID:
> +				n->sid[0] = c->sid[0];
> +				break;
> +			case OCON_PIRQ:
> +				n->u.pirq = c->u.pirq;
> +				break;
> +			case OCON_IOPORT:
> +				n->u.ioport.low_ioport = c->u.ioport.low_ioport;
> +				n->u.ioport.high_ioport =
> +					c->u.ioport.high_ioport;
> +				break;
> +			case OCON_IOMEM:
> +				n->u.iomem.low_iomem  = c->u.iomem.low_iomem;
> +				n->u.iomem.high_iomem = c->u.iomem.high_iomem;
> +				break;
> +			case OCON_DEVICE:
> +				n->u.device = c->u.device;
> +				break;
> +			default:
> +				/* shouldn't get here */
> +				ERR(state->handle, "Unknown ocontext");
> +				return -1;
>    

How do you not get here if you are going through to OCON_NUM which 
includes OCON_DUMMY{1,2} ?

> +			}
> +		}
> +	}
> +	return 0;
> +}
> +
> +static int ocontext_copy_selinux(expand_state_t *state)
> +{
> +	unsigned int i, j;
> +	ocontext_t *c, *n, *l;
> +
> +	for (i = 0; i<  OCON_NUM; i++) {
> +		l = NULL;
> +		for (c = state->base->ocontexts[i]; c; c = c->next) {
> +			n = malloc(sizeof(ocontext_t));
> +			if (!n) {
> +				ERR(state->handle, "Out of memory!");
> +				return -1;
>   			}
> +			memset(n, 0, sizeof(ocontext_t));
> +			if (l)
> +				l->next = n;
> +			else
> +				state->out->ocontexts[i] = n;
>   			l = n;
>   			if (context_copy(&n->context[0],&c->context[0], state)) {
>   				ERR(state->handle, "Out of memory!");
> @@ -1885,13 +1937,31 @@ static int ocontext_copy(expand_state_t * state)
>   				break;
>   			default:
>   				/* shouldn't get here */
> -				assert(0);
> +				ERR(state->handle, "Unknown ocontext");
> +				return -1;
>   			}
>   		}
>   	}
>   	return 0;
>   }
>
> +static int ocontext_copy(expand_state_t *state, uint32_t target)
> +{
> +	int rc = -1;
> +	switch (target) {
> +	case SEPOL_TARGET_SELINUX:
> +		rc = ocontext_copy_selinux(state);
> +		break;
> +	case SEPOL_TARGET_XEN:
> +		rc = ocontext_copy_xen(state);
> +		break;
> +	default:
> +		ERR(state->handle, "Unknown target");
> +		return -1;
> +	}
> +	return rc;
> +}
> +
>   static int genfs_copy(expand_state_t * state)
>   {
>   	ocontext_t *c, *newc, *l;
> @@ -2418,6 +2488,9 @@ int expand_module(sepol_handle_t * handle,
>   	out->mls = base->mls;
>   	out->handle_unknown = base->handle_unknown;
>
> +	/* Copy target from base to out */
> +	out->target_type = base->target_type;
> +
>   	/* Copy policy capabilities */
>   	if (ebitmap_cpy(&out->policycaps,&base->policycaps)) {
>   		ERR(handle, "Out of memory!");
> @@ -2576,7 +2649,7 @@ int expand_module(sepol_handle_t * handle,
>   	evaluate_conds(state.out);
>
>   	/* copy ocontexts */
> -	if (ocontext_copy(&state))
> +	if (ocontext_copy(&state, out->target_type))
>   		goto cleanup;
>
>   	/* copy genfs */
> diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
> index 85ddefc..3d9bfe0 100644
> --- a/libsepol/src/policydb.c
> +++ b/libsepol/src/policydb.c
> @@ -54,6 +54,9 @@
>   #include "debug.h"
>   #include "mls.h"
>
> +#define POLICYDB_TARGET_SZ   ARRAY_SIZE(policydb_target_strings)
> +char *policydb_target_strings[] = { POLICYDB_STRING, POLICYDB_XEN_STRING };
> +
>   /* These need to be updated if SYM_NUM or OCON_NUM changes */
>   static struct policydb_compat_info policydb_compat[] = {
>   	{
> @@ -1079,9 +1082,13 @@ void policydb_destroy(policydb_t * p)
>   			c = c->next;
>   			context_destroy(&ctmp->context[0]);
>   			context_destroy(&ctmp->context[1]);
> -			if (i == OCON_ISID || i == OCON_FS || i == OCON_NETIF
> -			    || i == OCON_FSUSE)
> +			if (i == OCON_ISID)
> +				free(ctmp->u.name);
> +			if (p->target_type == SEPOL_TARGET_SELINUX&&
> +				(i == OCON_FS || i == OCON_NETIF ||
> +				i == OCON_FSUSE))
>   				free(ctmp->u.name);
>    

This is messy, why not an ocontext_selinux_free() and 
ocontext_xen_free() (note: I realize the xen_free() one won't do 
anything except freep the ocontext_t)

> +
>   			free(ctmp);
>   		}
>   	}
> @@ -2102,7 +2109,88 @@ int role_allow_read(role_allow_t ** r, struct policy_file *fp)
>   	return 0;
>   }
>
> -static int ocontext_read(struct policydb_compat_info *info,
> +static int ocontext_read_xen(struct policydb_compat_info *info,
> +	policydb_t *p, struct policy_file *fp)
> +{
> +	unsigned int i, j;
> +	size_t nel;
> +	ocontext_t *l, *c;
> +	uint32_t buf[8];
> +	int rc;
> +
> +	for (i = 0; i<  info->ocon_num; i++) {
> +		rc = next_entry(buf, fp, sizeof(uint32_t));
> +		if (rc<  0)
> +			return -1;
> +		nel = le32_to_cpu(buf[0]);
> +		l = NULL;
> +		for (j = 0; j<  nel; j++) {
> +			c = calloc(1, sizeof(ocontext_t));
> +			if (!c)
> +				return -1;
> +			if (l)
> +				l->next = c;
> +			else
> +				p->ocontexts[i] = c;
> +			l = c;
> +			switch (i) {
> +			case OCON_ISID:
> +				rc = next_entry(buf, fp, sizeof(uint32_t));
> +				if (rc<  0)
> +					return -1;
> +				c->sid[0] = le32_to_cpu(buf[0]);
> +				if (context_read_and_validate
> +				    (&c->context[0], p, fp))
> +					return -1;
> +				break;
> +			case OCON_PIRQ:
> +				rc = next_entry(buf, fp, sizeof(uint32_t));
> +				if (rc<  0)
> +					return -1;
> +				c->u.pirq = le32_to_cpu(buf[0]);
> +				if (context_read_and_validate
> +				    (&c->context[0], p, fp))
> +					return -1;
> +				break;
> +			case OCON_IOPORT:
> +				rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
> +				if (rc<  0)
> +					return -1;
> +				c->u.ioport.low_ioport = le32_to_cpu(buf[0]);
> +				c->u.ioport.high_ioport = le32_to_cpu(buf[1]);
> +				if (context_read_and_validate
> +				    (&c->context[0], p, fp))
> +					return -1;
> +				break;
> +			case OCON_IOMEM:
> +				rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
> +				if (rc<  0)
> +					return -1;
> +				c->u.iomem.low_iomem = le32_to_cpu(buf[0]);
> +				c->u.iomem.high_iomem = le32_to_cpu(buf[1]);
> +				if (context_read_and_validate
> +				    (&c->context[0], p, fp))
> +					return -1;
> +				break;
> +			case OCON_DEVICE:
> +				rc = next_entry(buf, fp, sizeof(uint32_t));
> +				if (rc<  0)
> +					return -1;
> +				c->u.device = le32_to_cpu(buf[0]);
> +				if (context_read_and_validate
> +				    (&c->context[0], p, fp))
> +					return -1;
> +				break;
> +			default:
> +				/* should never get here */
> +				ERR(fp->handle, "Unknown Xen ocontext");
> +				return -1;
>    

Same as above with OCON_DUMMY{1,2}

> +			}
> +		}
> +	}
> +	return 0;
> +}
> +static int ocontext_read_selinux(struct policydb_compat_info *info,
>   			 policydb_t * p, struct policy_file *fp)
>   {
>   	unsigned int i, j;
> @@ -2197,23 +2285,25 @@ static int ocontext_read(struct policydb_compat_info *info,
>   					return -1;
>   				break;
>   			case OCON_NODE6:{
> -					int k;
> -
> -					rc = next_entry(buf, fp,
> -							sizeof(uint32_t) * 8);
> -					if (rc<  0)
> -						return -1;
> -					for (k = 0; k<  4; k++)
> -						c->u.node6.addr[k] = buf[k]; /* network order */
> -					for (k = 0; k<  4; k++)
> -						c->u.node6.mask[k] = buf[k + 4]; /* network order */
> -					if (context_read_and_validate
> -					    (&c->context[0], p, fp))
> -						return -1;
> -					break;
> +				int k;
> +
> +				rc = next_entry(buf, fp, sizeof(uint32_t) * 8);
> +				if (rc<  0)
> +					return -1;
> +				for (k = 0; k<  4; k++)
> +					 /* network order */
> +					c->u.node6.addr[k] = buf[k];
> +				for (k = 0; k<  4; k++)
> +					/* network order */
> +					c->u.node6.mask[k] = buf[k + 4];
> +				if (context_read_and_validate
> +				    (&c->context[0], p, fp))
> +					return -1;
> +				break;
>    

Was this only a whitespace change?

>   				}
>   			default:{
> -					assert(0);	/* should never get here */
> +				ERR(fp->handle, "Unknown SELinux ocontext");
> +				return -1;
>   				}
>   			}
>   		}
> @@ -2221,6 +2311,23 @@ static int ocontext_read(struct policydb_compat_info *info,
>   	return 0;
>   }
>
> +static int ocontext_read(struct policydb_compat_info *info,
> +	policydb_t *p, struct policy_file *fp)
> +{
> +	int rc = -1;
> +	switch (p->target_type) {
> +	case SEPOL_TARGET_SELINUX:
> +		rc = ocontext_read_selinux(info, p, fp);
> +		break;
> +	case SEPOL_TARGET_XEN:
> +		rc = ocontext_read_xen(info, p, fp);
> +		break;
> +	default:
> +		ERR(fp->handle, "Unknown target");
> +	}
> +	return rc;
> +}
> +
>   static int genfs_read(policydb_t * p, struct policy_file *fp)
>   {
>   	uint32_t buf[1];
> @@ -3070,7 +3177,7 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose)
>   	unsigned int i, j, r_policyvers;
>   	uint32_t buf[5], config;
>   	size_t len, nprim, nel;
> -	char *policydb_str, *target_str = NULL, *alt_target_str = NULL;
> +	char *policydb_str;
>   	struct policydb_compat_info *info;
>   	unsigned int policy_type, bufindex;
>   	ebitmap_node_t *tnode;
> @@ -3087,11 +3194,8 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose)
>
>   	if (buf[0] == POLICYDB_MAGIC) {
>   		policy_type = POLICY_KERN;
> -		target_str = POLICYDB_STRING;
> -		alt_target_str = POLICYDB_ALT_STRING;
>   	} else if (buf[0] == POLICYDB_MOD_MAGIC) {
>   		policy_type = POLICY_MOD;
> -		target_str = POLICYDB_MOD_STRING;
>   	} else {
>   		ERR(fp->handle, "policydb magic number %#08x does not "
>   		    "match expected magic number %#08x or %#08x",
> @@ -3100,10 +3204,8 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose)
>   	}
>
>   	len = buf[1];
> -	if (len != strlen(target_str)&&
> -	    (!alt_target_str || len != strlen(alt_target_str))) {
> -		ERR(fp->handle, "policydb string length %zu does not match "
> -		    "expected length %zu", len, strlen(target_str));
> +	if (len>  32) {
>    

magic number 32?

> +		ERR(fp->handle, "policydb string length too long ");
>   		return POLICYDB_ERROR;
>   	}
>
> @@ -3120,13 +3222,31 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose)
>   		return POLICYDB_ERROR;
>   	}
>   	policydb_str[len] = 0;
> -	if (strcmp(policydb_str, target_str)&&
> -	    (!alt_target_str || strcmp(policydb_str, alt_target_str))) {
> -		ERR(fp->handle, "policydb string %s does not match "
> -		    "my string %s", policydb_str, target_str);
> -		free(policydb_str);
> -		return POLICYDB_ERROR;
> +
> +	if (policy_type == POLICY_KERN) {
> +		for (i = 0; i<  POLICYDB_TARGET_SZ; i++) {
> +			if ((strcmp(policydb_str, policydb_target_strings[i])
> +				== 0)) {
> +				policydb_set_target_platform(p, i);
> +				break;
> +			}
> +		}
> +
> +		if (i == POLICYDB_TARGET_SZ) {
>    

That is a strange way to check if it was invalid but I suppose it works..

> +			ERR(fp->handle, "cannot find a valid target for policy "
> +				"string %s", policydb_str);
> +			free(policydb_str);
> +			return POLICYDB_ERROR;
> +		}
> +	} else {
> +		if (strcmp(policydb_str, POLICYDB_MOD_STRING)) {
> +			ERR(fp->handle, "invalid string identifier %s",
> +				policydb_str);
> +			free(policydb_str);
> +			return POLICYDB_ERROR;
> +		}
>   	}
> +
>   	/* Done with policydb_str. */
>   	free(policydb_str);
>   	policydb_str = NULL;
> @@ -3391,3 +3511,16 @@ void policy_file_init(policy_file_t *pf)
>   {
>   	memset(pf, 0, sizeof(policy_file_t));
>   }
> +
> +int policydb_set_target_platform(policydb_t *p, int platform)
> +{
> +	if (platform == SEPOL_TARGET_SELINUX)
> +		p->target_type = SEPOL_TARGET_SELINUX;
> +	else if (platform == SEPOL_TARGET_XEN)
> +		p->target_type = SEPOL_TARGET_XEN;
> +	else
> +		return -1;
>    

> +
> +	return 0;
> +}
> +
> diff --git a/libsepol/src/policydb_internal.h b/libsepol/src/policydb_internal.h
> index 1eb99e5..8a31506 100644
> --- a/libsepol/src/policydb_internal.h
> +++ b/libsepol/src/policydb_internal.h
> @@ -6,4 +6,5 @@
>
>   hidden_proto(sepol_policydb_create)
>       hidden_proto(sepol_policydb_free)
> +extern char *policydb_target_strings[];
>   #endif
> diff --git a/libsepol/src/write.c b/libsepol/src/write.c
> index 66b35ec..a557c2e 100644
> --- a/libsepol/src/write.c
> +++ b/libsepol/src/write.c
> @@ -1084,10 +1084,79 @@ static int (*write_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum,
>   common_write, class_write, role_write, type_write, user_write,
>   	    cond_write_bool, sens_write, cat_write,};
>
> -static int ocontext_write(struct policydb_compat_info *info, policydb_t * p,
> +static int ocontext_write_xen(struct policydb_compat_info *info, policydb_t *p,
>   			  struct policy_file *fp)
>   {
>   	unsigned int i, j;
> +	size_t nel, items;
> +	uint32_t buf[32];
> +	ocontext_t *c;
> +	for (i = 0; i<  info->ocon_num; i++) {
> +		nel = 0;
> +		for (c = p->ocontexts[i]; c; c = c->next)
> +			nel++;
> +		buf[0] = cpu_to_le32(nel);
> +		items = put_entry(buf, sizeof(uint32_t), 1, fp);
> +		if (items != 1)
> +			return POLICYDB_ERROR;
> +		for (c = p->ocontexts[i]; c; c = c->next) {
> +			switch (i) {
> +			case OCON_ISID:
> +				buf[0] = cpu_to_le32(c->sid[0]);
> +				items = put_entry(buf, sizeof(uint32_t), 1, fp);
> +				if (items != 1)
> +					return POLICYDB_ERROR;
> +				if (context_write(p,&c->context[0], fp))
> +					return POLICYDB_ERROR;
> +				break;
> +			case OCON_PIRQ:
> +				buf[0] = cpu_to_le32(c->u.pirq);
> +				items = put_entry(buf, sizeof(uint32_t), 1, fp);
> +				if (items != 1)
> +					return POLICYDB_ERROR;
> +				if (context_write(p,&c->context[0], fp))
> +					return POLICYDB_ERROR;
> +				break;
> +			case OCON_IOPORT:
> +				buf[0] = c->u.ioport.low_ioport;
> +				buf[1] = c->u.ioport.high_ioport;
> +				for (j = 0; j<  2; j++)
> +					buf[j] = cpu_to_le32(buf[j]);
> +				items = put_entry(buf, sizeof(uint32_t), 2, fp);
> +				if (items != 2)
> +					return POLICYDB_ERROR;
> +				if (context_write(p,&c->context[0], fp))
> +					return POLICYDB_ERROR;
> +				break;
> +			case OCON_IOMEM:
> +				buf[0] = c->u.iomem.low_iomem;
> +				buf[1] = c->u.iomem.high_iomem;
> +				for (j = 0; j<  2; j++)
> +					buf[j] = cpu_to_le32(buf[j]);
> +				items = put_entry(buf, sizeof(uint32_t), 2, fp);
> +				if (items != 2)
> +					return POLICYDB_ERROR;
> +				if (context_write(p,&c->context[0], fp))
> +					return POLICYDB_ERROR;
> +				break;
> +			case OCON_DEVICE:
> +				buf[0] = cpu_to_le32(c->u.device);
> +				items = put_entry(buf, sizeof(uint32_t), 1, fp);
> +				if (items != 1)
> +					return POLICYDB_ERROR;
> +				if (context_write(p,&c->context[0], fp))
> +					return POLICYDB_ERROR;
> +				break;
> +			}
> +		}
> +	}
> +	return POLICYDB_SUCCESS;
> +}
> +
> +static int ocontext_write_selinux(struct policydb_compat_info *info,
> +	policydb_t *p, struct policy_file *fp)
> +{
> +	unsigned int i, j;
>   	size_t nel, items, len;
>   	uint32_t buf[32];
>   	ocontext_t *c;
> @@ -1176,6 +1245,21 @@ static int ocontext_write(struct policydb_compat_info *info, policydb_t * p,
>   	return POLICYDB_SUCCESS;
>   }
>
> +static int ocontext_write(struct policydb_compat_info *info, policydb_t * p,
> +	struct policy_file *fp)
> +{
> +	int rc = POLICYDB_ERROR;
> +	switch (p->target_type) {
> +	case SEPOL_TARGET_SELINUX:
> +		rc = ocontext_write_selinux(info, p, fp);
> +		break;
> +	case SEPOL_TARGET_XEN:
> +		rc = ocontext_write_xen(info, p, fp);
> +		break;
> +	}
> +	return rc;
> +}
> +
>   static int genfs_write(policydb_t * p, struct policy_file *fp)
>   {
>   	genfs_t *genfs;
> @@ -1610,8 +1694,8 @@ int policydb_write(policydb_t * p, struct policy_file *fp)
>   	items = 0;
>   	if (p->policy_type == POLICY_KERN) {
>   		buf[items++] = cpu_to_le32(POLICYDB_MAGIC);
> -		len = strlen(POLICYDB_STRING);
> -		policydb_str = POLICYDB_STRING;
> +		len = strlen(policydb_target_strings[p->target_type]);
> +		policydb_str = policydb_target_strings[p->target_type];
>   	} else {
>   		buf[items++] = cpu_to_le32(POLICYDB_MOD_MAGIC);
>   		len = strlen(POLICYDB_MOD_STRING);
>
>
>
> --
> 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.
>
>    

--
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] 13+ messages in thread

* Re: [PATCH 1/3] libsepol: Add support for multiple target OSes
  2009-09-16 13:58 ` [PATCH 1/3] libsepol: " Joshua Brindle
@ 2009-09-16 17:44   ` Paul Nuzzi
  2009-09-16 19:01     ` Stephen Smalley
  2009-09-29 14:03   ` Paul Nuzzi
  1 sibling, 1 reply; 13+ messages in thread
From: Paul Nuzzi @ 2009-09-16 17:44 UTC (permalink / raw)
  To: Joshua Brindle; +Cc: selinux, Stephen Smalley

On Wed, 2009-09-16 at 09:58 -0400, Joshua Brindle wrote:
> 
> pjnuzzi wrote:
> 
> <snip>
> > Signed-off-by: Paul Nuzzi<pjnuzzi@tycho.ncsc.mil>
> >
> > ---
> >   libsepol/include/sepol/policydb/policydb.h |   28 +++-
> >   libsepol/src/expand.c                      |   85 +++++++++++-
> >   libsepol/src/policydb.c                    |  197
> > ++++++++++++++++++++++++-----
> >   libsepol/src/policydb_internal.h           |    1
> >   libsepol/src/write.c                       |   90 ++++++++++++-
> >   5 files changed, 359 insertions(+), 42 deletions(-)
> >
> > diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h
> > index 0105cf4..2013238 100644
> > --- a/libsepol/include/sepol/policydb/policydb.h
> > +++ b/libsepol/include/sepol/policydb/policydb.h
> > @@ -276,6 +276,16 @@ typedef struct ocontext {
> >   			uint32_t addr[4]; /* network order */
> >   			uint32_t mask[4]; /* network order */
> >   		} node6;	/* IPv6 node information */
> > +		uint32_t device;
> > +		uint16_t pirq;
> > +		struct {
> > +			uint32_t low_iomem;
> > +			uint32_t high_iomem;
> > +		} iomem;
> > +		struct {
> > +			uint32_t low_ioport;
> > +			uint32_t high_ioport;
> > +		} ioport;
> >    
> 
> I'd rather have separate ocontext structs for each system. That way it 
> is very easy to understand which ones apply to which system and you 
> don't get a crazy out of context ocontext struct.
> 

In the beginning I tried implementing a separate ocontext struct for
each system but I was having issues.  If we have a separate struct for
each platform a lot more code is going to have to be patched to decouple
SELinux from being the default ocontext target.  Just a quick search
with cscope shows there is 96 references to ocontext_t.  It might be
easier to have one big (and confusing) ocontext structure at the expense
of refactoring a lot of code.  

A good compromise might be to have an ocontext structure that nests Xen,
SELinux, Solaris, etc. structures to make it easier to see which ones
apply to the platform.  For example..

struct ocontext {
	struct xen_ocontexts {
		uint32_t device;
			struct {
				uint32_t low_iomem;
				uint32_t high_iomem;
			} iomem;
	} xen;
	struct selinux_ocontexts {
		uint32_t addr[4]; /* network order */
	} selinux;	
}

Let me know what would be better.


> >   	} u;
> >   	union {
> >   		uint32_t sclass;	/* security class for genfs */
> > @@ -313,6 +323,17 @@ typedef struct genfs {
> >   #define OCON_NODE6 6		/* IPv6 nodes */
> >   #define OCON_NUM   7
> >
> > +/* object context array indices for Xen */
> > +#define OCON_ISID    0    /* initial SIDs */
> > +#define OCON_PIRQ    1    /* physical irqs */
> > +#define OCON_IOPORT  2    /* io ports */
> > +#define OCON_IOMEM   3    /* io memory */
> > +#define OCON_DEVICE  4    /* pci devices */
> > +#define OCON_DUMMY1  5    /* reserved */
> > +#define OCON_DUMMY2  6    /* reserved */
> > +#define OCON_NUM     7
> > +
> > +
> >    
> 
> Should these be namespaced? What if <random other system> has io port 
> objects? You'd have to align them with each other and you have a mess of 
> keeping the numbers the same (you already do this with OCON_ISID)
> 
> Also we are relying on having the same number of OCON's which isn't good 
> I don't think. As much as I hate the policydb_compat_info (read: alot) 
> why aren't we using that to say how many ocons a xen policy really has?
> 

These should probably be namespaced then.  I will check into
policydb_compat_info.  

> >   /* section: module information */
> >
> >   /* scope_index_t holds all of the symbols that are in scope in a
> > @@ -400,6 +421,7 @@ typedef struct policydb {
> >   	uint32_t policy_type;
> >   	char *name;
> >   	char *version;
> > +	uint32_t target_type;
> >
> >    
> 
> Really bad variable name. how about target_platform or something?

Sounds good. Easy fix.

> 
> >   	/* Set when the policydb is modified such that writing is unsupported */
> >   	int unsupported_format;
> > @@ -593,6 +615,7 @@ extern int avrule_read_list(policydb_t * p, avrule_t ** avrules,
> >   			    struct policy_file *fp);
> >
> >   extern int policydb_write(struct policydb *p, struct policy_file *pf);
> > +extern int policydb_set_target_platform(policydb_t *p, int platform);
> >
> >   #define PERM_SYMTAB_SIZE 32
> >
> > @@ -651,9 +674,12 @@ extern int policydb_write(struct policydb *p, struct policy_file *pf);
> >
> >   #define POLICYDB_MAGIC SELINUX_MAGIC
> >   #define POLICYDB_STRING "SE Linux"
> > -#define POLICYDB_ALT_STRING "Flask"
> > +#define POLICYDB_XEN_STRING "XenFlask"
> >   #define POLICYDB_MOD_MAGIC SELINUX_MOD_MAGIC
> >   #define POLICYDB_MOD_STRING "SE Linux Module"
> > +#define SEPOL_TARGET_SELINUX 0
> > +#define SEPOL_TARGET_XEN     1
> > +
> >
> >   #endif				/* _POLICYDB_H_ */
> >
> > diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
> > index e9cd986..38e2481 100644
> > --- a/libsepol/src/expand.c
> > +++ b/libsepol/src/expand.c
> > @@ -1819,9 +1819,9 @@ static int context_copy(context_struct_t * dst, context_struct_t * src,
> >   	return mls_context_cpy(dst, src);
> >   }
> >
> > -static int ocontext_copy(expand_state_t * state)
> > +static int ocontext_copy_xen(expand_state_t *state)
> >   {
> > -	unsigned int i, j;
> > +	unsigned int i;
> >   	ocontext_t *c, *n, *l;
> >
> >   	for (i = 0; i<  OCON_NUM; i++) {
> > @@ -1833,11 +1833,63 @@ static int ocontext_copy(expand_state_t * state)
> >   				return -1;
> >   			}
> >   			memset(n, 0, sizeof(ocontext_t));
> > -			if (l) {
> > +			if (l)
> >   				l->next = n;
> > -			} else {
> > +			else
> >    
> 
> whitespace changes.

It looks like whitespace changes but this is where ocontext_read is
expanded to ocontext_read_xen.  ocontext_read becomes a switch statement
on target_platform.  Checkpatch was giving errors about the style which
is why the brackets were deleted.  

> 
> >   				state->out->ocontexts[i] = n;
> > +			l = n;
> > +			if (context_copy(&n->context[0],&c->context[0],
> > +				state)) {
> > +				ERR(state->handle, "Out of memory!");
> > +				return -1;
> > +			}
> > +			switch (i) {
> > +			case OCON_ISID:
> > +				n->sid[0] = c->sid[0];
> > +				break;
> > +			case OCON_PIRQ:
> > +				n->u.pirq = c->u.pirq;
> > +				break;
> > +			case OCON_IOPORT:
> > +				n->u.ioport.low_ioport = c->u.ioport.low_ioport;
> > +				n->u.ioport.high_ioport =
> > +					c->u.ioport.high_ioport;
> > +				break;
> > +			case OCON_IOMEM:
> > +				n->u.iomem.low_iomem  = c->u.iomem.low_iomem;
> > +				n->u.iomem.high_iomem = c->u.iomem.high_iomem;
> > +				break;
> > +			case OCON_DEVICE:
> > +				n->u.device = c->u.device;
> > +				break;
> > +			default:
> > +				/* shouldn't get here */
> > +				ERR(state->handle, "Unknown ocontext");
> > +				return -1;
> >    
> 
> How do you not get here if you are going through to OCON_NUM which 
> includes OCON_DUMMY{1,2} ?
> 

The ocontext is not copied because there are no rules attached to the
OCON_DUMMY{1,2} linked list. The default case should never be reached.

> > +			}
> > +		}
> > +	}
> > +	return 0;
> > +}
> > +
> > +static int ocontext_copy_selinux(expand_state_t *state)
> > +{
> > +	unsigned int i, j;
> > +	ocontext_t *c, *n, *l;
> > +
> > +	for (i = 0; i<  OCON_NUM; i++) {
> > +		l = NULL;
> > +		for (c = state->base->ocontexts[i]; c; c = c->next) {
> > +			n = malloc(sizeof(ocontext_t));
> > +			if (!n) {
> > +				ERR(state->handle, "Out of memory!");
> > +				return -1;
> >   			}
> > +			memset(n, 0, sizeof(ocontext_t));
> > +			if (l)
> > +				l->next = n;
> > +			else
> > +				state->out->ocontexts[i] = n;
> >   			l = n;
> >   			if (context_copy(&n->context[0],&c->context[0], state)) {
> >   				ERR(state->handle, "Out of memory!");
> > @@ -1885,13 +1937,31 @@ static int ocontext_copy(expand_state_t * state)
> >   				break;
> >   			default:
> >   				/* shouldn't get here */
> > -				assert(0);
> > +				ERR(state->handle, "Unknown ocontext");
> > +				return -1;
> >   			}
> >   		}
> >   	}
> >   	return 0;
> >   }
> >
> > +static int ocontext_copy(expand_state_t *state, uint32_t target)
> > +{
> > +	int rc = -1;
> > +	switch (target) {
> > +	case SEPOL_TARGET_SELINUX:
> > +		rc = ocontext_copy_selinux(state);
> > +		break;
> > +	case SEPOL_TARGET_XEN:
> > +		rc = ocontext_copy_xen(state);
> > +		break;
> > +	default:
> > +		ERR(state->handle, "Unknown target");
> > +		return -1;
> > +	}
> > +	return rc;
> > +}
> > +
> >   static int genfs_copy(expand_state_t * state)
> >   {
> >   	ocontext_t *c, *newc, *l;
> > @@ -2418,6 +2488,9 @@ int expand_module(sepol_handle_t * handle,
> >   	out->mls = base->mls;
> >   	out->handle_unknown = base->handle_unknown;
> >
> > +	/* Copy target from base to out */
> > +	out->target_type = base->target_type;
> > +
> >   	/* Copy policy capabilities */
> >   	if (ebitmap_cpy(&out->policycaps,&base->policycaps)) {
> >   		ERR(handle, "Out of memory!");
> > @@ -2576,7 +2649,7 @@ int expand_module(sepol_handle_t * handle,
> >   	evaluate_conds(state.out);
> >
> >   	/* copy ocontexts */
> > -	if (ocontext_copy(&state))
> > +	if (ocontext_copy(&state, out->target_type))
> >   		goto cleanup;
> >
> >   	/* copy genfs */
> > diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
> > index 85ddefc..3d9bfe0 100644
> > --- a/libsepol/src/policydb.c
> > +++ b/libsepol/src/policydb.c
> > @@ -54,6 +54,9 @@
> >   #include "debug.h"
> >   #include "mls.h"
> >
> > +#define POLICYDB_TARGET_SZ   ARRAY_SIZE(policydb_target_strings)
> > +char *policydb_target_strings[] = { POLICYDB_STRING, POLICYDB_XEN_STRING };
> > +
> >   /* These need to be updated if SYM_NUM or OCON_NUM changes */
> >   static struct policydb_compat_info policydb_compat[] = {
> >   	{
> > @@ -1079,9 +1082,13 @@ void policydb_destroy(policydb_t * p)
> >   			c = c->next;
> >   			context_destroy(&ctmp->context[0]);
> >   			context_destroy(&ctmp->context[1]);
> > -			if (i == OCON_ISID || i == OCON_FS || i == OCON_NETIF
> > -			    || i == OCON_FSUSE)
> > +			if (i == OCON_ISID)
> > +				free(ctmp->u.name);
> > +			if (p->target_type == SEPOL_TARGET_SELINUX&&
> > +				(i == OCON_FS || i == OCON_NETIF ||
> > +				i == OCON_FSUSE))
> >   				free(ctmp->u.name);
> >    
> 
> This is messy, why not an ocontext_selinux_free() and 
> ocontext_xen_free() (note: I realize the xen_free() one won't do 
> anything except freep the ocontext_t)

Sounds good.  

> > +
> >   			free(ctmp);
> >   		}
> >   	}
> > @@ -2102,7 +2109,88 @@ int role_allow_read(role_allow_t ** r, struct policy_file *fp)
> >   	return 0;
> >   }
> >
> > -static int ocontext_read(struct policydb_compat_info *info,
> > +static int ocontext_read_xen(struct policydb_compat_info *info,
> > +	policydb_t *p, struct policy_file *fp)
> > +{
> > +	unsigned int i, j;
> > +	size_t nel;
> > +	ocontext_t *l, *c;
> > +	uint32_t buf[8];
> > +	int rc;
> > +
> > +	for (i = 0; i<  info->ocon_num; i++) {
> > +		rc = next_entry(buf, fp, sizeof(uint32_t));
> > +		if (rc<  0)
> > +			return -1;
> > +		nel = le32_to_cpu(buf[0]);
> > +		l = NULL;
> > +		for (j = 0; j<  nel; j++) {
> > +			c = calloc(1, sizeof(ocontext_t));
> > +			if (!c)
> > +				return -1;
> > +			if (l)
> > +				l->next = c;
> > +			else
> > +				p->ocontexts[i] = c;
> > +			l = c;
> > +			switch (i) {
> > +			case OCON_ISID:
> > +				rc = next_entry(buf, fp, sizeof(uint32_t));
> > +				if (rc<  0)
> > +					return -1;
> > +				c->sid[0] = le32_to_cpu(buf[0]);
> > +				if (context_read_and_validate
> > +				    (&c->context[0], p, fp))
> > +					return -1;
> > +				break;
> > +			case OCON_PIRQ:
> > +				rc = next_entry(buf, fp, sizeof(uint32_t));
> > +				if (rc<  0)
> > +					return -1;
> > +				c->u.pirq = le32_to_cpu(buf[0]);
> > +				if (context_read_and_validate
> > +				    (&c->context[0], p, fp))
> > +					return -1;
> > +				break;
> > +			case OCON_IOPORT:
> > +				rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
> > +				if (rc<  0)
> > +					return -1;
> > +				c->u.ioport.low_ioport = le32_to_cpu(buf[0]);
> > +				c->u.ioport.high_ioport = le32_to_cpu(buf[1]);
> > +				if (context_read_and_validate
> > +				    (&c->context[0], p, fp))
> > +					return -1;
> > +				break;
> > +			case OCON_IOMEM:
> > +				rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
> > +				if (rc<  0)
> > +					return -1;
> > +				c->u.iomem.low_iomem = le32_to_cpu(buf[0]);
> > +				c->u.iomem.high_iomem = le32_to_cpu(buf[1]);
> > +				if (context_read_and_validate
> > +				    (&c->context[0], p, fp))
> > +					return -1;
> > +				break;
> > +			case OCON_DEVICE:
> > +				rc = next_entry(buf, fp, sizeof(uint32_t));
> > +				if (rc<  0)
> > +					return -1;
> > +				c->u.device = le32_to_cpu(buf[0]);
> > +				if (context_read_and_validate
> > +				    (&c->context[0], p, fp))
> > +					return -1;
> > +				break;
> > +			default:
> > +				/* should never get here */
> > +				ERR(fp->handle, "Unknown Xen ocontext");
> > +				return -1;
> >    
> 
> Same as above with OCON_DUMMY{1,2}

This check is correct.  It will only error if there is an OCON_DUMMY being read 
from the policy.  

> > +			}
> > +		}
> > +	}
> > +	return 0;
> > +}
> > +static int ocontext_read_selinux(struct policydb_compat_info *info,
> >   			 policydb_t * p, struct policy_file *fp)
> >   {
> >   	unsigned int i, j;
> > @@ -2197,23 +2285,25 @@ static int ocontext_read(struct policydb_compat_info *info,
> >   					return -1;
> >   				break;
> >   			case OCON_NODE6:{
> > -					int k;
> > -
> > -					rc = next_entry(buf, fp,
> > -							sizeof(uint32_t) * 8);
> > -					if (rc<  0)
> > -						return -1;
> > -					for (k = 0; k<  4; k++)
> > -						c->u.node6.addr[k] = buf[k]; /* network order */
> > -					for (k = 0; k<  4; k++)
> > -						c->u.node6.mask[k] = buf[k + 4]; /* network order */
> > -					if (context_read_and_validate
> > -					    (&c->context[0], p, fp))
> > -						return -1;
> > -					break;
> > +				int k;
> > +
> > +				rc = next_entry(buf, fp, sizeof(uint32_t) * 8);
> > +				if (rc<  0)
> > +					return -1;
> > +				for (k = 0; k<  4; k++)
> > +					 /* network order */
> > +					c->u.node6.addr[k] = buf[k];
> > +				for (k = 0; k<  4; k++)
> > +					/* network order */
> > +					c->u.node6.mask[k] = buf[k + 4];
> > +				if (context_read_and_validate
> > +				    (&c->context[0], p, fp))
> > +					return -1;
> > +				break;
> >    
> 
> Was this only a whitespace change?

The above is whitespace change.  The addition of ERR and return below is
where the change is.  Checkpatch was giving errors on indentation.  

> 
> >   				}
> >   			default:{
> > -					assert(0);	/* should never get here */
> > +				ERR(fp->handle, "Unknown SELinux ocontext");
> > +				return -1;
> >   				}
> >   			}
> >   		}
> > @@ -2221,6 +2311,23 @@ static int ocontext_read(struct policydb_compat_info *info,
> >   	return 0;
> >   }
> >
> > +static int ocontext_read(struct policydb_compat_info *info,
> > +	policydb_t *p, struct policy_file *fp)
> > +{
> > +	int rc = -1;
> > +	switch (p->target_type) {
> > +	case SEPOL_TARGET_SELINUX:
> > +		rc = ocontext_read_selinux(info, p, fp);
> > +		break;
> > +	case SEPOL_TARGET_XEN:
> > +		rc = ocontext_read_xen(info, p, fp);
> > +		break;
> > +	default:
> > +		ERR(fp->handle, "Unknown target");
> > +	}
> > +	return rc;
> > +}
> > +
> >   static int genfs_read(policydb_t * p, struct policy_file *fp)
> >   {
> >   	uint32_t buf[1];
> > @@ -3070,7 +3177,7 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose)
> >   	unsigned int i, j, r_policyvers;
> >   	uint32_t buf[5], config;
> >   	size_t len, nprim, nel;
> > -	char *policydb_str, *target_str = NULL, *alt_target_str = NULL;
> > +	char *policydb_str;
> >   	struct policydb_compat_info *info;
> >   	unsigned int policy_type, bufindex;
> >   	ebitmap_node_t *tnode;
> > @@ -3087,11 +3194,8 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose)
> >
> >   	if (buf[0] == POLICYDB_MAGIC) {
> >   		policy_type = POLICY_KERN;
> > -		target_str = POLICYDB_STRING;
> > -		alt_target_str = POLICYDB_ALT_STRING;
> >   	} else if (buf[0] == POLICYDB_MOD_MAGIC) {
> >   		policy_type = POLICY_MOD;
> > -		target_str = POLICYDB_MOD_STRING;
> >   	} else {
> >   		ERR(fp->handle, "policydb magic number %#08x does not "
> >   		    "match expected magic number %#08x or %#08x",
> > @@ -3100,10 +3204,8 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose)
> >   	}
> >
> >   	len = buf[1];
> > -	if (len != strlen(target_str)&&
> > -	    (!alt_target_str || len != strlen(alt_target_str))) {
> > -		ERR(fp->handle, "policydb string length %zu does not match "
> > -		    "expected length %zu", len, strlen(target_str));
> > +	if (len>  32) {
> >    
> 
> magic number 32?
> 

Will change to #define

> > +		ERR(fp->handle, "policydb string length too long ");
> >   		return POLICYDB_ERROR;
> >   	}
> >
> > @@ -3120,13 +3222,31 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose)
> >   		return POLICYDB_ERROR;
> >   	}
> >   	policydb_str[len] = 0;
> > -	if (strcmp(policydb_str, target_str)&&
> > -	    (!alt_target_str || strcmp(policydb_str, alt_target_str))) {
> > -		ERR(fp->handle, "policydb string %s does not match "
> > -		    "my string %s", policydb_str, target_str);
> > -		free(policydb_str);
> > -		return POLICYDB_ERROR;
> > +
> > +	if (policy_type == POLICY_KERN) {
> > +		for (i = 0; i<  POLICYDB_TARGET_SZ; i++) {
> > +			if ((strcmp(policydb_str, policydb_target_strings[i])
> > +				== 0)) {
> > +				policydb_set_target_platform(p, i);
> > +				break;
> > +			}
> > +		}
> > +
> > +		if (i == POLICYDB_TARGET_SZ) {
> >    
> 
> That is a strange way to check if it was invalid but I suppose it works..
> 
> > +			ERR(fp->handle, "cannot find a valid target for policy "
> > +				"string %s", policydb_str);
> > +			free(policydb_str);
> > +			return POLICYDB_ERROR;
> > +		}
> > +	} else {
> > +		if (strcmp(policydb_str, POLICYDB_MOD_STRING)) {
> > +			ERR(fp->handle, "invalid string identifier %s",
> > +				policydb_str);
> > +			free(policydb_str);
> > +			return POLICYDB_ERROR;
> > +		}
> >   	}
> > +
> >   	/* Done with policydb_str. */
> >   	free(policydb_str);
> >   	policydb_str = NULL;
> > @@ -3391,3 +3511,16 @@ void policy_file_init(policy_file_t *pf)
> >   {
> >   	memset(pf, 0, sizeof(policy_file_t));
> >   }
> > +
> > +int policydb_set_target_platform(policydb_t *p, int platform)
> > +{
> > +	if (platform == SEPOL_TARGET_SELINUX)
> > +		p->target_type = SEPOL_TARGET_SELINUX;
> > +	else if (platform == SEPOL_TARGET_XEN)
> > +		p->target_type = SEPOL_TARGET_XEN;
> > +	else
> > +		return -1;
> >    
> 
> > +
> > +	return 0;
> > +}
> > +
> > diff --git a/libsepol/src/policydb_internal.h b/libsepol/src/policydb_internal.h
> > index 1eb99e5..8a31506 100644
> > --- a/libsepol/src/policydb_internal.h
> > +++ b/libsepol/src/policydb_internal.h
> > @@ -6,4 +6,5 @@
> >
> >   hidden_proto(sepol_policydb_create)
> >       hidden_proto(sepol_policydb_free)
> > +extern char *policydb_target_strings[];
> >   #endif
> > diff --git a/libsepol/src/write.c b/libsepol/src/write.c
> > index 66b35ec..a557c2e 100644
> > --- a/libsepol/src/write.c
> > +++ b/libsepol/src/write.c
> > @@ -1084,10 +1084,79 @@ static int (*write_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum,
> >   common_write, class_write, role_write, type_write, user_write,
> >   	    cond_write_bool, sens_write, cat_write,};
> >
> > -static int ocontext_write(struct policydb_compat_info *info, policydb_t * p,
> > +static int ocontext_write_xen(struct policydb_compat_info *info, policydb_t *p,
> >   			  struct policy_file *fp)
> >   {
> >   	unsigned int i, j;
> > +	size_t nel, items;
> > +	uint32_t buf[32];
> > +	ocontext_t *c;
> > +	for (i = 0; i<  info->ocon_num; i++) {
> > +		nel = 0;
> > +		for (c = p->ocontexts[i]; c; c = c->next)
> > +			nel++;
> > +		buf[0] = cpu_to_le32(nel);
> > +		items = put_entry(buf, sizeof(uint32_t), 1, fp);
> > +		if (items != 1)
> > +			return POLICYDB_ERROR;
> > +		for (c = p->ocontexts[i]; c; c = c->next) {
> > +			switch (i) {
> > +			case OCON_ISID:
> > +				buf[0] = cpu_to_le32(c->sid[0]);
> > +				items = put_entry(buf, sizeof(uint32_t), 1, fp);
> > +				if (items != 1)
> > +					return POLICYDB_ERROR;
> > +				if (context_write(p,&c->context[0], fp))
> > +					return POLICYDB_ERROR;
> > +				break;
> > +			case OCON_PIRQ:
> > +				buf[0] = cpu_to_le32(c->u.pirq);
> > +				items = put_entry(buf, sizeof(uint32_t), 1, fp);
> > +				if (items != 1)
> > +					return POLICYDB_ERROR;
> > +				if (context_write(p,&c->context[0], fp))
> > +					return POLICYDB_ERROR;
> > +				break;
> > +			case OCON_IOPORT:
> > +				buf[0] = c->u.ioport.low_ioport;
> > +				buf[1] = c->u.ioport.high_ioport;
> > +				for (j = 0; j<  2; j++)
> > +					buf[j] = cpu_to_le32(buf[j]);
> > +				items = put_entry(buf, sizeof(uint32_t), 2, fp);
> > +				if (items != 2)
> > +					return POLICYDB_ERROR;
> > +				if (context_write(p,&c->context[0], fp))
> > +					return POLICYDB_ERROR;
> > +				break;
> > +			case OCON_IOMEM:
> > +				buf[0] = c->u.iomem.low_iomem;
> > +				buf[1] = c->u.iomem.high_iomem;
> > +				for (j = 0; j<  2; j++)
> > +					buf[j] = cpu_to_le32(buf[j]);
> > +				items = put_entry(buf, sizeof(uint32_t), 2, fp);
> > +				if (items != 2)
> > +					return POLICYDB_ERROR;
> > +				if (context_write(p,&c->context[0], fp))
> > +					return POLICYDB_ERROR;
> > +				break;
> > +			case OCON_DEVICE:
> > +				buf[0] = cpu_to_le32(c->u.device);
> > +				items = put_entry(buf, sizeof(uint32_t), 1, fp);
> > +				if (items != 1)
> > +					return POLICYDB_ERROR;
> > +				if (context_write(p,&c->context[0], fp))
> > +					return POLICYDB_ERROR;
> > +				break;
> > +			}
> > +		}
> > +	}
> > +	return POLICYDB_SUCCESS;
> > +}
> > +
> > +static int ocontext_write_selinux(struct policydb_compat_info *info,
> > +	policydb_t *p, struct policy_file *fp)
> > +{
> > +	unsigned int i, j;
> >   	size_t nel, items, len;
> >   	uint32_t buf[32];
> >   	ocontext_t *c;
> > @@ -1176,6 +1245,21 @@ static int ocontext_write(struct policydb_compat_info *info, policydb_t * p,
> >   	return POLICYDB_SUCCESS;
> >   }
> >
> > +static int ocontext_write(struct policydb_compat_info *info, policydb_t * p,
> > +	struct policy_file *fp)
> > +{
> > +	int rc = POLICYDB_ERROR;
> > +	switch (p->target_type) {
> > +	case SEPOL_TARGET_SELINUX:
> > +		rc = ocontext_write_selinux(info, p, fp);
> > +		break;
> > +	case SEPOL_TARGET_XEN:
> > +		rc = ocontext_write_xen(info, p, fp);
> > +		break;
> > +	}
> > +	return rc;
> > +}
> > +
> >   static int genfs_write(policydb_t * p, struct policy_file *fp)
> >   {
> >   	genfs_t *genfs;
> > @@ -1610,8 +1694,8 @@ int policydb_write(policydb_t * p, struct policy_file *fp)
> >   	items = 0;
> >   	if (p->policy_type == POLICY_KERN) {
> >   		buf[items++] = cpu_to_le32(POLICYDB_MAGIC);
> > -		len = strlen(POLICYDB_STRING);
> > -		policydb_str = POLICYDB_STRING;
> > +		len = strlen(policydb_target_strings[p->target_type]);
> > +		policydb_str = policydb_target_strings[p->target_type];
> >   	} else {
> >   		buf[items++] = cpu_to_le32(POLICYDB_MOD_MAGIC);
> >   		len = strlen(POLICYDB_MOD_STRING);
> >
> >
> >
> > --
> > 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.
> >
> >    
> 
> --
> 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.


--
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] 13+ messages in thread

* Re: [PATCH 1/3] libsepol: Add support for multiple target OSes
  2009-09-16 17:44   ` Paul Nuzzi
@ 2009-09-16 19:01     ` Stephen Smalley
  0 siblings, 0 replies; 13+ messages in thread
From: Stephen Smalley @ 2009-09-16 19:01 UTC (permalink / raw)
  To: Paul Nuzzi; +Cc: Joshua Brindle, selinux

On Wed, 2009-09-16 at 13:44 -0400, Paul Nuzzi wrote:
> On Wed, 2009-09-16 at 09:58 -0400, Joshua Brindle wrote:
> > 
> > pjnuzzi wrote:
> > 
> > <snip>
> > > Signed-off-by: Paul Nuzzi<pjnuzzi@tycho.ncsc.mil>
> > >
> > > ---
> > >   libsepol/include/sepol/policydb/policydb.h |   28 +++-
> > >   libsepol/src/expand.c                      |   85 +++++++++++-
> > >   libsepol/src/policydb.c                    |  197
> > > ++++++++++++++++++++++++-----
> > >   libsepol/src/policydb_internal.h           |    1
> > >   libsepol/src/write.c                       |   90 ++++++++++++-
> > >   5 files changed, 359 insertions(+), 42 deletions(-)
> > >
> > > diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h
> > > index 0105cf4..2013238 100644
> > > --- a/libsepol/include/sepol/policydb/policydb.h
> > > +++ b/libsepol/include/sepol/policydb/policydb.h
> > > @@ -276,6 +276,16 @@ typedef struct ocontext {
> > >   			uint32_t addr[4]; /* network order */
> > >   			uint32_t mask[4]; /* network order */
> > >   		} node6;	/* IPv6 node information */
> > > +		uint32_t device;
> > > +		uint16_t pirq;
> > > +		struct {
> > > +			uint32_t low_iomem;
> > > +			uint32_t high_iomem;
> > > +		} iomem;
> > > +		struct {
> > > +			uint32_t low_ioport;
> > > +			uint32_t high_ioport;
> > > +		} ioport;
> > >    
> > 
> > I'd rather have separate ocontext structs for each system. That way it 
> > is very easy to understand which ones apply to which system and you 
> > don't get a crazy out of context ocontext struct.
> > 
> 
> In the beginning I tried implementing a separate ocontext struct for
> each system but I was having issues.  If we have a separate struct for
> each platform a lot more code is going to have to be patched to decouple
> SELinux from being the default ocontext target.  Just a quick search
> with cscope shows there is 96 references to ocontext_t.  It might be
> easier to have one big (and confusing) ocontext structure at the expense
> of refactoring a lot of code.  
> 
> A good compromise might be to have an ocontext structure that nests Xen,
> SELinux, Solaris, etc. structures to make it easier to see which ones
> apply to the platform.  For example..
> 
> struct ocontext {
> 	struct xen_ocontexts {
> 		uint32_t device;
> 			struct {
> 				uint32_t low_iomem;
> 				uint32_t high_iomem;
> 			} iomem;
> 	} xen;
> 	struct selinux_ocontexts {
> 		uint32_t addr[4]; /* network order */
> 	} selinux;	
> }
> 
> Let me know what would be better.

My $0.02 - this particular change isn't worth the trouble.  struct
ocontext already contains a union where the particular field is selected
based on the OCON_ index, and adding new fields within that union causes
no confusion.  Target platforms will always share the fields outside of
the union (the context, sid, and next fields), and will share the union
fields as appropriate (e.g. Linux, FreeBSD, and Solaris will share the
name, port, and node fields).

Most of the other suggested changes sounded reasonable to me.  In
particular, letting OCON_NUM vary based on target platform would be
nice.  Note that this means replacing all uses of OCON_NUM with a value
taken from the policydb compat info structure, and dynamically
allocating the ocontext array to that size.  Also passing in the target
platform as a key into policydb_lookup_compat().

-- 
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] 13+ messages in thread

* Re: [PATCH 1/3] libsepol: Add support for multiple target OSes
  2009-09-16 13:58 ` [PATCH 1/3] libsepol: " Joshua Brindle
  2009-09-16 17:44   ` Paul Nuzzi
@ 2009-09-29 14:03   ` Paul Nuzzi
  2009-10-06 14:20     ` Joshua Brindle
  2009-10-13 19:56     ` Joshua Brindle
  1 sibling, 2 replies; 13+ messages in thread
From: Paul Nuzzi @ 2009-09-29 14:03 UTC (permalink / raw)
  To: Joshua Brindle; +Cc: selinux, Stephen Smalley

On Wed, 2009-09-16 at 09:58 -0400, Joshua Brindle wrote: 
> I'd rather have separate ocontext structs for each system. That way it 
> is very easy to understand which ones apply to which system and you 
> don't get a crazy out of context ocontext struct.
> 

I looked into having separate ocontext structs but that would involve
changing a lot of files making the patch much larger and more intrusive.

> >   	} u;
> >   	union {
> >   		uint32_t sclass;	/* security class for genfs */
> > @@ -313,6 +323,17 @@ typedef struct genfs {
> >   #define OCON_NODE6 6		/* IPv6 nodes */
> >   #define OCON_NUM   7
> >
> > +/* object context array indices for Xen */
> > +#define OCON_ISID    0    /* initial SIDs */
> > +#define OCON_PIRQ    1    /* physical irqs */
> > +#define OCON_IOPORT  2    /* io ports */
> > +#define OCON_IOMEM   3    /* io memory */
> > +#define OCON_DEVICE  4    /* pci devices */
> > +#define OCON_DUMMY1  5    /* reserved */
> > +#define OCON_DUMMY2  6    /* reserved */
> > +#define OCON_NUM     7
> > +
> > +
> >    
> Should these be namespaced? What if <random other system> has io port 
> objects? You'd have to align them with each other and you have a mess of 
> keeping the numbers the same (you already do this with OCON_ISID)

Variables have been namespaced and there is no more overlap with
OCON_ISID.

> Also we are relying on having the same number of OCON's which isn't good 
> I don't think. As much as I hate the policydb_compat_info (read: alot) 
> why aren't we using that to say how many ocons a xen policy really has?

OCON_NUM is now dynamically read through policydb_compat_info.


> This is messy, why not an ocontext_selinux_free() and 
> ocontext_xen_free() (note: I realize the xen_free() one won't do 
> anything except freep the ocontext_t)
> 

done.

> >
> >   	len = buf[1];
> > -	if (len != strlen(target_str)&&
> > -	    (!alt_target_str || len != strlen(alt_target_str))) {
> > -		ERR(fp->handle, "policydb string length %zu does not match "
> > -		    "expected length %zu", len, strlen(target_str));
> > +	if (len>  32) {
> >    
> 
> magic number 32?

#defined.

Thanks for your input.  Below is the updated patch for libsepol.  

----

 libsepol/include/sepol/policydb/policydb.h |   28 ++
 libsepol/src/expand.c                      |   85 +++++++-
 libsepol/src/policydb.c                    |  295
+++++++++++++++++++++++------
 libsepol/src/policydb_internal.h           |    1
 libsepol/src/private.h                     |    4
 libsepol/src/write.c                       |   93 ++++++++-
 6 files changed, 443 insertions(+), 63 deletions(-)

diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h
index 0105cf4..e8991e2 100644
--- a/libsepol/include/sepol/policydb/policydb.h
+++ b/libsepol/include/sepol/policydb/policydb.h
@@ -276,6 +276,16 @@ typedef struct ocontext {
 			uint32_t addr[4]; /* network order */
 			uint32_t mask[4]; /* network order */
 		} node6;	/* IPv6 node information */
+		uint32_t device;
+		uint16_t pirq;
+		struct {
+			uint32_t low_iomem;
+			uint32_t high_iomem;
+		} iomem;
+		struct {
+			uint32_t low_ioport;
+			uint32_t high_ioport;
+		} ioport;
 	} u;
 	union {
 		uint32_t sclass;	/* security class for genfs */
@@ -311,6 +321,16 @@ typedef struct genfs {
 #define OCON_NODE  4		/* nodes */
 #define OCON_FSUSE 5		/* fs_use */
 #define OCON_NODE6 6		/* IPv6 nodes */
+#define OCON_GENFS 7            /* needed for ocontext_supported */
+
+/* object context array indices for Xen */
+#define OCON_XEN_ISID  	    0    /* initial SIDs */
+#define OCON_XEN_PIRQ       1    /* physical irqs */
+#define OCON_XEN_IOPORT     2    /* io ports */
+#define OCON_XEN_IOMEM	    3    /* io memory */
+#define OCON_XEN_PCIDEVICE  4    /* pci devices */
+
+/* OCON_NUM needs to be the largest index in any platform's ocontext array */
 #define OCON_NUM   7
 
 /* section: module information */
@@ -400,6 +420,7 @@ typedef struct policydb {
 	uint32_t policy_type;
 	char *name;
 	char *version;
+	int  target_platform;
 
 	/* Set when the policydb is modified such that writing is unsupported */
 	int unsupported_format;
@@ -593,6 +614,7 @@ extern int avrule_read_list(policydb_t * p, avrule_t ** avrules,
 			    struct policy_file *fp);
 
 extern int policydb_write(struct policydb *p, struct policy_file *pf);
+extern int policydb_set_target_platform(policydb_t *p, int platform);
 
 #define PERM_SYMTAB_SIZE 32
 
@@ -651,9 +673,13 @@ extern int policydb_write(struct policydb *p, struct policy_file *pf);
 
 #define POLICYDB_MAGIC SELINUX_MAGIC
 #define POLICYDB_STRING "SE Linux"
-#define POLICYDB_ALT_STRING "Flask"
+#define POLICYDB_XEN_STRING "XenFlask"
+#define POLICYDB_STRING_MAX_LENGTH 32
 #define POLICYDB_MOD_MAGIC SELINUX_MOD_MAGIC
 #define POLICYDB_MOD_STRING "SE Linux Module"
+#define SEPOL_TARGET_SELINUX 0
+#define SEPOL_TARGET_XEN     1
+
 
 #endif				/* _POLICYDB_H_ */
 
diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
index e9cd986..16d6bcb 100644
--- a/libsepol/src/expand.c
+++ b/libsepol/src/expand.c
@@ -1819,9 +1819,9 @@ static int context_copy(context_struct_t * dst, context_struct_t * src,
 	return mls_context_cpy(dst, src);
 }
 
-static int ocontext_copy(expand_state_t * state)
+static int ocontext_copy_xen(expand_state_t *state)
 {
-	unsigned int i, j;
+	unsigned int i;
 	ocontext_t *c, *n, *l;
 
 	for (i = 0; i < OCON_NUM; i++) {
@@ -1833,11 +1833,63 @@ static int ocontext_copy(expand_state_t * state)
 				return -1;
 			}
 			memset(n, 0, sizeof(ocontext_t));
-			if (l) {
+			if (l)
 				l->next = n;
-			} else {
+			else
 				state->out->ocontexts[i] = n;
+			l = n;
+			if (context_copy(&n->context[0], &c->context[0],
+				state)) {
+				ERR(state->handle, "Out of memory!");
+				return -1;
 			}
+			switch (i) {
+			case OCON_XEN_ISID:
+				n->sid[0] = c->sid[0];
+				break;
+			case OCON_XEN_PIRQ:
+				n->u.pirq = c->u.pirq;
+				break;
+			case OCON_XEN_IOPORT:
+				n->u.ioport.low_ioport = c->u.ioport.low_ioport;
+				n->u.ioport.high_ioport =
+					c->u.ioport.high_ioport;
+				break;
+			case OCON_XEN_IOMEM:
+				n->u.iomem.low_iomem  = c->u.iomem.low_iomem;
+				n->u.iomem.high_iomem = c->u.iomem.high_iomem;
+				break;
+			case OCON_XEN_PCIDEVICE:
+				n->u.device = c->u.device;
+				break;
+			default:
+				/* shouldn't get here */
+				ERR(state->handle, "Unknown ocontext");
+				return -1;
+			}
+		}
+	}
+	return 0;
+}
+
+static int ocontext_copy_selinux(expand_state_t *state)
+{
+	unsigned int i, j;
+	ocontext_t *c, *n, *l;
+
+	for (i = 0; i < OCON_NUM; i++) {
+		l = NULL;
+		for (c = state->base->ocontexts[i]; c; c = c->next) {
+			n = malloc(sizeof(ocontext_t));
+			if (!n) {
+				ERR(state->handle, "Out of memory!");
+				return -1;
+			}
+			memset(n, 0, sizeof(ocontext_t));
+			if (l)
+				l->next = n;
+			else
+				state->out->ocontexts[i] = n;
 			l = n;
 			if (context_copy(&n->context[0], &c->context[0], state)) {
 				ERR(state->handle, "Out of memory!");
@@ -1885,13 +1937,31 @@ static int ocontext_copy(expand_state_t * state)
 				break;
 			default:
 				/* shouldn't get here */
-				assert(0);
+				ERR(state->handle, "Unknown ocontext");
+				return -1;
 			}
 		}
 	}
 	return 0;
 }
 
+static int ocontext_copy(expand_state_t *state, uint32_t target)
+{
+	int rc = -1;
+	switch (target) {
+	case SEPOL_TARGET_SELINUX:
+		rc = ocontext_copy_selinux(state);
+		break;
+	case SEPOL_TARGET_XEN:
+		rc = ocontext_copy_xen(state);
+		break;
+	default:
+		ERR(state->handle, "Unknown target");
+		return -1;
+	}
+	return rc;
+}
+
 static int genfs_copy(expand_state_t * state)
 {
 	ocontext_t *c, *newc, *l;
@@ -2418,6 +2488,9 @@ int expand_module(sepol_handle_t * handle,
 	out->mls = base->mls;
 	out->handle_unknown = base->handle_unknown;
 
+	/* Copy target from base to out */
+	out->target_platform = base->target_platform;
+
 	/* Copy policy capabilities */
 	if (ebitmap_cpy(&out->policycaps, &base->policycaps)) {
 		ERR(handle, "Out of memory!");
@@ -2576,7 +2649,7 @@ int expand_module(sepol_handle_t * handle,
 	evaluate_conds(state.out);
 
 	/* copy ocontexts */
-	if (ocontext_copy(&state))
+	if (ocontext_copy(&state, out->target_platform))
 		goto cleanup;
 
 	/* copy genfs */
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index 85ddefc..dae05d3 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -54,151 +54,185 @@
 #include "debug.h"
 #include "mls.h"
 
+#define POLICYDB_TARGET_SZ   ARRAY_SIZE(policydb_target_strings)
+char *policydb_target_strings[] = { POLICYDB_STRING, POLICYDB_XEN_STRING };
+
 /* These need to be updated if SYM_NUM or OCON_NUM changes */
 static struct policydb_compat_info policydb_compat[] = {
 	{
 	 .type = POLICY_KERN,
+	 .version = POLICYDB_VERSION_BOUNDARY,
+	 .sym_num = SYM_NUM,
+	 .ocon_num = OCON_XEN_PCIDEVICE + 1,
+	 .target_platform = SEPOL_TARGET_XEN,
+	 },
+	{
+	 .type = POLICY_KERN,
 	 .version = POLICYDB_VERSION_BASE,
 	 .sym_num = SYM_NUM - 3,
 	 .ocon_num = OCON_FSUSE + 1,
+	 .target_platform = SEPOL_TARGET_SELINUX,
 	 },
 	{
 	 .type = POLICY_KERN,
 	 .version = POLICYDB_VERSION_BOOL,
 	 .sym_num = SYM_NUM - 2,
 	 .ocon_num = OCON_FSUSE + 1,
+	 .target_platform = SEPOL_TARGET_SELINUX,
 	 },
 	{
 	 .type = POLICY_KERN,
 	 .version = POLICYDB_VERSION_IPV6,
 	 .sym_num = SYM_NUM - 2,
 	 .ocon_num = OCON_NODE6 + 1,
+	 .target_platform = SEPOL_TARGET_SELINUX,
 	 },
 	{
 	 .type = POLICY_KERN,
 	 .version = POLICYDB_VERSION_NLCLASS,
 	 .sym_num = SYM_NUM - 2,
 	 .ocon_num = OCON_NODE6 + 1,
+	 .target_platform = SEPOL_TARGET_SELINUX,
 	 },
 	{
 	 .type = POLICY_KERN,
 	 .version = POLICYDB_VERSION_MLS,
 	 .sym_num = SYM_NUM,
 	 .ocon_num = OCON_NODE6 + 1,
+	 .target_platform = SEPOL_TARGET_SELINUX,
 	 },
 	{
 	 .type = POLICY_KERN,
 	 .version = POLICYDB_VERSION_AVTAB,
 	 .sym_num = SYM_NUM,
 	 .ocon_num = OCON_NODE6 + 1,
+	 .target_platform = SEPOL_TARGET_SELINUX,
 	 },
 	{
 	 .type = POLICY_KERN,
 	 .version = POLICYDB_VERSION_RANGETRANS,
 	 .sym_num = SYM_NUM,
 	 .ocon_num = OCON_NODE6 + 1,
+	 .target_platform = SEPOL_TARGET_SELINUX,
 	 },
 	{
 	 .type = POLICY_KERN,
 	 .version = POLICYDB_VERSION_POLCAP,
 	 .sym_num = SYM_NUM,
 	 .ocon_num = OCON_NODE6 + 1,
+	 .target_platform = SEPOL_TARGET_SELINUX,
 	 },
 	{
 	 .type = POLICY_KERN,
 	 .version = POLICYDB_VERSION_PERMISSIVE,
 	 .sym_num = SYM_NUM,
 	 .ocon_num = OCON_NODE6 + 1,
+	 .target_platform = SEPOL_TARGET_SELINUX,
 	 },
         {
 	 .type = POLICY_KERN,
 	 .version = POLICYDB_VERSION_BOUNDARY,
 	 .sym_num = SYM_NUM,
 	 .ocon_num = OCON_NODE6 + 1,
+	 .target_platform = SEPOL_TARGET_SELINUX,
 	},
 	{
 	 .type = POLICY_BASE,
 	 .version = MOD_POLICYDB_VERSION_BASE,
 	 .sym_num = SYM_NUM,
 	 .ocon_num = OCON_NODE6 + 1,
+	 .target_platform = SEPOL_TARGET_SELINUX,
 	 },
 	{
 	 .type = POLICY_BASE,
 	 .version = MOD_POLICYDB_VERSION_MLS,
 	 .sym_num = SYM_NUM,
 	 .ocon_num = OCON_NODE6 + 1,
+	 .target_platform = SEPOL_TARGET_SELINUX,
 	 },
 	{
 	 .type = POLICY_BASE,
 	 .version = MOD_POLICYDB_VERSION_MLS_USERS,
 	 .sym_num = SYM_NUM,
 	 .ocon_num = OCON_NODE6 + 1,
+	 .target_platform = SEPOL_TARGET_SELINUX,
 	 },
 	{
 	 .type = POLICY_BASE,
 	 .version = MOD_POLICYDB_VERSION_POLCAP,
 	 .sym_num = SYM_NUM,
 	 .ocon_num = OCON_NODE6 + 1,
+	 .target_platform = SEPOL_TARGET_SELINUX,
 	 },
 	{
 	 .type = POLICY_BASE,
 	 .version = MOD_POLICYDB_VERSION_PERMISSIVE,
 	 .sym_num = SYM_NUM,
 	 .ocon_num = OCON_NODE6 + 1,
+	 .target_platform = SEPOL_TARGET_SELINUX,
 	 },
 	{
 	 .type = POLICY_BASE,
 	 .version = MOD_POLICYDB_VERSION_BOUNDARY,
 	 .sym_num = SYM_NUM,
 	 .ocon_num = OCON_NODE6 + 1,
+	 .target_platform = SEPOL_TARGET_SELINUX,
 	},
 	{
 	 .type = POLICY_BASE,
 	 .version = MOD_POLICYDB_VERSION_BOUNDARY_ALIAS,
 	 .sym_num = SYM_NUM,
 	 .ocon_num = OCON_NODE6 + 1,
+	 .target_platform = SEPOL_TARGET_SELINUX,
 	},
 	{
 	 .type = POLICY_MOD,
 	 .version = MOD_POLICYDB_VERSION_BASE,
 	 .sym_num = SYM_NUM,
 	 .ocon_num = 0,
+	 .target_platform = SEPOL_TARGET_SELINUX,
 	 },
 	{
 	 .type = POLICY_MOD,
 	 .version = MOD_POLICYDB_VERSION_MLS,
 	 .sym_num = SYM_NUM,
 	 .ocon_num = 0,
+	 .target_platform = SEPOL_TARGET_SELINUX,
 	 },
 	{
 	 .type = POLICY_MOD,
 	 .version = MOD_POLICYDB_VERSION_MLS_USERS,
 	 .sym_num = SYM_NUM,
-	 .ocon_num = 0
+	 .ocon_num = 0,
+	 .target_platform = SEPOL_TARGET_SELINUX,
 	 },
 	{
 	 .type = POLICY_MOD,
 	 .version = MOD_POLICYDB_VERSION_POLCAP,
 	 .sym_num = SYM_NUM,
-	 .ocon_num = 0
+	 .ocon_num = 0,
+	 .target_platform = SEPOL_TARGET_SELINUX,
 	 },
 	{
 	 .type = POLICY_MOD,
 	 .version = MOD_POLICYDB_VERSION_PERMISSIVE,
 	 .sym_num = SYM_NUM,
-	 .ocon_num = 0
+	 .ocon_num = 0,
+	 .target_platform = SEPOL_TARGET_SELINUX,
 	 },
 	{
 	 .type = POLICY_MOD,
 	 .version = MOD_POLICYDB_VERSION_BOUNDARY,
 	 .sym_num = SYM_NUM,
-	 .ocon_num = 0
+	 .ocon_num = 0,
+	 .target_platform = SEPOL_TARGET_SELINUX,
 	},
 	{
 	 .type = POLICY_MOD,
 	 .version = MOD_POLICYDB_VERSION_BOUNDARY_ALIAS,
 	 .sym_num = SYM_NUM,
-	 .ocon_num = 0
+	 .ocon_num = 0,
+	 .target_platform = SEPOL_TARGET_SELINUX,
 	},
 };
 
@@ -225,14 +259,16 @@ static unsigned int symtab_sizes[SYM_NUM] = {
 };
 
 struct policydb_compat_info *policydb_lookup_compat(unsigned int version,
-						    unsigned int type)
+						    unsigned int type,
+						unsigned int target_platform)
 {
 	unsigned int i;
 	struct policydb_compat_info *info = NULL;
 
 	for (i = 0; i < sizeof(policydb_compat) / sizeof(*info); i++) {
 		if (policydb_compat[i].version == version &&
-		    policydb_compat[i].type == type) {
+		    policydb_compat[i].type == type &&
+		    policydb_compat[i].target_platform == target_platform) {
 			info = &policydb_compat[i];
 			break;
 		}
@@ -1026,6 +1062,45 @@ static int (*destroy_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum,
 common_destroy, class_destroy, role_destroy, type_destroy, user_destroy,
 	    cond_destroy_bool, sens_destroy, cat_destroy,};
 
+void ocontext_selinux_free(ocontext_t **ocontexts)
+{
+	ocontext_t *c, *ctmp;
+	int i;
+
+	for (i = 0; i < OCON_NUM; i++) {
+		c = ocontexts[i];
+		while (c) {
+			ctmp = c;
+			c = c->next;
+			context_destroy(&ctmp->context[0]);
+			context_destroy(&ctmp->context[1]);
+			if (i == OCON_ISID || i == OCON_FS || i == OCON_NETIF
+				|| i == OCON_FSUSE)
+				free(ctmp->u.name);
+			free(ctmp);
+		}
+	}
+}
+
+void ocontext_xen_free(ocontext_t **ocontexts)
+{
+	ocontext_t *c, *ctmp;
+	int i;
+
+	for (i = 0; i < OCON_NUM; i++) {
+		c = ocontexts[i];
+		while (c) {
+			ctmp = c;
+			c = c->next;
+			context_destroy(&ctmp->context[0]);
+			context_destroy(&ctmp->context[1]);
+			if (i == OCON_ISID)
+				free(ctmp->u.name);
+			free(ctmp);
+		}
+	}
+}
+
 /*
  * Free any memory allocated by a policy database structure.
  */
@@ -1072,19 +1147,10 @@ void policydb_destroy(policydb_t * p)
 
 	avtab_destroy(&p->te_avtab);
 
-	for (i = 0; i < OCON_NUM; i++) {
-		c = p->ocontexts[i];
-		while (c) {
-			ctmp = c;
-			c = c->next;
-			context_destroy(&ctmp->context[0]);
-			context_destroy(&ctmp->context[1]);
-			if (i == OCON_ISID || i == OCON_FS || i == OCON_NETIF
-			    || i == OCON_FSUSE)
-				free(ctmp->u.name);
-			free(ctmp);
-		}
-	}
+	if (p->target_platform == SEPOL_TARGET_SELINUX)
+		ocontext_selinux_free(p->ocontexts);
+	else if (p->target_platform == SEPOL_TARGET_XEN)
+		ocontext_xen_free(p->ocontexts);
 
 	g = p->genfs;
 	while (g) {
@@ -2102,7 +2168,88 @@ int role_allow_read(role_allow_t ** r, struct policy_file *fp)
 	return 0;
 }
 
-static int ocontext_read(struct policydb_compat_info *info,
+static int ocontext_read_xen(struct policydb_compat_info *info,
+	policydb_t *p, struct policy_file *fp)
+{
+	unsigned int i, j;
+	size_t nel;
+	ocontext_t *l, *c;
+	uint32_t buf[8];
+	int rc;
+
+	for (i = 0; i < info->ocon_num; i++) {
+		rc = next_entry(buf, fp, sizeof(uint32_t));
+		if (rc < 0)
+			return -1;
+		nel = le32_to_cpu(buf[0]);
+		l = NULL;
+		for (j = 0; j < nel; j++) {
+			c = calloc(1, sizeof(ocontext_t));
+			if (!c)
+				return -1;
+			if (l)
+				l->next = c;
+			else
+				p->ocontexts[i] = c;
+			l = c;
+			switch (i) {
+			case OCON_XEN_ISID:
+				rc = next_entry(buf, fp, sizeof(uint32_t));
+				if (rc < 0)
+					return -1;
+				c->sid[0] = le32_to_cpu(buf[0]);
+				if (context_read_and_validate
+				    (&c->context[0], p, fp))
+					return -1;
+				break;
+			case OCON_XEN_PIRQ:
+				rc = next_entry(buf, fp, sizeof(uint32_t));
+				if (rc < 0)
+					return -1;
+				c->u.pirq = le32_to_cpu(buf[0]);
+				if (context_read_and_validate
+				    (&c->context[0], p, fp))
+					return -1;
+				break;
+			case OCON_XEN_IOPORT:
+				rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
+				if (rc < 0)
+					return -1;
+				c->u.ioport.low_ioport = le32_to_cpu(buf[0]);
+				c->u.ioport.high_ioport = le32_to_cpu(buf[1]);
+				if (context_read_and_validate
+				    (&c->context[0], p, fp))
+					return -1;
+				break;
+			case OCON_XEN_IOMEM:
+				rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
+				if (rc < 0)
+					return -1;
+				c->u.iomem.low_iomem = le32_to_cpu(buf[0]);
+				c->u.iomem.high_iomem = le32_to_cpu(buf[1]);
+				if (context_read_and_validate
+				    (&c->context[0], p, fp))
+					return -1;
+				break;
+			case OCON_XEN_PCIDEVICE:
+				rc = next_entry(buf, fp, sizeof(uint32_t));
+				if (rc < 0)
+					return -1;
+				c->u.device = le32_to_cpu(buf[0]);
+				if (context_read_and_validate
+				    (&c->context[0], p, fp))
+					return -1;
+				break;
+			default:
+				/* should never get here */
+				ERR(fp->handle, "Unknown Xen ocontext");
+				return -1;
+			}
+		}
+	}
+	return 0;
+}
+static int ocontext_read_selinux(struct policydb_compat_info *info,
 			 policydb_t * p, struct policy_file *fp)
 {
 	unsigned int i, j;
@@ -2197,23 +2344,25 @@ static int ocontext_read(struct policydb_compat_info *info,
 					return -1;
 				break;
 			case OCON_NODE6:{
-					int k;
-
-					rc = next_entry(buf, fp,
-							sizeof(uint32_t) * 8);
-					if (rc < 0)
-						return -1;
-					for (k = 0; k < 4; k++)
-						c->u.node6.addr[k] = buf[k]; /* network order */
-					for (k = 0; k < 4; k++)
-						c->u.node6.mask[k] = buf[k + 4]; /* network order */
-					if (context_read_and_validate
-					    (&c->context[0], p, fp))
-						return -1;
-					break;
+				int k;
+
+				rc = next_entry(buf, fp, sizeof(uint32_t) * 8);
+				if (rc < 0)
+					return -1;
+				for (k = 0; k < 4; k++)
+					 /* network order */
+					c->u.node6.addr[k] = buf[k];
+				for (k = 0; k < 4; k++)
+					/* network order */
+					c->u.node6.mask[k] = buf[k + 4];
+				if (context_read_and_validate
+				    (&c->context[0], p, fp))
+					return -1;
+				break;
 				}
 			default:{
-					assert(0);	/* should never get here */
+				ERR(fp->handle, "Unknown SELinux ocontext");
+				return -1;
 				}
 			}
 		}
@@ -2221,6 +2370,23 @@ static int ocontext_read(struct policydb_compat_info *info,
 	return 0;
 }
 
+static int ocontext_read(struct policydb_compat_info *info,
+	policydb_t *p, struct policy_file *fp)
+{
+	int rc = -1;
+	switch (p->target_platform) {
+	case SEPOL_TARGET_SELINUX:
+		rc = ocontext_read_selinux(info, p, fp);
+		break;
+	case SEPOL_TARGET_XEN:
+		rc = ocontext_read_xen(info, p, fp);
+		break;
+	default:
+		ERR(fp->handle, "Unknown target");
+	}
+	return rc;
+}
+
 static int genfs_read(policydb_t * p, struct policy_file *fp)
 {
 	uint32_t buf[1];
@@ -3070,7 +3236,7 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose)
 	unsigned int i, j, r_policyvers;
 	uint32_t buf[5], config;
 	size_t len, nprim, nel;
-	char *policydb_str, *target_str = NULL, *alt_target_str = NULL;
+	char *policydb_str;
 	struct policydb_compat_info *info;
 	unsigned int policy_type, bufindex;
 	ebitmap_node_t *tnode;
@@ -3087,11 +3253,8 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose)
 
 	if (buf[0] == POLICYDB_MAGIC) {
 		policy_type = POLICY_KERN;
-		target_str = POLICYDB_STRING;
-		alt_target_str = POLICYDB_ALT_STRING;
 	} else if (buf[0] == POLICYDB_MOD_MAGIC) {
 		policy_type = POLICY_MOD;
-		target_str = POLICYDB_MOD_STRING;
 	} else {
 		ERR(fp->handle, "policydb magic number %#08x does not "
 		    "match expected magic number %#08x or %#08x",
@@ -3100,10 +3263,8 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose)
 	}
 
 	len = buf[1];
-	if (len != strlen(target_str) &&
-	    (!alt_target_str || len != strlen(alt_target_str))) {
-		ERR(fp->handle, "policydb string length %zu does not match "
-		    "expected length %zu", len, strlen(target_str));
+	if (len > POLICYDB_STRING_MAX_LENGTH) {
+		ERR(fp->handle, "policydb string length too long ");
 		return POLICYDB_ERROR;
 	}
 
@@ -3120,13 +3281,31 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose)
 		return POLICYDB_ERROR;
 	}
 	policydb_str[len] = 0;
-	if (strcmp(policydb_str, target_str) &&
-	    (!alt_target_str || strcmp(policydb_str, alt_target_str))) {
-		ERR(fp->handle, "policydb string %s does not match "
-		    "my string %s", policydb_str, target_str);
-		free(policydb_str);
-		return POLICYDB_ERROR;
+
+	if (policy_type == POLICY_KERN) {
+		for (i = 0; i < POLICYDB_TARGET_SZ; i++) {
+			if ((strcmp(policydb_str, policydb_target_strings[i])
+				== 0)) {
+				policydb_set_target_platform(p, i);
+				break;
+			}
+		}
+
+		if (i == POLICYDB_TARGET_SZ) {
+			ERR(fp->handle, "cannot find a valid target for policy "
+				"string %s", policydb_str);
+			free(policydb_str);
+			return POLICYDB_ERROR;
+		}
+	} else {
+		if (strcmp(policydb_str, POLICYDB_MOD_STRING)) {
+			ERR(fp->handle, "invalid string identifier %s",
+				policydb_str);
+			free(policydb_str);
+			return POLICYDB_ERROR;
+		}
 	}
+
 	/* Done with policydb_str. */
 	free(policydb_str);
 	policydb_str = NULL;
@@ -3195,7 +3374,8 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose)
 
 	bufindex++;
 
-	info = policydb_lookup_compat(r_policyvers, policy_type);
+	info = policydb_lookup_compat(r_policyvers, policy_type,
+					p->target_platform);
 	if (!info) {
 		ERR(fp->handle, "unable to find policy compat info "
 		    "for version %d", r_policyvers);
@@ -3391,3 +3571,16 @@ void policy_file_init(policy_file_t *pf)
 {
 	memset(pf, 0, sizeof(policy_file_t));
 }
+
+int policydb_set_target_platform(policydb_t *p, int platform)
+{
+	if (platform == SEPOL_TARGET_SELINUX)
+		p->target_platform = SEPOL_TARGET_SELINUX;
+	else if (platform == SEPOL_TARGET_XEN)
+		p->target_platform = SEPOL_TARGET_XEN;
+	else
+		return -1;
+
+	return 0;
+}
+
diff --git a/libsepol/src/policydb_internal.h b/libsepol/src/policydb_internal.h
index 1eb99e5..8a31506 100644
--- a/libsepol/src/policydb_internal.h
+++ b/libsepol/src/policydb_internal.h
@@ -6,4 +6,5 @@
 
 hidden_proto(sepol_policydb_create)
     hidden_proto(sepol_policydb_free)
+extern char *policydb_target_strings[];
 #endif
diff --git a/libsepol/src/private.h b/libsepol/src/private.h
index 594f736..b2b247e 100644
--- a/libsepol/src/private.h
+++ b/libsepol/src/private.h
@@ -36,10 +36,12 @@ struct policydb_compat_info {
 	unsigned int version;
 	unsigned int sym_num;
 	unsigned int ocon_num;
+	unsigned int target_platform;
 };
 
 extern struct policydb_compat_info *policydb_lookup_compat(unsigned int version,
-							   unsigned int type);
+							   unsigned int type,
+						unsigned int target_platform);
 
 /* Reading from a policy "file". */
 extern int next_entry(void *buf, struct policy_file *fp, size_t bytes) hidden;
diff --git a/libsepol/src/write.c b/libsepol/src/write.c
index 66b35ec..9906e35 100644
--- a/libsepol/src/write.c
+++ b/libsepol/src/write.c
@@ -1084,10 +1084,79 @@ static int (*write_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum,
 common_write, class_write, role_write, type_write, user_write,
 	    cond_write_bool, sens_write, cat_write,};
 
-static int ocontext_write(struct policydb_compat_info *info, policydb_t * p,
+static int ocontext_write_xen(struct policydb_compat_info *info, policydb_t *p,
 			  struct policy_file *fp)
 {
 	unsigned int i, j;
+	size_t nel, items;
+	uint32_t buf[32];
+	ocontext_t *c;
+	for (i = 0; i < info->ocon_num; i++) {
+		nel = 0;
+		for (c = p->ocontexts[i]; c; c = c->next)
+			nel++;
+		buf[0] = cpu_to_le32(nel);
+		items = put_entry(buf, sizeof(uint32_t), 1, fp);
+		if (items != 1)
+			return POLICYDB_ERROR;
+		for (c = p->ocontexts[i]; c; c = c->next) {
+			switch (i) {
+			case OCON_XEN_ISID:
+				buf[0] = cpu_to_le32(c->sid[0]);
+				items = put_entry(buf, sizeof(uint32_t), 1, fp);
+				if (items != 1)
+					return POLICYDB_ERROR;
+				if (context_write(p, &c->context[0], fp))
+					return POLICYDB_ERROR;
+				break;
+			case OCON_XEN_PIRQ:
+				buf[0] = cpu_to_le32(c->u.pirq);
+				items = put_entry(buf, sizeof(uint32_t), 1, fp);
+				if (items != 1)
+					return POLICYDB_ERROR;
+				if (context_write(p, &c->context[0], fp))
+					return POLICYDB_ERROR;
+				break;
+			case OCON_XEN_IOPORT:
+				buf[0] = c->u.ioport.low_ioport;
+				buf[1] = c->u.ioport.high_ioport;
+				for (j = 0; j < 2; j++)
+					buf[j] = cpu_to_le32(buf[j]);
+				items = put_entry(buf, sizeof(uint32_t), 2, fp);
+				if (items != 2)
+					return POLICYDB_ERROR;
+				if (context_write(p, &c->context[0], fp))
+					return POLICYDB_ERROR;
+				break;
+			case OCON_XEN_IOMEM:
+				buf[0] = c->u.iomem.low_iomem;
+				buf[1] = c->u.iomem.high_iomem;
+				for (j = 0; j < 2; j++)
+					buf[j] = cpu_to_le32(buf[j]);
+				items = put_entry(buf, sizeof(uint32_t), 2, fp);
+				if (items != 2)
+					return POLICYDB_ERROR;
+				if (context_write(p, &c->context[0], fp))
+					return POLICYDB_ERROR;
+				break;
+			case OCON_XEN_PCIDEVICE:
+				buf[0] = cpu_to_le32(c->u.device);
+				items = put_entry(buf, sizeof(uint32_t), 1, fp);
+				if (items != 1)
+					return POLICYDB_ERROR;
+				if (context_write(p, &c->context[0], fp))
+					return POLICYDB_ERROR;
+				break;
+			}
+		}
+	}
+	return POLICYDB_SUCCESS;
+}
+
+static int ocontext_write_selinux(struct policydb_compat_info *info,
+	policydb_t *p, struct policy_file *fp)
+{
+	unsigned int i, j;
 	size_t nel, items, len;
 	uint32_t buf[32];
 	ocontext_t *c;
@@ -1176,6 +1245,21 @@ static int ocontext_write(struct policydb_compat_info *info, policydb_t * p,
 	return POLICYDB_SUCCESS;
 }
 
+static int ocontext_write(struct policydb_compat_info *info, policydb_t * p,
+	struct policy_file *fp)
+{
+	int rc = POLICYDB_ERROR;
+	switch (p->target_platform) {
+	case SEPOL_TARGET_SELINUX:
+		rc = ocontext_write_selinux(info, p, fp);
+		break;
+	case SEPOL_TARGET_XEN:
+		rc = ocontext_write_xen(info, p, fp);
+		break;
+	}
+	return rc;
+}
+
 static int genfs_write(policydb_t * p, struct policy_file *fp)
 {
 	genfs_t *genfs;
@@ -1610,8 +1694,8 @@ int policydb_write(policydb_t * p, struct policy_file *fp)
 	items = 0;
 	if (p->policy_type == POLICY_KERN) {
 		buf[items++] = cpu_to_le32(POLICYDB_MAGIC);
-		len = strlen(POLICYDB_STRING);
-		policydb_str = POLICYDB_STRING;
+		len = strlen(policydb_target_strings[p->target_platform]);
+		policydb_str = policydb_target_strings[p->target_platform];
 	} else {
 		buf[items++] = cpu_to_le32(POLICYDB_MOD_MAGIC);
 		len = strlen(POLICYDB_MOD_STRING);
@@ -1627,7 +1711,8 @@ int policydb_write(policydb_t * p, struct policy_file *fp)
 
 	/* Write the version, config, and table sizes. */
 	items = 0;
-	info = policydb_lookup_compat(p->policyvers, p->policy_type);
+	info = policydb_lookup_compat(p->policyvers, p->policy_type,
+					p->target_platform);
 	if (!info) {
 		ERR(fp->handle, "compatibility lookup failed for policy "
 		    "version %d", p->policyvers);


--
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 related	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/3] checkpolicy: Add support for multiple target OSes
  2009-09-15 16:37 ` [PATCH 2/3] checkpolicy: " pjnuzzi
  2009-09-15 16:40   ` [PATCH 3/3] sepolgen: " pjnuzzi
@ 2009-09-29 14:06   ` Paul Nuzzi
  1 sibling, 0 replies; 13+ messages in thread
From: Paul Nuzzi @ 2009-09-29 14:06 UTC (permalink / raw)
  To: selinux; +Cc: Stephen Smalley

Updated patch of checkpolicy based on input.

On Tue, 2009-09-15 at 12:37 -0400, pjnuzzi wrote:
> Add support for multiple target OSes by adding the -t target option to
> checkpolicy.  Implemented the new Xen ocontext identifiers pirqcon,
> pcidevicecon, iomemcon and ioportcon.  
> 
> Signed-off-by: Paul Nuzzi <pjnuzzi@tycho.ncsc.mil>
> 
> ---

 checkpolicy/checkpolicy.c   |   20 ++-
 checkpolicy/policy_define.c |  272
++++++++++++++++++++++++++++++++++++++++++++
 checkpolicy/policy_define.h |    4
 checkpolicy/policy_parse.y  |   29 ++++
 checkpolicy/policy_scan.l   |   10 +
 5 files changed, 330 insertions(+), 5 deletions(-)

diff --git a/checkpolicy/checkpolicy.c b/checkpolicy/checkpolicy.c
index d7772d5..76d8ed3 100644
--- a/checkpolicy/checkpolicy.c
+++ b/checkpolicy/checkpolicy.c
@@ -100,7 +100,9 @@ unsigned int policyvers = POLICYDB_VERSION_MAX;
 void usage(char *progname)
 {
 	printf
-	    ("usage:  %s [-b] [-d] [-U handle_unknown (allow,deny,reject) [-M] [-c policyvers (%d-%d)] [-o output_file] [input_file]\n",
+	    ("usage:  %s [-b] [-d] [-U handle_unknown (allow,deny,reject) [-M]"
+	     "[-c policyvers (%d-%d)] [-o output_file] [-t platform]"
+	     "[input_file]\n",
 	     progname, POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
 	exit(1);
 }
@@ -381,7 +383,7 @@ int main(int argc, char **argv)
 	unsigned int protocol, port;
 	unsigned int binary = 0, debug = 0;
 	struct val_to_name v;
-	int ret, ch, fd;
+	int ret, ch, fd, target = SEPOL_TARGET_SELINUX;
 	unsigned int nel, uret;
 	struct stat sb;
 	void *map;
@@ -391,11 +393,22 @@ int main(int argc, char **argv)
 	int show_version = 0;
 	struct policy_file pf;
 
-	while ((ch = getopt(argc, argv, "o:dbU:MVc:")) != EOF) {
+	while ((ch = getopt(argc, argv, "o:t:dbU:MVc:")) != EOF) {
 		switch (ch) {
 		case 'o':
 			outfile = optarg;
 			break;
+		case 't':
+			if (!strcasecmp(optarg, "Xen"))
+				target = SEPOL_TARGET_XEN;
+			else if (!strcasecmp(optarg, "SELinux"))
+				target = SEPOL_TARGET_SELINUX;
+			else{
+				fprintf(stderr, "%s:  Unknown target platform:"
+					"%s\n", argv[0], optarg);
+				exit(1);
+			}
+			break;
 		case 'b':
 			binary = 1;
 			file = binfile;
@@ -528,6 +541,7 @@ int main(int argc, char **argv)
 			exit(1);
 		/* We build this as a base policy first since that is all the parser understands */
 		parse_policy.policy_type = POLICY_BASE;
+		policydb_set_target_platform(&parse_policy, target);
 
 		/* Let sepol know if we are dealing with MLS support */
 		parse_policy.mls = mlspol;
diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c
index 17b84ce..a064307 100644
--- a/checkpolicy/policy_define.c
+++ b/checkpolicy/policy_define.c
@@ -3320,6 +3320,11 @@ int define_fs_context(unsigned int major, unsigned int minor)
 {
 	ocontext_t *newc, *c, *head;
 
+	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
+		yyerror("fscon not supported for target");
+		return -1;
+	}
+
 	if (pass == 1) {
 		parse_security_context(NULL);
 		parse_security_context(NULL);
@@ -3372,12 +3377,254 @@ int define_fs_context(unsigned int major, unsigned int minor)
 	return 0;
 }
 
+int define_pirq_context(unsigned int pirq)
+{
+	ocontext_t *newc, *c, *l, *head;
+	char *id;
+
+	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
+		yyerror("pirqcon not supported for target");
+		return -1;
+	}
+
+	if (pass == 1) {
+		id = (char *) queue_remove(id_queue);
+		free(id);
+		parse_security_context(NULL);
+		return 0;
+	}
+
+	newc = malloc(sizeof(ocontext_t));
+	if (!newc) {
+		yyerror("out of memory");
+		return -1;
+	}
+	memset(newc, 0, sizeof(ocontext_t));
+
+	newc->u.pirq = pirq;
+
+	if (parse_security_context(&newc->context[0])) {
+		free(newc);
+		return -1;
+	}
+
+	head = policydbp->ocontexts[OCON_XEN_PIRQ];
+	for (l = NULL, c = head; c; l = c, c = c->next) {
+		unsigned int pirq2;
+
+		pirq2 = c->u.pirq;
+		if (pirq == pirq2) {
+			yyerror2("duplicate pirqcon entry for %d ", pirq);
+			goto bad;
+		}
+	}
+
+	if (l)
+		l->next = newc;
+	else
+		policydbp->ocontexts[OCON_XEN_PIRQ] = newc;
+
+	return 0;
+
+bad:
+	free(newc);
+	return -1;
+}
+
+int define_iomem_context(unsigned long low, unsigned long high)
+{
+	ocontext_t *newc, *c, *l, *head;
+	char *id;
+
+	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
+		yyerror("iomemcon not supported for target");
+		return -1;
+	}
+
+	if (pass == 1) {
+		id = (char *)queue_remove(id_queue);
+		free(id);
+		parse_security_context(NULL);
+		return 0;
+	}
+
+	newc = malloc(sizeof(ocontext_t));
+	if (!newc) {
+		yyerror("out of memory");
+		return -1;
+	}
+	memset(newc, 0, sizeof(ocontext_t));
+
+	newc->u.iomem.low_iomem  = low;
+	newc->u.iomem.high_iomem = high;
+
+	if (low > high) {
+		yyerror2("low memory 0x%x exceeds high memory 0x%x", low, high);
+		free(newc);
+		return -1;
+	}
+
+	if (parse_security_context(&newc->context[0])) {
+		free(newc);
+		return -1;
+	}
+
+	head = policydbp->ocontexts[OCON_XEN_IOMEM];
+	for (l = NULL, c = head; c; l = c, c = c->next) {
+		unsigned int low2, high2;
+
+		low2 = c->u.iomem.low_iomem;
+		high2 = c->u.iomem.high_iomem;
+		if (low <= high2 && low2 <= high) {
+			yyerror2("iomemcon entry for 0x%x-0x%x overlaps with "
+				"earlier entry 0x%x-0x%x", low, high,
+				low2, high2);
+			goto bad;
+		}
+	}
+
+	if (l)
+		l->next = newc;
+	else
+		policydbp->ocontexts[OCON_XEN_IOMEM] = newc;
+
+	return 0;
+
+bad:
+	free(newc);
+	return -1;
+}
+
+int define_ioport_context(unsigned long low, unsigned long high)
+{
+	ocontext_t *newc, *c, *l, *head;
+	char *id;
+
+	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
+		yyerror("ioportcon not supported for target");
+		return -1;
+	}
+
+	if (pass == 1) {
+		id = (char *)queue_remove(id_queue);
+		free(id);
+		parse_security_context(NULL);
+		return 0;
+	}
+
+	newc = malloc(sizeof(ocontext_t));
+	if (!newc) {
+		yyerror("out of memory");
+		return -1;
+	}
+	memset(newc, 0, sizeof(ocontext_t));
+
+	newc->u.ioport.low_ioport  = low;
+	newc->u.ioport.high_ioport = high;
+
+	if (low > high) {
+		yyerror2("low ioport 0x%x exceeds high ioport 0x%x", low, high);
+		free(newc);
+		return -1;
+	}
+
+	if (parse_security_context(&newc->context[0])) {
+		free(newc);
+		return -1;
+	}
+
+	head = policydbp->ocontexts[OCON_XEN_IOPORT];
+	for (l = NULL, c = head; c; l = c, c = c->next) {
+		unsigned int low2, high2;
+
+		low2 = c->u.ioport.low_ioport;
+		high2 = c->u.ioport.high_ioport;
+		if (low <= high2 && low2 <= high) {
+			yyerror2("ioportcon entry for 0x%x-0x%x overlaps with"
+				"earlier entry 0x%x-0x%x", low, high,
+				low2, high2);
+			goto bad;
+		}
+	}
+
+	if (l)
+		l->next = newc;
+	else
+		policydbp->ocontexts[OCON_XEN_IOPORT] = newc;
+
+	return 0;
+
+bad:
+	free(newc);
+	return -1;
+}
+
+int define_pcidevice_context(unsigned long device)
+{
+	ocontext_t *newc, *c, *l, *head;
+	char *id;
+
+	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
+		yyerror("pcidevicecon not supported for target");
+		return -1;
+	}
+
+	if (pass == 1) {
+		id = (char *) queue_remove(id_queue);
+		free(id);
+		parse_security_context(NULL);
+		return 0;
+	}
+
+	newc = malloc(sizeof(ocontext_t));
+	if (!newc) {
+		yyerror("out of memory");
+		return -1;
+	}
+	memset(newc, 0, sizeof(ocontext_t));
+
+	newc->u.device = device;
+
+	if (parse_security_context(&newc->context[0])) {
+		free(newc);
+		return -1;
+	}
+
+	head = policydbp->ocontexts[OCON_XEN_PCIDEVICE];
+	for (l = NULL, c = head; c; l = c, c = c->next) {
+		unsigned int device2;
+
+		device2 = c->u.device;
+		if (device == device2) {
+			yyerror2("duplicate pcidevicecon entry for 0x%x ",
+				 device);
+			goto bad;
+		}
+	}
+
+	if (l)
+		l->next = newc;
+	else
+		policydbp->ocontexts[OCON_XEN_PCIDEVICE] = newc;
+
+	return 0;
+
+bad:
+	free(newc);
+	return -1;
+}
+
 int define_port_context(unsigned int low, unsigned int high)
 {
 	ocontext_t *newc, *c, *l, *head;
 	unsigned int protocol;
 	char *id;
 
+	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
+		yyerror("portcon not supported for target");
+		return -1;
+	}
+
 	if (pass == 1) {
 		id = (char *)queue_remove(id_queue);
 		free(id);
@@ -3460,6 +3707,11 @@ int define_netif_context(void)
 {
 	ocontext_t *newc, *c, *head;
 
+	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
+		yyerror("netifcon not supported for target");
+		return -1;
+	}
+
 	if (pass == 1) {
 		free(queue_remove(id_queue));
 		parse_security_context(NULL);
@@ -3516,6 +3768,11 @@ int define_ipv4_node_context()
 	struct in_addr addr, mask;
 	ocontext_t *newc, *c, *l, *head;
 
+	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
+		yyerror("nodecon not supported for target");
+		return -1;
+	}
+
 	if (pass == 1) {
 		free(queue_remove(id_queue));
 		free(queue_remove(id_queue));
@@ -3597,6 +3854,11 @@ int define_ipv6_node_context(void)
 	struct in6_addr addr, mask;
 	ocontext_t *newc, *c, *l, *head;
 
+	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
+		yyerror("nodecon not supported for target");
+		return -1;
+	}
+
 	if (pass == 1) {
 		free(queue_remove(id_queue));
 		free(queue_remove(id_queue));
@@ -3677,6 +3939,11 @@ int define_fs_use(int behavior)
 {
 	ocontext_t *newc, *c, *head;
 
+	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
+		yyerror("fsuse not supported for target");
+		return -1;
+	}
+
 	if (pass == 1) {
 		free(queue_remove(id_queue));
 		parse_security_context(NULL);
@@ -3727,6 +3994,11 @@ int define_genfs_context_helper(char *fstype, int has_type)
 	char *type = NULL;
 	int len, len2;
 
+	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
+		yyerror("genfs not supported for target");
+		return -1;
+	}
+
 	if (pass == 1) {
 		free(fstype);
 		free(queue_remove(id_queue));
diff --git a/checkpolicy/policy_define.h b/checkpolicy/policy_define.h
index b5a972e..5ac6667 100644
--- a/checkpolicy/policy_define.h
+++ b/checkpolicy/policy_define.h
@@ -39,6 +39,10 @@ int define_netif_context(void);
 int define_permissive(void);
 int define_polcap(void);
 int define_port_context(unsigned int low, unsigned int high);
+int define_pirq_context(unsigned int pirq);
+int define_iomem_context(unsigned long low, unsigned long high);
+int define_ioport_context(unsigned long low, unsigned long high);
+int define_pcidevice_context(unsigned long device);
 int define_range_trans(int class_specified);
 int define_role_allow(void);
 int define_role_trans(void);
diff --git a/checkpolicy/policy_parse.y b/checkpolicy/policy_parse.y
index 5ca7101..8d1bc37 100644
--- a/checkpolicy/policy_parse.y
+++ b/checkpolicy/policy_parse.y
@@ -123,6 +123,7 @@ typedef int (* require_func_t)();
 %token TARGET
 %token SAMEUSER
 %token FSCON PORTCON NETIFCON NODECON 
+%token PIRQCON IOMEMCON IOPORTCON PCIDEVICECON
 %token FSUSEXATTR FSUSETASK FSUSETRANS
 %token GENFSCON
 %token U1 U2 U3 R1 R2 R3 T1 T2 T3 L1 L2 H1 H2
@@ -154,7 +155,7 @@ base_policy             : { if (define_policy(pass, 0) == -1) return -1; }
 			  opt_mls te_rbac users opt_constraints 
                          { if (pass == 1) { if (policydb_index_bools(policydbp)) return -1;}
 			   else if (pass == 2) { if (policydb_index_others(NULL, policydbp, 0)) return -1;}}
-			  initial_sid_contexts opt_fs_contexts opt_fs_uses opt_genfs_contexts net_contexts 
+			  initial_sid_contexts opt_fs_contexts opt_fs_uses opt_genfs_contexts net_contexts opt_dev_contexts
 			;
 classes			: class_def 
 			| classes class_def
@@ -562,6 +563,32 @@ initial_sid_contexts	: initial_sid_context_def
 initial_sid_context_def	: SID identifier security_context_def
 			{if (define_initial_sid_context()) return -1;}
 			;
+opt_dev_contexts	: dev_contexts |
+			;
+dev_contexts		: dev_context_def
+			| dev_contexts dev_context_def
+			;
+dev_context_def		: pirq_context_def |
+			  iomem_context_def |
+			  ioport_context_def |
+			  pci_context_def
+			;
+pirq_context_def 	: PIRQCON number security_context_def
+		        {if (define_pirq_context($2)) return -1;}
+		        ;
+iomem_context_def	: IOMEMCON number security_context_def
+		        {if (define_iomem_context($2,$2)) return -1;}
+		        | IOMEMCON number '-' number security_context_def
+		        {if (define_iomem_context($2,$4)) return -1;}
+		        ;
+ioport_context_def	: IOPORTCON number security_context_def
+			{if (define_ioport_context($2,$2)) return -1;}
+			| IOPORTCON number '-' number security_context_def
+			{if (define_ioport_context($2,$4)) return -1;}
+			;
+pci_context_def  	: PCIDEVICECON number security_context_def
+		        {if (define_pcidevice_context($2)) return -1;}
+		        ;
 opt_fs_contexts         : fs_contexts 
                         |
                         ;
diff --git a/checkpolicy/policy_scan.l b/checkpolicy/policy_scan.l
index b55c659..48128a8 100644
--- a/checkpolicy/policy_scan.l
+++ b/checkpolicy/policy_scan.l
@@ -169,6 +169,14 @@ netifcon |
 NETIFCON			{ return(NETIFCON);}
 nodecon |                     
 NODECON				{ return(NODECON);}
+pirqcon |
+PIRQCON  		        { return(PIRQCON);}
+iomemcon |
+IOMEMCON            		{ return(IOMEMCON);}
+ioportcon |
+IOPORTCON           		{ return(IOPORTCON);}
+pcidevicecon |
+PCIDEVICECON           		{ return(PCIDEVICECON);}
 fs_use_xattr |
 FS_USE_XATTR			{ return(FSUSEXATTR);}
 fs_use_task |
@@ -209,7 +217,7 @@ permissive |
 PERMISSIVE			{ return(PERMISSIVE); }
 "/"({alnum}|[_\.\-/])*	        { return(PATH); }
 {letter}({alnum}|[_\-])*([\.]?({alnum}|[_\-]))*	{ return(IDENTIFIER); }
-{digit}+                        { return(NUMBER); }
+{digit}+|0x{hexval}+            { return(NUMBER); }
 {digit}{1,3}(\.{digit}{1,3}){3}    { return(IPV4_ADDR); }
 {hexval}{0,4}":"{hexval}{0,4}":"({hexval}|[:.])*  { return(IPV6_ADDR); }
 {digit}+(\.({alnum}|[_.])*)?    { return(VERSION_IDENTIFIER); }


--
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 related	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/3] libsepol: Add support for multiple target OSes
  2009-09-29 14:03   ` Paul Nuzzi
@ 2009-10-06 14:20     ` Joshua Brindle
  2009-10-07 17:37       ` Stephen Smalley
  2009-10-13 19:56     ` Joshua Brindle
  1 sibling, 1 reply; 13+ messages in thread
From: Joshua Brindle @ 2009-10-06 14:20 UTC (permalink / raw)
  To: Paul Nuzzi; +Cc: selinux, Stephen Smalley



Paul Nuzzi wrote:
> On Wed, 2009-09-16 at 09:58 -0400, Joshua Brindle wrote:
<snip>
> Thanks for your input.  Below is the updated patch for libsepol.
>

A quick look through looks good. I'd like to test it out a bit, do you 
have a Xen policy somewhere I can use for testing?

Also, I notice that this only lets you write out a "kernel" policy for 
Xen, but it might be beneficial to write out a base policy for testing, 
development, analysis, etc.

--
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] 13+ messages in thread

* Re: [PATCH 1/3] libsepol: Add support for multiple target OSes
  2009-10-06 14:20     ` Joshua Brindle
@ 2009-10-07 17:37       ` Stephen Smalley
  2009-10-07 18:48         ` Joshua Brindle
  0 siblings, 1 reply; 13+ messages in thread
From: Stephen Smalley @ 2009-10-07 17:37 UTC (permalink / raw)
  To: Joshua Brindle; +Cc: Paul Nuzzi, selinux

On Tue, 2009-10-06 at 10:20 -0400, Joshua Brindle wrote:
> 
> Paul Nuzzi wrote:
> > On Wed, 2009-09-16 at 09:58 -0400, Joshua Brindle wrote:
> <snip>
> > Thanks for your input.  Below is the updated patch for libsepol.
> >
> 
> A quick look through looks good. I'd like to test it out a bit, do you 
> have a Xen policy somewhere I can use for testing?
> 
> Also, I notice that this only lets you write out a "kernel" policy for 
> Xen, but it might be beneficial to write out a base policy for testing, 
> development, analysis, etc.

The Xen Flask policy lives in the xen-unstable tree; Paul has a patch to
update the Xen Flask module to support this new policy string identifier
and the new ocontext records and to update the policy there, but you'd
have to apply that patch to xen-unstable and build it.

In terms of base policy, if you mean modular base policy, we'd have to
introduce multiple string identifiers for it in the same way as the
kernel policy format, and I couldn't see the benefit of doing that when
the module format is going to be replaced in the not-too-distant future.
And what precisely is the benefit of writing a base policy vs. a kernel
policy now that policy.24 includes attribute names and preserves
attributes in allow rules (aside from certain cases, like type set
exclusion aka minus)?

-- 
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] 13+ messages in thread

* Re: [PATCH 1/3] libsepol: Add support for multiple target OSes
  2009-10-07 17:37       ` Stephen Smalley
@ 2009-10-07 18:48         ` Joshua Brindle
  0 siblings, 0 replies; 13+ messages in thread
From: Joshua Brindle @ 2009-10-07 18:48 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: Paul Nuzzi, selinux

Stephen Smalley wrote:
> On Tue, 2009-10-06 at 10:20 -0400, Joshua Brindle wrote:
>> Paul Nuzzi wrote:
>>> On Wed, 2009-09-16 at 09:58 -0400, Joshua Brindle wrote:
>> <snip>
>>> Thanks for your input.  Below is the updated patch for libsepol.
>>>
>> A quick look through looks good. I'd like to test it out a bit, do you
>> have a Xen policy somewhere I can use for testing?
>>
>> Also, I notice that this only lets you write out a "kernel" policy for
>> Xen, but it might be beneficial to write out a base policy for testing,
>> development, analysis, etc.
>
> The Xen Flask policy lives in the xen-unstable tree; Paul has a patch to
> update the Xen Flask module to support this new policy string identifier
> and the new ocontext records and to update the policy there, but you'd
> have to apply that patch to xen-unstable and build it.
>

I'll leave the Xen Flask Module part to you guys, I just wanted to build 
a Xen policy and do some poking around on it to see if it looks right.


> In terms of base policy, if you mean modular base policy, we'd have to
> introduce multiple string identifiers for it in the same way as the
> kernel policy format, and I couldn't see the benefit of doing that when
> the module format is going to be replaced in the not-too-distant future.
> And what precisely is the benefit of writing a base policy vs. a kernel
> policy now that policy.24 includes attribute names and preserves
> attributes in allow rules (aside from certain cases, like type set
> exclusion aka minus)?

That is fine, I was just thinking it is nicer to put a base module into 
setools than a kernel policy but there is a good chance that won't work 
anyway since setools won't know about the new ocontexts and might freak 
out (completely untested).

--
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] 13+ messages in thread

* Re: [PATCH 1/3] libsepol: Add support for multiple target OSes
  2009-09-29 14:03   ` Paul Nuzzi
  2009-10-06 14:20     ` Joshua Brindle
@ 2009-10-13 19:56     ` Joshua Brindle
  2009-10-14 19:38       ` Joshua Brindle
  1 sibling, 1 reply; 13+ messages in thread
From: Joshua Brindle @ 2009-10-13 19:56 UTC (permalink / raw)
  To: Paul Nuzzi; +Cc: selinux, Stephen Smalley

Paul Nuzzi wrote:
> On Wed, 2009-09-16 at 09:58 -0400, Joshua Brindle wrote:
>> I'd rather have separate ocontext structs for each system. That way it
>> is very easy to understand which ones apply to which system and you
>> don't get a crazy out of context ocontext struct.
>>
>
> I looked into having separate ocontext structs but that would involve
> changing a lot of files making the patch much larger and more intrusive.
>
>>>    	} u;
>>>    	union {
>>>    		uint32_t sclass;	/* security class for genfs */
>>> @@ -313,6 +323,17 @@ typedef struct genfs {
>>>    #define OCON_NODE6 6		/* IPv6 nodes */
>>>    #define OCON_NUM   7
>>>
>>> +/* object context array indices for Xen */
>>> +#define OCON_ISID    0    /* initial SIDs */
>>> +#define OCON_PIRQ    1    /* physical irqs */
>>> +#define OCON_IOPORT  2    /* io ports */
>>> +#define OCON_IOMEM   3    /* io memory */
>>> +#define OCON_DEVICE  4    /* pci devices */
>>> +#define OCON_DUMMY1  5    /* reserved */
>>> +#define OCON_DUMMY2  6    /* reserved */
>>> +#define OCON_NUM     7
>>> +
>>> +
>>>
>> Should these be namespaced? What if<random other system>  has io port
>> objects? You'd have to align them with each other and you have a mess of
>> keeping the numbers the same (you already do this with OCON_ISID)
>
> Variables have been namespaced and there is no more overlap with
> OCON_ISID.
>
>> Also we are relying on having the same number of OCON's which isn't good
>> I don't think. As much as I hate the policydb_compat_info (read: alot)
>> why aren't we using that to say how many ocons a xen policy really has?
>
> OCON_NUM is now dynamically read through policydb_compat_info.
>
>
>> This is messy, why not an ocontext_selinux_free() and
>> ocontext_xen_free() (note: I realize the xen_free() one won't do
>> anything except freep the ocontext_t)
>>
>
> done.
>
>>>    	len = buf[1];
>>> -	if (len != strlen(target_str)&&
>>> -	    (!alt_target_str || len != strlen(alt_target_str))) {
>>> -		ERR(fp->handle, "policydb string length %zu does not match "
>>> -		    "expected length %zu", len, strlen(target_str));
>>> +	if (len>   32) {
>>>
>> magic number 32?
>
> #defined.
>
> Thanks for your input.  Below is the updated patch for libsepol.
>

Acked-by: Joshua Brindle <method@manicmethod.com>

for the entire patchset with the following diff on top:

diff --git a/checkpolicy/checkpolicy.c b/checkpolicy/checkpolicy.c
index 76d8ed3..c5fdf19 100644
--- a/checkpolicy/checkpolicy.c
+++ b/checkpolicy/checkpolicy.c
@@ -100,8 +100,8 @@ unsigned int policyvers = POLICYDB_VERSION_MAX;
  void usage(char *progname)
  {
         printf
-           ("usage:  %s [-b] [-d] [-U handle_unknown 
(allow,deny,reject) [-M]"
-            "[-c policyvers (%d-%d)] [-o output_file] [-t platform]"
+           ("usage:  %s [-b] [-d] [-U handle_unknown 
(allow,deny,reject)] [-M]"
+            "[-c policyvers (%d-%d)] [-o output_file] [-t (selinux,xen)]"
              "[input_file]\n",
              progname, POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
         exit(1);


--
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 related	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/3] libsepol: Add support for multiple target OSes
  2009-10-13 19:56     ` Joshua Brindle
@ 2009-10-14 19:38       ` Joshua Brindle
  0 siblings, 0 replies; 13+ messages in thread
From: Joshua Brindle @ 2009-10-14 19:38 UTC (permalink / raw)
  To: Paul Nuzzi; +Cc: selinux, Stephen Smalley

Joshua Brindle wrote:
> Paul Nuzzi wrote:
>> On Wed, 2009-09-16 at 09:58 -0400, Joshua Brindle wrote:
>>> I'd rather have separate ocontext structs for each system. That way it
>>> is very easy to understand which ones apply to which system and you
>>> don't get a crazy out of context ocontext struct.
>>>
>>
>> I looked into having separate ocontext structs but that would involve
>> changing a lot of files making the patch much larger and more intrusive.
>>
>>>> } u;
>>>> union {
>>>> uint32_t sclass; /* security class for genfs */
>>>> @@ -313,6 +323,17 @@ typedef struct genfs {
>>>> #define OCON_NODE6 6 /* IPv6 nodes */
>>>> #define OCON_NUM 7
>>>>
>>>> +/* object context array indices for Xen */
>>>> +#define OCON_ISID 0 /* initial SIDs */
>>>> +#define OCON_PIRQ 1 /* physical irqs */
>>>> +#define OCON_IOPORT 2 /* io ports */
>>>> +#define OCON_IOMEM 3 /* io memory */
>>>> +#define OCON_DEVICE 4 /* pci devices */
>>>> +#define OCON_DUMMY1 5 /* reserved */
>>>> +#define OCON_DUMMY2 6 /* reserved */
>>>> +#define OCON_NUM 7
>>>> +
>>>> +
>>>>
>>> Should these be namespaced? What if<random other system> has io port
>>> objects? You'd have to align them with each other and you have a mess of
>>> keeping the numbers the same (you already do this with OCON_ISID)
>>
>> Variables have been namespaced and there is no more overlap with
>> OCON_ISID.
>>
>>> Also we are relying on having the same number of OCON's which isn't good
>>> I don't think. As much as I hate the policydb_compat_info (read: alot)
>>> why aren't we using that to say how many ocons a xen policy really has?
>>
>> OCON_NUM is now dynamically read through policydb_compat_info.
>>
>>
>>> This is messy, why not an ocontext_selinux_free() and
>>> ocontext_xen_free() (note: I realize the xen_free() one won't do
>>> anything except freep the ocontext_t)
>>>
>>
>> done.
>>
>>>> len = buf[1];
>>>> - if (len != strlen(target_str)&&
>>>> - (!alt_target_str || len != strlen(alt_target_str))) {
>>>> - ERR(fp->handle, "policydb string length %zu does not match "
>>>> - "expected length %zu", len, strlen(target_str));
>>>> + if (len> 32) {
>>>>
>>> magic number 32?
>>
>> #defined.
>>
>> Thanks for your input. Below is the updated patch for libsepol.
>>
>
> Acked-by: Joshua Brindle <method@manicmethod.com>
>
> for the entire patchset with the following diff on top:
>
> diff --git a/checkpolicy/checkpolicy.c b/checkpolicy/checkpolicy.c
> index 76d8ed3..c5fdf19 100644
> --- a/checkpolicy/checkpolicy.c
> +++ b/checkpolicy/checkpolicy.c
> @@ -100,8 +100,8 @@ unsigned int policyvers = POLICYDB_VERSION_MAX;
> void usage(char *progname)
> {
> printf
> - ("usage: %s [-b] [-d] [-U handle_unknown (allow,deny,reject) [-M]"
> - "[-c policyvers (%d-%d)] [-o output_file] [-t platform]"
> + ("usage: %s [-b] [-d] [-U handle_unknown (allow,deny,reject)] [-M]"
> + "[-c policyvers (%d-%d)] [-o output_file] [-t (selinux,xen)]"
> "[input_file]\n",
> progname, POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
> exit(1);
>
>

Merged in checkpolicy 2.0.20, libsepol 2.0.39, sepolgen 1.0.18




--
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] 13+ messages in thread

end of thread, other threads:[~2009-10-14 19:38 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-15 16:15 [PATCH 1/3] libsepol: Add support for multiple target OSes pjnuzzi
2009-09-15 16:37 ` [PATCH 2/3] checkpolicy: " pjnuzzi
2009-09-15 16:40   ` [PATCH 3/3] sepolgen: " pjnuzzi
2009-09-29 14:06   ` [PATCH 2/3] checkpolicy: " Paul Nuzzi
2009-09-16 13:58 ` [PATCH 1/3] libsepol: " Joshua Brindle
2009-09-16 17:44   ` Paul Nuzzi
2009-09-16 19:01     ` Stephen Smalley
2009-09-29 14:03   ` Paul Nuzzi
2009-10-06 14:20     ` Joshua Brindle
2009-10-07 17:37       ` Stephen Smalley
2009-10-07 18:48         ` Joshua Brindle
2009-10-13 19:56     ` Joshua Brindle
2009-10-14 19:38       ` Joshua Brindle

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.