All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/3] Xen/FLASK policy updates for device contexts
@ 2015-03-17 20:43 Daniel De Graaf
  2015-03-17 20:43   ` Daniel De Graaf
                   ` (5 more replies)
  0 siblings, 6 replies; 14+ messages in thread
From: Daniel De Graaf @ 2015-03-17 20:43 UTC (permalink / raw)
  To: selinux; +Cc: xen-devel

In order to support assigning security lables to ARM device tree nodes
in Xen's XSM policy, a new ocontext type is needed in the security
policy.

In addition to adding the new ocontext, the existing I/O memory range
ocontext is expanded to 64 bits in order to support hardware with more
than 44 bits of physical address space (32-bit count of 4K pages).

Changes from v2:
 - Clean up printf format strings for 32-bit builds

Changes from v1:
 - Use policy version 30 instead of forking the version numbers for Xen;
   this removes the need for v1's patch 3.
 - Report an error when attempting to use an I/O memory range that
   requires a 64-bit representation with an old policy output version
   that cannot support this
 - Fix a few incorrect references to PCIDEVICECON
 - Reorder patches to clarify the allowed characterset of device tree
   paths

[PATCH 1/3] checkpolicy: Expand allowed character set in paths
[PATCH 2/3] libsepol, checkpolicy: widen Xen IOMEM ocontext entries
[PATCH 3/3] libsepol, checkpolicy: add device tree ocontext nodes to

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

* [PATCH 1/3] checkpolicy: Expand allowed character set in paths
  2015-03-17 20:43 [PATCH v3 0/3] Xen/FLASK policy updates for device contexts Daniel De Graaf
@ 2015-03-17 20:43   ` Daniel De Graaf
  2015-03-17 20:43   ` Daniel De Graaf
                     ` (4 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Daniel De Graaf @ 2015-03-17 20:43 UTC (permalink / raw)
  To: selinux; +Cc: xen-devel

In order to support paths containing spaces or other characters, allow a
quoted string with these characters to be parsed as a path in addition
to the existing unquoted string.

Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
---
 checkpolicy/policy_parse.y | 3 +++
 checkpolicy/policy_scan.l  | 1 +
 2 files changed, 4 insertions(+)

diff --git a/checkpolicy/policy_parse.y b/checkpolicy/policy_parse.y
index 15c8997..e5210bd 100644
--- a/checkpolicy/policy_parse.y
+++ b/checkpolicy/policy_parse.y
@@ -81,6 +81,7 @@ typedef int (* require_func_t)(int pass);
 %type <require_func> require_decl_def
 
 %token PATH
+%token QPATH
 %token FILENAME
 %token CLONE
 %token COMMON
@@ -805,6 +806,8 @@ filesystem		: FILESYSTEM
                         ;
 path     		: PATH
 			{ if (insert_id(yytext,0)) return -1; }
+			| QPATH
+			{ yytext[strlen(yytext) - 1] = '\0'; if (insert_id(yytext + 1,0)) return -1; }
 			;
 filename		: FILENAME
 			{ yytext[strlen(yytext) - 1] = '\0'; if (insert_id(yytext + 1,0)) return -1; }
diff --git a/checkpolicy/policy_scan.l b/checkpolicy/policy_scan.l
index 648e1d6..6763c38 100644
--- a/checkpolicy/policy_scan.l
+++ b/checkpolicy/policy_scan.l
@@ -240,6 +240,7 @@ HIGH				{ return(HIGH); }
 low |
 LOW				{ return(LOW); }
 "/"({alnum}|[_\.\-/])*	        { return(PATH); }
+\""/"[ !#-~]*\" 		{ return(QPATH); }
 \"({alnum}|[_\.\-\+\~\: ])+\"	{ return(FILENAME); }
 {letter}({alnum}|[_\-])*([\.]?({alnum}|[_\-]))*	{ return(IDENTIFIER); }
 {digit}+|0x{hexval}+            { return(NUMBER); }
-- 
2.1.0

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

* [PATCH 1/3] checkpolicy: Expand allowed character set in paths
@ 2015-03-17 20:43   ` Daniel De Graaf
  0 siblings, 0 replies; 14+ messages in thread
From: Daniel De Graaf @ 2015-03-17 20:43 UTC (permalink / raw)
  To: selinux; +Cc: xen-devel, Daniel De Graaf

In order to support paths containing spaces or other characters, allow a
quoted string with these characters to be parsed as a path in addition
to the existing unquoted string.

Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
---
 checkpolicy/policy_parse.y | 3 +++
 checkpolicy/policy_scan.l  | 1 +
 2 files changed, 4 insertions(+)

diff --git a/checkpolicy/policy_parse.y b/checkpolicy/policy_parse.y
index 15c8997..e5210bd 100644
--- a/checkpolicy/policy_parse.y
+++ b/checkpolicy/policy_parse.y
@@ -81,6 +81,7 @@ typedef int (* require_func_t)(int pass);
 %type <require_func> require_decl_def
 
 %token PATH
+%token QPATH
 %token FILENAME
 %token CLONE
 %token COMMON
@@ -805,6 +806,8 @@ filesystem		: FILESYSTEM
                         ;
 path     		: PATH
 			{ if (insert_id(yytext,0)) return -1; }
+			| QPATH
+			{ yytext[strlen(yytext) - 1] = '\0'; if (insert_id(yytext + 1,0)) return -1; }
 			;
 filename		: FILENAME
 			{ yytext[strlen(yytext) - 1] = '\0'; if (insert_id(yytext + 1,0)) return -1; }
diff --git a/checkpolicy/policy_scan.l b/checkpolicy/policy_scan.l
index 648e1d6..6763c38 100644
--- a/checkpolicy/policy_scan.l
+++ b/checkpolicy/policy_scan.l
@@ -240,6 +240,7 @@ HIGH				{ return(HIGH); }
 low |
 LOW				{ return(LOW); }
 "/"({alnum}|[_\.\-/])*	        { return(PATH); }
+\""/"[ !#-~]*\" 		{ return(QPATH); }
 \"({alnum}|[_\.\-\+\~\: ])+\"	{ return(FILENAME); }
 {letter}({alnum}|[_\-])*([\.]?({alnum}|[_\-]))*	{ return(IDENTIFIER); }
 {digit}+|0x{hexval}+            { return(NUMBER); }
-- 
2.1.0

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

* [PATCH 2/3] libsepol, checkpolicy: widen Xen IOMEM ocontext entries
  2015-03-17 20:43 [PATCH v3 0/3] Xen/FLASK policy updates for device contexts Daniel De Graaf
@ 2015-03-17 20:43   ` Daniel De Graaf
  2015-03-17 20:43   ` Daniel De Graaf
                     ` (4 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Daniel De Graaf @ 2015-03-17 20:43 UTC (permalink / raw)
  To: selinux; +Cc: xen-devel

This expands IOMEMCON device context entries to 64 bits.  This change is
required to support static I/O memory range labeling for systems with
over 16TB of physical address space.  The policy version number change
is shared with the next patch.

While this makes no changes to SELinux policy, a new SELinux policy
compatibility entry was added in order to avoid breaking compilation of
an SELinux policy without explicitly specifying the policy version.

Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
---
 checkpolicy/policy_define.c                | 11 +++++-----
 checkpolicy/policy_define.h                |  2 +-
 checkpolicy/policy_parse.y                 |  9 ++++++--
 libsepol/cil/src/cil_build_ast.c           | 32 ++++++++++++++++++++++++++---
 libsepol/cil/src/cil_build_ast.h           |  1 +
 libsepol/cil/src/cil_internal.h            |  4 ++--
 libsepol/cil/src/cil_policy.c              |  3 ++-
 libsepol/cil/src/cil_tree.c                |  3 ++-
 libsepol/include/sepol/policydb/policydb.h |  7 ++++---
 libsepol/src/policydb.c                    | 33 +++++++++++++++++++++++++-----
 libsepol/src/write.c                       | 32 ++++++++++++++++++++++-------
 policycoreutils/hll/pp/pp.c                |  4 ++--
 12 files changed, 109 insertions(+), 32 deletions(-)

diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c
index a6c5d65..66c1ff2 100644
--- a/checkpolicy/policy_define.c
+++ b/checkpolicy/policy_define.c
@@ -39,6 +39,7 @@
 #include <arpa/inet.h>
 #include <stdlib.h>
 #include <limits.h>
+#include <inttypes.h>
 
 #include <sepol/policydb/expand.h>
 #include <sepol/policydb/policydb.h>
@@ -3932,7 +3933,7 @@ bad:
 	return -1;
 }
 
-int define_iomem_context(unsigned long low, unsigned long high)
+int define_iomem_context(uint64_t low, uint64_t high)
 {
 	ocontext_t *newc, *c, *l, *head;
 	char *id;
@@ -3960,7 +3961,7 @@ int define_iomem_context(unsigned long low, unsigned long high)
 	newc->u.iomem.high_iomem = high;
 
 	if (low > high) {
-		yyerror2("low memory 0x%lx exceeds high memory 0x%lx", low, high);
+		yyerror2("low memory 0x%"PRIx64" exceeds high memory 0x%"PRIx64"", low, high);
 		free(newc);
 		return -1;
 	}
@@ -3972,13 +3973,13 @@ int define_iomem_context(unsigned long low, unsigned long high)
 
 	head = policydbp->ocontexts[OCON_XEN_IOMEM];
 	for (l = NULL, c = head; c; l = c, c = c->next) {
-		uint32_t low2, high2;
+		uint64_t low2, high2;
 
 		low2 = c->u.iomem.low_iomem;
 		high2 = c->u.iomem.high_iomem;
 		if (low <= high2 && low2 <= high) {
-			yyerror2("iomemcon entry for 0x%lx-0x%lx overlaps with "
-				"earlier entry 0x%x-0x%x", low, high,
+			yyerror2("iomemcon entry for 0x%"PRIx64"-0x%"PRIx64" overlaps with "
+				"earlier entry 0x%"PRIx64"-0x%"PRIx64"", low, high,
 				low2, high2);
 			goto bad;
 		}
diff --git a/checkpolicy/policy_define.h b/checkpolicy/policy_define.h
index 4ef0f4f..14d30e1 100644
--- a/checkpolicy/policy_define.h
+++ b/checkpolicy/policy_define.h
@@ -46,7 +46,7 @@ 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_iomem_context(uint64_t low, uint64_t 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);
diff --git a/checkpolicy/policy_parse.y b/checkpolicy/policy_parse.y
index e5210bd..e3899b9 100644
--- a/checkpolicy/policy_parse.y
+++ b/checkpolicy/policy_parse.y
@@ -67,6 +67,7 @@ typedef int (* require_func_t)(int pass);
 
 %union {
 	unsigned int val;
+	uint64_t val64;
 	uintptr_t valptr;
 	void *ptr;
         require_func_t require_func;
@@ -78,6 +79,7 @@ typedef int (* require_func_t)(int pass);
 %type <ptr> role_def roles
 %type <valptr> cexpr cexpr_prim op role_mls_op
 %type <val> ipv4_addr_def number
+%type <val64> number64
 %type <require_func> require_decl_def
 
 %token PATH
@@ -647,9 +649,9 @@ dev_context_def		: pirq_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
+iomem_context_def	: IOMEMCON number64 security_context_def
 		        {if (define_iomem_context($2,$2)) return -1;}
-		        | IOMEMCON number '-' number security_context_def
+		        | IOMEMCON number64 '-' number64 security_context_def
 		        {if (define_iomem_context($2,$4)) return -1;}
 		        ;
 ioport_context_def	: IOPORTCON number security_context_def
@@ -815,6 +817,9 @@ filename		: FILENAME
 number			: NUMBER 
 			{ $$ = strtoul(yytext,NULL,0); }
 			;
+number64		: NUMBER
+			{ $$ = strtoull(yytext,NULL,0); }
+			;
 ipv6_addr		: IPV6_ADDR
 			{ if (insert_id(yytext,0)) return -1; }
 			;
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
index 419c20f..1949d2b 100644
--- a/libsepol/cil/src/cil_build_ast.c
+++ b/libsepol/cil/src/cil_build_ast.c
@@ -4319,12 +4319,12 @@ int cil_gen_iomemcon(__attribute__((unused)) struct cil_db *db, struct cil_tree_
 	if (parse_current->next->cl_head != NULL) {
 		if (parse_current->next->cl_head->next != NULL &&
 		    parse_current->next->cl_head->next->next == NULL) {
-			rc = cil_fill_integer(parse_current->next->cl_head, &iomemcon->iomem_low);
+			rc = cil_fill_integer64(parse_current->next->cl_head, &iomemcon->iomem_low);
 			if (rc != SEPOL_OK) {
 				cil_log(CIL_ERR, "Improper iomem specified\n");
 				goto exit;
 			}
-			rc = cil_fill_integer(parse_current->next->cl_head->next, &iomemcon->iomem_high);
+			rc = cil_fill_integer64(parse_current->next->cl_head->next, &iomemcon->iomem_high);
 			if (rc != SEPOL_OK) {
 				cil_log(CIL_ERR, "Improper iomem specified\n");
 				goto exit;
@@ -4335,7 +4335,7 @@ int cil_gen_iomemcon(__attribute__((unused)) struct cil_db *db, struct cil_tree_
 			goto exit;
 		}
 	} else {
-		rc = cil_fill_integer(parse_current->next, &iomemcon->iomem_low);;
+		rc = cil_fill_integer64(parse_current->next, &iomemcon->iomem_low);;
 		if (rc != SEPOL_OK) {
 			cil_log(CIL_ERR, "Improper iomem specified\n");
 			goto exit;
@@ -5054,6 +5054,32 @@ exit:
 	return rc;
 }
 
+int cil_fill_integer64(struct cil_tree_node *int_node, uint64_t *integer)
+{
+	int rc = SEPOL_ERR;
+	char *endptr = NULL;
+	uint64_t val;
+
+	if (int_node == NULL || integer == NULL) {
+		goto exit;
+	}
+
+	errno = 0;
+	val = strtoull(int_node->data, &endptr, 10);
+	if (errno != 0 || endptr == int_node->data || *endptr != '\0') {
+		rc = SEPOL_ERR;
+		goto exit;
+	}
+
+	*integer = val;
+
+	return SEPOL_OK;
+
+exit:
+	cil_log(CIL_ERR, "Failed to create integer from string\n");
+	return rc;
+}
+
 int cil_fill_ipaddr(struct cil_tree_node *addr_node, struct cil_ipaddr *addr)
 {
 	int rc = SEPOL_ERR;
diff --git a/libsepol/cil/src/cil_build_ast.h b/libsepol/cil/src/cil_build_ast.h
index 5b07c14..1bd33ce 100644
--- a/libsepol/cil/src/cil_build_ast.h
+++ b/libsepol/cil/src/cil_build_ast.h
@@ -211,6 +211,7 @@ int cil_fill_cats(struct cil_tree_node *curr, struct cil_cats **cats);
 void cil_destroy_cats(struct cil_cats *cats);
 int cil_fill_context(struct cil_tree_node *user_node, struct cil_context *context);
 int cil_fill_integer(struct cil_tree_node *int_node, uint32_t *integer);
+int cil_fill_integer64(struct cil_tree_node *int_node, uint64_t *integer);
 int cil_fill_ipaddr(struct cil_tree_node *addr_node, struct cil_ipaddr *addr);
 int cil_fill_level(struct cil_tree_node *sens, struct cil_level *level);
 
diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h
index cf0a8b1..11a2085 100644
--- a/libsepol/cil/src/cil_internal.h
+++ b/libsepol/cil/src/cil_internal.h
@@ -719,8 +719,8 @@ struct cil_pirqcon {
 };
 
 struct cil_iomemcon {
-	uint32_t iomem_low;
-	uint32_t iomem_high;
+	uint64_t iomem_low;
+	uint64_t iomem_high;
 	char *context_str;
 	struct cil_context *context;
 };
diff --git a/libsepol/cil/src/cil_policy.c b/libsepol/cil/src/cil_policy.c
index ec38f69..eefcbc1 100644
--- a/libsepol/cil/src/cil_policy.c
+++ b/libsepol/cil/src/cil_policy.c
@@ -32,6 +32,7 @@
 #include <string.h>
 #include <stdint.h>
 #include <unistd.h>
+#include <inttypes.h>
 
 #include <sepol/policydb/conditional.h>
 #include <sepol/errcodes.h>
@@ -236,7 +237,7 @@ int cil_iomemcon_to_policy(FILE **file_arr, struct cil_sort *sort)
 
 	for (i = 0; i < sort->count; i++) {
 		struct cil_iomemcon *iomemcon = (struct cil_iomemcon*)sort->array[i];
-		fprintf(file_arr[NETIFCONS], "iomemcon %d-%d ", iomemcon->iomem_low, iomemcon->iomem_high);
+		fprintf(file_arr[NETIFCONS], "iomemcon %"PRId64"-%"PRId64" ", iomemcon->iomem_low, iomemcon->iomem_high);
 		cil_context_to_policy(file_arr, NETIFCONS, iomemcon->context);
 		fprintf(file_arr[NETIFCONS], ";\n");
 	}
diff --git a/libsepol/cil/src/cil_tree.c b/libsepol/cil/src/cil_tree.c
index 4f9f480..81a1abc 100644
--- a/libsepol/cil/src/cil_tree.c
+++ b/libsepol/cil/src/cil_tree.c
@@ -29,6 +29,7 @@
 
 #include <stdio.h>
 #include <stdarg.h>
+#include <inttypes.h>
 
 #include <sepol/policydb/conditional.h>
 
@@ -1392,7 +1393,7 @@ void cil_tree_print_node(struct cil_tree_node *node)
 		case CIL_IOMEMCON: {
 			struct cil_iomemcon *iomemcon = node->data;
 
-			cil_log(CIL_INFO, "IOMEMCON ( %d %d )", iomemcon->iomem_low, iomemcon->iomem_high);
+			cil_log(CIL_INFO, "IOMEMCON ( %"PRId64" %"PRId64" )", iomemcon->iomem_low, iomemcon->iomem_high);
 			if (iomemcon->context != NULL) {
 				cil_tree_print_context(iomemcon->context);
 			} else {
diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h
index 6254fef..946cbaf 100644
--- a/libsepol/include/sepol/policydb/policydb.h
+++ b/libsepol/include/sepol/policydb/policydb.h
@@ -325,8 +325,8 @@ typedef struct ocontext {
 		uint32_t device;
 		uint16_t pirq;
 		struct {
-			uint32_t low_iomem;
-			uint32_t high_iomem;
+			uint64_t low_iomem;
+			uint64_t high_iomem;
 		} iomem;
 		struct {
 			uint32_t low_ioport;
@@ -689,10 +689,11 @@ extern int policydb_set_target_platform(policydb_t *p, int platform);
 #define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS	27
 #define POLICYDB_VERSION_DEFAULT_TYPE	28
 #define POLICYDB_VERSION_CONSTRAINT_NAMES	29
+#define POLICYDB_VERSION_XEN_DEVICETREE 30
 
 /* Range of policy versions we understand*/
 #define POLICYDB_VERSION_MIN	POLICYDB_VERSION_BASE
-#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_CONSTRAINT_NAMES
+#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_XEN_DEVICETREE
 
 /* Module versions and specific changes*/
 #define MOD_POLICYDB_VERSION_BASE		4
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index 667e98a..d54eb9e 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -68,6 +68,13 @@ static struct policydb_compat_info policydb_compat[] = {
 	 },
 	{
 	 .type = POLICY_KERN,
+	 .version = POLICYDB_VERSION_XEN_DEVICETREE,
+	 .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,
@@ -172,6 +179,13 @@ static struct policydb_compat_info policydb_compat[] = {
 	 .target_platform = SEPOL_TARGET_SELINUX,
 	},
 	{
+	 .type = POLICY_KERN,
+	 .version = POLICYDB_VERSION_XEN_DEVICETREE,
+	 .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,
@@ -2514,11 +2528,20 @@ static int ocontext_read_xen(struct policydb_compat_info *info,
 					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 (p->policyvers >= POLICYDB_VERSION_XEN_DEVICETREE) {
+					uint64_t b64[2];
+					rc = next_entry(b64, fp, sizeof(uint64_t) * 2);
+					if (rc < 0)
+						return -1;
+					c->u.iomem.low_iomem = le64_to_cpu(b64[0]);
+					c->u.iomem.high_iomem = le64_to_cpu(b64[1]);
+				} else {
+					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;
diff --git a/libsepol/src/write.c b/libsepol/src/write.c
index d03dc20..3452017 100644
--- a/libsepol/src/write.c
+++ b/libsepol/src/write.c
@@ -1252,13 +1252,31 @@ static int ocontext_write_xen(struct policydb_compat_info *info, policydb_t *p,
 					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 (p->policyvers >= POLICYDB_VERSION_XEN_DEVICETREE) {
+					uint64_t b64[2];
+					b64[0] = c->u.iomem.low_iomem;
+					b64[1] = c->u.iomem.high_iomem;
+					for (j = 0; j < 2; j++)
+						b64[j] = cpu_to_le64(b64[j]);
+					items = put_entry(b64, sizeof(uint64_t), 2, fp);
+					if (items != 2)
+						return POLICYDB_ERROR;
+				} else {
+					if (c->u.iomem.high_iomem > 0xFFFFFFFFULL) {
+						ERR(fp->handle, "policy version %d"
+							" cannot represent IOMEM addresses over 16TB",
+							p->policyvers);
+						return POLICYDB_ERROR;
+					}
+
+					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;
diff --git a/policycoreutils/hll/pp/pp.c b/policycoreutils/hll/pp/pp.c
index b863346..60c493d 100644
--- a/policycoreutils/hll/pp/pp.c
+++ b/policycoreutils/hll/pp/pp.c
@@ -2695,8 +2695,8 @@ static int ocontext_xen_ioport_to_cil(struct policydb *pdb, struct ocontext *iop
 static int ocontext_xen_iomem_to_cil(struct policydb *pdb, struct ocontext *iomems)
 {
 	struct ocontext *iomem;
-	uint32_t low;
-	uint32_t high;
+	uint64_t low;
+	uint64_t high;
 
 	for (iomem = iomems; iomem != NULL; iomem = iomem->next) {
 		low = iomem->u.iomem.low_iomem;
-- 
2.1.0

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

* [PATCH 2/3] libsepol, checkpolicy: widen Xen IOMEM ocontext entries
@ 2015-03-17 20:43   ` Daniel De Graaf
  0 siblings, 0 replies; 14+ messages in thread
From: Daniel De Graaf @ 2015-03-17 20:43 UTC (permalink / raw)
  To: selinux; +Cc: xen-devel, Daniel De Graaf

This expands IOMEMCON device context entries to 64 bits.  This change is
required to support static I/O memory range labeling for systems with
over 16TB of physical address space.  The policy version number change
is shared with the next patch.

While this makes no changes to SELinux policy, a new SELinux policy
compatibility entry was added in order to avoid breaking compilation of
an SELinux policy without explicitly specifying the policy version.

Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
---
 checkpolicy/policy_define.c                | 11 +++++-----
 checkpolicy/policy_define.h                |  2 +-
 checkpolicy/policy_parse.y                 |  9 ++++++--
 libsepol/cil/src/cil_build_ast.c           | 32 ++++++++++++++++++++++++++---
 libsepol/cil/src/cil_build_ast.h           |  1 +
 libsepol/cil/src/cil_internal.h            |  4 ++--
 libsepol/cil/src/cil_policy.c              |  3 ++-
 libsepol/cil/src/cil_tree.c                |  3 ++-
 libsepol/include/sepol/policydb/policydb.h |  7 ++++---
 libsepol/src/policydb.c                    | 33 +++++++++++++++++++++++++-----
 libsepol/src/write.c                       | 32 ++++++++++++++++++++++-------
 policycoreutils/hll/pp/pp.c                |  4 ++--
 12 files changed, 109 insertions(+), 32 deletions(-)

diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c
index a6c5d65..66c1ff2 100644
--- a/checkpolicy/policy_define.c
+++ b/checkpolicy/policy_define.c
@@ -39,6 +39,7 @@
 #include <arpa/inet.h>
 #include <stdlib.h>
 #include <limits.h>
+#include <inttypes.h>
 
 #include <sepol/policydb/expand.h>
 #include <sepol/policydb/policydb.h>
@@ -3932,7 +3933,7 @@ bad:
 	return -1;
 }
 
-int define_iomem_context(unsigned long low, unsigned long high)
+int define_iomem_context(uint64_t low, uint64_t high)
 {
 	ocontext_t *newc, *c, *l, *head;
 	char *id;
@@ -3960,7 +3961,7 @@ int define_iomem_context(unsigned long low, unsigned long high)
 	newc->u.iomem.high_iomem = high;
 
 	if (low > high) {
-		yyerror2("low memory 0x%lx exceeds high memory 0x%lx", low, high);
+		yyerror2("low memory 0x%"PRIx64" exceeds high memory 0x%"PRIx64"", low, high);
 		free(newc);
 		return -1;
 	}
@@ -3972,13 +3973,13 @@ int define_iomem_context(unsigned long low, unsigned long high)
 
 	head = policydbp->ocontexts[OCON_XEN_IOMEM];
 	for (l = NULL, c = head; c; l = c, c = c->next) {
-		uint32_t low2, high2;
+		uint64_t low2, high2;
 
 		low2 = c->u.iomem.low_iomem;
 		high2 = c->u.iomem.high_iomem;
 		if (low <= high2 && low2 <= high) {
-			yyerror2("iomemcon entry for 0x%lx-0x%lx overlaps with "
-				"earlier entry 0x%x-0x%x", low, high,
+			yyerror2("iomemcon entry for 0x%"PRIx64"-0x%"PRIx64" overlaps with "
+				"earlier entry 0x%"PRIx64"-0x%"PRIx64"", low, high,
 				low2, high2);
 			goto bad;
 		}
diff --git a/checkpolicy/policy_define.h b/checkpolicy/policy_define.h
index 4ef0f4f..14d30e1 100644
--- a/checkpolicy/policy_define.h
+++ b/checkpolicy/policy_define.h
@@ -46,7 +46,7 @@ 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_iomem_context(uint64_t low, uint64_t 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);
diff --git a/checkpolicy/policy_parse.y b/checkpolicy/policy_parse.y
index e5210bd..e3899b9 100644
--- a/checkpolicy/policy_parse.y
+++ b/checkpolicy/policy_parse.y
@@ -67,6 +67,7 @@ typedef int (* require_func_t)(int pass);
 
 %union {
 	unsigned int val;
+	uint64_t val64;
 	uintptr_t valptr;
 	void *ptr;
         require_func_t require_func;
@@ -78,6 +79,7 @@ typedef int (* require_func_t)(int pass);
 %type <ptr> role_def roles
 %type <valptr> cexpr cexpr_prim op role_mls_op
 %type <val> ipv4_addr_def number
+%type <val64> number64
 %type <require_func> require_decl_def
 
 %token PATH
@@ -647,9 +649,9 @@ dev_context_def		: pirq_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
+iomem_context_def	: IOMEMCON number64 security_context_def
 		        {if (define_iomem_context($2,$2)) return -1;}
-		        | IOMEMCON number '-' number security_context_def
+		        | IOMEMCON number64 '-' number64 security_context_def
 		        {if (define_iomem_context($2,$4)) return -1;}
 		        ;
 ioport_context_def	: IOPORTCON number security_context_def
@@ -815,6 +817,9 @@ filename		: FILENAME
 number			: NUMBER 
 			{ $$ = strtoul(yytext,NULL,0); }
 			;
+number64		: NUMBER
+			{ $$ = strtoull(yytext,NULL,0); }
+			;
 ipv6_addr		: IPV6_ADDR
 			{ if (insert_id(yytext,0)) return -1; }
 			;
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
index 419c20f..1949d2b 100644
--- a/libsepol/cil/src/cil_build_ast.c
+++ b/libsepol/cil/src/cil_build_ast.c
@@ -4319,12 +4319,12 @@ int cil_gen_iomemcon(__attribute__((unused)) struct cil_db *db, struct cil_tree_
 	if (parse_current->next->cl_head != NULL) {
 		if (parse_current->next->cl_head->next != NULL &&
 		    parse_current->next->cl_head->next->next == NULL) {
-			rc = cil_fill_integer(parse_current->next->cl_head, &iomemcon->iomem_low);
+			rc = cil_fill_integer64(parse_current->next->cl_head, &iomemcon->iomem_low);
 			if (rc != SEPOL_OK) {
 				cil_log(CIL_ERR, "Improper iomem specified\n");
 				goto exit;
 			}
-			rc = cil_fill_integer(parse_current->next->cl_head->next, &iomemcon->iomem_high);
+			rc = cil_fill_integer64(parse_current->next->cl_head->next, &iomemcon->iomem_high);
 			if (rc != SEPOL_OK) {
 				cil_log(CIL_ERR, "Improper iomem specified\n");
 				goto exit;
@@ -4335,7 +4335,7 @@ int cil_gen_iomemcon(__attribute__((unused)) struct cil_db *db, struct cil_tree_
 			goto exit;
 		}
 	} else {
-		rc = cil_fill_integer(parse_current->next, &iomemcon->iomem_low);;
+		rc = cil_fill_integer64(parse_current->next, &iomemcon->iomem_low);;
 		if (rc != SEPOL_OK) {
 			cil_log(CIL_ERR, "Improper iomem specified\n");
 			goto exit;
@@ -5054,6 +5054,32 @@ exit:
 	return rc;
 }
 
+int cil_fill_integer64(struct cil_tree_node *int_node, uint64_t *integer)
+{
+	int rc = SEPOL_ERR;
+	char *endptr = NULL;
+	uint64_t val;
+
+	if (int_node == NULL || integer == NULL) {
+		goto exit;
+	}
+
+	errno = 0;
+	val = strtoull(int_node->data, &endptr, 10);
+	if (errno != 0 || endptr == int_node->data || *endptr != '\0') {
+		rc = SEPOL_ERR;
+		goto exit;
+	}
+
+	*integer = val;
+
+	return SEPOL_OK;
+
+exit:
+	cil_log(CIL_ERR, "Failed to create integer from string\n");
+	return rc;
+}
+
 int cil_fill_ipaddr(struct cil_tree_node *addr_node, struct cil_ipaddr *addr)
 {
 	int rc = SEPOL_ERR;
diff --git a/libsepol/cil/src/cil_build_ast.h b/libsepol/cil/src/cil_build_ast.h
index 5b07c14..1bd33ce 100644
--- a/libsepol/cil/src/cil_build_ast.h
+++ b/libsepol/cil/src/cil_build_ast.h
@@ -211,6 +211,7 @@ int cil_fill_cats(struct cil_tree_node *curr, struct cil_cats **cats);
 void cil_destroy_cats(struct cil_cats *cats);
 int cil_fill_context(struct cil_tree_node *user_node, struct cil_context *context);
 int cil_fill_integer(struct cil_tree_node *int_node, uint32_t *integer);
+int cil_fill_integer64(struct cil_tree_node *int_node, uint64_t *integer);
 int cil_fill_ipaddr(struct cil_tree_node *addr_node, struct cil_ipaddr *addr);
 int cil_fill_level(struct cil_tree_node *sens, struct cil_level *level);
 
diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h
index cf0a8b1..11a2085 100644
--- a/libsepol/cil/src/cil_internal.h
+++ b/libsepol/cil/src/cil_internal.h
@@ -719,8 +719,8 @@ struct cil_pirqcon {
 };
 
 struct cil_iomemcon {
-	uint32_t iomem_low;
-	uint32_t iomem_high;
+	uint64_t iomem_low;
+	uint64_t iomem_high;
 	char *context_str;
 	struct cil_context *context;
 };
diff --git a/libsepol/cil/src/cil_policy.c b/libsepol/cil/src/cil_policy.c
index ec38f69..eefcbc1 100644
--- a/libsepol/cil/src/cil_policy.c
+++ b/libsepol/cil/src/cil_policy.c
@@ -32,6 +32,7 @@
 #include <string.h>
 #include <stdint.h>
 #include <unistd.h>
+#include <inttypes.h>
 
 #include <sepol/policydb/conditional.h>
 #include <sepol/errcodes.h>
@@ -236,7 +237,7 @@ int cil_iomemcon_to_policy(FILE **file_arr, struct cil_sort *sort)
 
 	for (i = 0; i < sort->count; i++) {
 		struct cil_iomemcon *iomemcon = (struct cil_iomemcon*)sort->array[i];
-		fprintf(file_arr[NETIFCONS], "iomemcon %d-%d ", iomemcon->iomem_low, iomemcon->iomem_high);
+		fprintf(file_arr[NETIFCONS], "iomemcon %"PRId64"-%"PRId64" ", iomemcon->iomem_low, iomemcon->iomem_high);
 		cil_context_to_policy(file_arr, NETIFCONS, iomemcon->context);
 		fprintf(file_arr[NETIFCONS], ";\n");
 	}
diff --git a/libsepol/cil/src/cil_tree.c b/libsepol/cil/src/cil_tree.c
index 4f9f480..81a1abc 100644
--- a/libsepol/cil/src/cil_tree.c
+++ b/libsepol/cil/src/cil_tree.c
@@ -29,6 +29,7 @@
 
 #include <stdio.h>
 #include <stdarg.h>
+#include <inttypes.h>
 
 #include <sepol/policydb/conditional.h>
 
@@ -1392,7 +1393,7 @@ void cil_tree_print_node(struct cil_tree_node *node)
 		case CIL_IOMEMCON: {
 			struct cil_iomemcon *iomemcon = node->data;
 
-			cil_log(CIL_INFO, "IOMEMCON ( %d %d )", iomemcon->iomem_low, iomemcon->iomem_high);
+			cil_log(CIL_INFO, "IOMEMCON ( %"PRId64" %"PRId64" )", iomemcon->iomem_low, iomemcon->iomem_high);
 			if (iomemcon->context != NULL) {
 				cil_tree_print_context(iomemcon->context);
 			} else {
diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h
index 6254fef..946cbaf 100644
--- a/libsepol/include/sepol/policydb/policydb.h
+++ b/libsepol/include/sepol/policydb/policydb.h
@@ -325,8 +325,8 @@ typedef struct ocontext {
 		uint32_t device;
 		uint16_t pirq;
 		struct {
-			uint32_t low_iomem;
-			uint32_t high_iomem;
+			uint64_t low_iomem;
+			uint64_t high_iomem;
 		} iomem;
 		struct {
 			uint32_t low_ioport;
@@ -689,10 +689,11 @@ extern int policydb_set_target_platform(policydb_t *p, int platform);
 #define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS	27
 #define POLICYDB_VERSION_DEFAULT_TYPE	28
 #define POLICYDB_VERSION_CONSTRAINT_NAMES	29
+#define POLICYDB_VERSION_XEN_DEVICETREE 30
 
 /* Range of policy versions we understand*/
 #define POLICYDB_VERSION_MIN	POLICYDB_VERSION_BASE
-#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_CONSTRAINT_NAMES
+#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_XEN_DEVICETREE
 
 /* Module versions and specific changes*/
 #define MOD_POLICYDB_VERSION_BASE		4
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index 667e98a..d54eb9e 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -68,6 +68,13 @@ static struct policydb_compat_info policydb_compat[] = {
 	 },
 	{
 	 .type = POLICY_KERN,
+	 .version = POLICYDB_VERSION_XEN_DEVICETREE,
+	 .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,
@@ -172,6 +179,13 @@ static struct policydb_compat_info policydb_compat[] = {
 	 .target_platform = SEPOL_TARGET_SELINUX,
 	},
 	{
+	 .type = POLICY_KERN,
+	 .version = POLICYDB_VERSION_XEN_DEVICETREE,
+	 .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,
@@ -2514,11 +2528,20 @@ static int ocontext_read_xen(struct policydb_compat_info *info,
 					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 (p->policyvers >= POLICYDB_VERSION_XEN_DEVICETREE) {
+					uint64_t b64[2];
+					rc = next_entry(b64, fp, sizeof(uint64_t) * 2);
+					if (rc < 0)
+						return -1;
+					c->u.iomem.low_iomem = le64_to_cpu(b64[0]);
+					c->u.iomem.high_iomem = le64_to_cpu(b64[1]);
+				} else {
+					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;
diff --git a/libsepol/src/write.c b/libsepol/src/write.c
index d03dc20..3452017 100644
--- a/libsepol/src/write.c
+++ b/libsepol/src/write.c
@@ -1252,13 +1252,31 @@ static int ocontext_write_xen(struct policydb_compat_info *info, policydb_t *p,
 					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 (p->policyvers >= POLICYDB_VERSION_XEN_DEVICETREE) {
+					uint64_t b64[2];
+					b64[0] = c->u.iomem.low_iomem;
+					b64[1] = c->u.iomem.high_iomem;
+					for (j = 0; j < 2; j++)
+						b64[j] = cpu_to_le64(b64[j]);
+					items = put_entry(b64, sizeof(uint64_t), 2, fp);
+					if (items != 2)
+						return POLICYDB_ERROR;
+				} else {
+					if (c->u.iomem.high_iomem > 0xFFFFFFFFULL) {
+						ERR(fp->handle, "policy version %d"
+							" cannot represent IOMEM addresses over 16TB",
+							p->policyvers);
+						return POLICYDB_ERROR;
+					}
+
+					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;
diff --git a/policycoreutils/hll/pp/pp.c b/policycoreutils/hll/pp/pp.c
index b863346..60c493d 100644
--- a/policycoreutils/hll/pp/pp.c
+++ b/policycoreutils/hll/pp/pp.c
@@ -2695,8 +2695,8 @@ static int ocontext_xen_ioport_to_cil(struct policydb *pdb, struct ocontext *iop
 static int ocontext_xen_iomem_to_cil(struct policydb *pdb, struct ocontext *iomems)
 {
 	struct ocontext *iomem;
-	uint32_t low;
-	uint32_t high;
+	uint64_t low;
+	uint64_t high;
 
 	for (iomem = iomems; iomem != NULL; iomem = iomem->next) {
 		low = iomem->u.iomem.low_iomem;
-- 
2.1.0

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

* [PATCH 3/3] libsepol, checkpolicy: add device tree ocontext nodes to Xen policy
  2015-03-17 20:43 [PATCH v3 0/3] Xen/FLASK policy updates for device contexts Daniel De Graaf
@ 2015-03-17 20:43   ` Daniel De Graaf
  2015-03-17 20:43   ` Daniel De Graaf
                     ` (4 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Daniel De Graaf @ 2015-03-17 20:43 UTC (permalink / raw)
  To: selinux; +Cc: xen-devel

In Xen on ARM, device tree nodes identified by a path (string) need to
be labeled by the security policy.

Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
---
 checkpolicy/policy_define.c                | 55 +++++++++++++++++++++++++
 checkpolicy/policy_define.h                |  1 +
 checkpolicy/policy_parse.y                 |  8 +++-
 checkpolicy/policy_scan.l                  |  2 +
 libsepol/cil/src/cil.c                     | 17 ++++++++
 libsepol/cil/src/cil_binary.c              | 29 +++++++++++++
 libsepol/cil/src/cil_build_ast.c           | 66 ++++++++++++++++++++++++++++++
 libsepol/cil/src/cil_build_ast.h           |  2 +
 libsepol/cil/src/cil_copy_ast.c            | 24 +++++++++++
 libsepol/cil/src/cil_flavor.h              |  1 +
 libsepol/cil/src/cil_internal.h            | 10 +++++
 libsepol/cil/src/cil_post.c                | 34 +++++++++++++++
 libsepol/cil/src/cil_reset_ast.c           | 10 +++++
 libsepol/cil/src/cil_resolve_ast.c         | 28 +++++++++++++
 libsepol/cil/src/cil_tree.c                | 13 ++++++
 libsepol/cil/src/cil_verify.c              | 24 +++++++++++
 libsepol/include/sepol/policydb/policydb.h |  1 +
 libsepol/src/expand.c                      |  7 ++++
 libsepol/src/policydb.c                    | 18 +++++++-
 libsepol/src/write.c                       | 14 ++++++-
 sepolgen/src/sepolgen/refparser.py         | 11 +++++
 sepolgen/src/sepolgen/refpolicy.py         |  9 ++++
 22 files changed, 379 insertions(+), 5 deletions(-)

diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c
index 66c1ff2..de01f6f 100644
--- a/checkpolicy/policy_define.c
+++ b/checkpolicy/policy_define.c
@@ -4116,6 +4116,61 @@ bad:
 	return -1;
 }
 
+int define_devicetree_context()
+{
+	ocontext_t *newc, *c, *l, *head;
+
+	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
+		yyerror("devicetreecon not supported for target");
+		return -1;
+	}
+
+	if (pass == 1) {
+		free(queue_remove(id_queue));
+		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.name = (char *)queue_remove(id_queue);
+	if (!newc->u.name) {
+		free(newc);
+		return -1;
+	}
+
+	if (parse_security_context(&newc->context[0])) {
+		free(newc->u.name);
+		free(newc);
+		return -1;
+	}
+
+	head = policydbp->ocontexts[OCON_XEN_DEVICETREE];
+	for (l = NULL, c = head; c; l = c, c = c->next) {
+		if (strcmp(newc->u.name, c->u.name) == 0) {
+			yyerror2("duplicate devicetree entry for '%s'", newc->u.name);
+			goto bad;
+		}
+	}
+
+	if (l)
+		l->next = newc;
+	else
+		policydbp->ocontexts[OCON_XEN_DEVICETREE] = newc;
+
+	return 0;
+
+bad:
+	free(newc->u.name);
+	free(newc);
+	return -1;
+}
+
 int define_port_context(unsigned int low, unsigned int high)
 {
 	ocontext_t *newc, *c, *l, *head;
diff --git a/checkpolicy/policy_define.h b/checkpolicy/policy_define.h
index 14d30e1..a87ced3 100644
--- a/checkpolicy/policy_define.h
+++ b/checkpolicy/policy_define.h
@@ -49,6 +49,7 @@ int define_pirq_context(unsigned int pirq);
 int define_iomem_context(uint64_t low, uint64_t high);
 int define_ioport_context(unsigned long low, unsigned long high);
 int define_pcidevice_context(unsigned long device);
+int define_devicetree_context(void);
 int define_range_trans(int class_specified);
 int define_role_allow(void);
 int define_role_trans(int class_specified);
diff --git a/checkpolicy/policy_parse.y b/checkpolicy/policy_parse.y
index e3899b9..8b81f04 100644
--- a/checkpolicy/policy_parse.y
+++ b/checkpolicy/policy_parse.y
@@ -130,7 +130,7 @@ typedef int (* require_func_t)(int pass);
 %token TARGET
 %token SAMEUSER
 %token FSCON PORTCON NETIFCON NODECON 
-%token PIRQCON IOMEMCON IOPORTCON PCIDEVICECON
+%token PIRQCON IOMEMCON IOPORTCON PCIDEVICECON DEVICETREECON
 %token FSUSEXATTR FSUSETASK FSUSETRANS
 %token GENFSCON
 %token U1 U2 U3 R1 R2 R3 T1 T2 T3 L1 L2 H1 H2
@@ -644,7 +644,8 @@ dev_contexts		: dev_context_def
 dev_context_def		: pirq_context_def |
 			  iomem_context_def |
 			  ioport_context_def |
-			  pci_context_def
+			  pci_context_def |
+			  dtree_context_def
 			;
 pirq_context_def 	: PIRQCON number security_context_def
 		        {if (define_pirq_context($2)) return -1;}
@@ -662,6 +663,9 @@ ioport_context_def	: IOPORTCON number security_context_def
 pci_context_def  	: PCIDEVICECON number security_context_def
 		        {if (define_pcidevice_context($2)) return -1;}
 		        ;
+dtree_context_def	: DEVICETREECON path security_context_def
+		        {if (define_devicetree_context()) return -1;}
+		        ;
 opt_fs_contexts         : fs_contexts 
                         |
                         ;
diff --git a/checkpolicy/policy_scan.l b/checkpolicy/policy_scan.l
index 6763c38..108edbc 100644
--- a/checkpolicy/policy_scan.l
+++ b/checkpolicy/policy_scan.l
@@ -187,6 +187,8 @@ ioportcon |
 IOPORTCON           		{ return(IOPORTCON);}
 pcidevicecon |
 PCIDEVICECON           		{ return(PCIDEVICECON);}
+devicetreecon |
+DEVICETREECON           	{ return(DEVICETREECON);}
 fs_use_xattr |
 FS_USE_XATTR			{ return(FSUSEXATTR);}
 fs_use_task |
diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
index a25f878..1594be6 100644
--- a/libsepol/cil/src/cil.c
+++ b/libsepol/cil/src/cil.c
@@ -189,6 +189,7 @@ static void cil_init_keys(void)
 	CIL_KEY_IOMEMCON = cil_strpool_add("iomemcon");
 	CIL_KEY_IOPORTCON = cil_strpool_add("ioportcon");
 	CIL_KEY_PCIDEVICECON = cil_strpool_add("pcidevicecon");
+	CIL_KEY_DEVICETREECON = cil_strpool_add("devicetreecon");
 	CIL_KEY_FSUSE = cil_strpool_add("fsuse");
 	CIL_KEY_POLICYCAP = cil_strpool_add("policycap");
 	CIL_KEY_OPTIONAL = cil_strpool_add("optional");
@@ -244,6 +245,7 @@ void cil_db_init(struct cil_db **db)
 	cil_sort_init(&(*db)->iomemcon);
 	cil_sort_init(&(*db)->ioportcon);
 	cil_sort_init(&(*db)->pcidevicecon);
+	cil_sort_init(&(*db)->devicetreecon);
 	cil_sort_init(&(*db)->fsuse);
 	cil_list_init(&(*db)->userprefixes, CIL_LIST_ITEM);
 	cil_list_init(&(*db)->selinuxusers, CIL_LIST_ITEM);
@@ -289,6 +291,7 @@ void cil_db_destroy(struct cil_db **db)
 	cil_sort_destroy(&(*db)->iomemcon);
 	cil_sort_destroy(&(*db)->ioportcon);
 	cil_sort_destroy(&(*db)->pcidevicecon);
+	cil_sort_destroy(&(*db)->devicetreecon);
 	cil_sort_destroy(&(*db)->fsuse);
 	cil_list_destroy(&(*db)->userprefixes, CIL_FALSE);
 	cil_list_destroy(&(*db)->selinuxusers, CIL_FALSE);
@@ -697,6 +700,9 @@ void cil_destroy_data(void **data, enum cil_flavor flavor)
 	case CIL_PCIDEVICECON:
 		cil_destroy_pcidevicecon(*data);
 		break;
+	case CIL_DEVICETREECON:
+		cil_destroy_devicetreecon(*data);
+		break;
 	case CIL_POLICYCAP:
 		cil_destroy_policycap(*data);
 		break;
@@ -1026,6 +1032,8 @@ const char * cil_node_to_string(struct cil_tree_node *node)
 		return CIL_KEY_IOPORTCON;
 	case CIL_PCIDEVICECON:
 		return CIL_KEY_PCIDEVICECON;
+	case CIL_DEVICETREECON:
+		return CIL_KEY_DEVICETREECON;
 	case CIL_POLICYCAP:
 		return CIL_KEY_POLICYCAP;
 	case CIL_DEFAULTUSER:
@@ -2181,6 +2189,15 @@ void cil_pcidevicecon_init(struct cil_pcidevicecon **pcidevicecon)
 	(*pcidevicecon)->context = NULL;
 }
 
+void cil_devicetreecon_init(struct cil_devicetreecon **dtcon)
+{
+	*dtcon = cil_malloc(sizeof(**dtcon));
+
+	(*dtcon)->path = NULL;
+	(*dtcon)->context_str = NULL;
+	(*dtcon)->context = NULL;
+}
+
 void cil_fsuse_init(struct cil_fsuse **fsuse)
 {
 	*fsuse = cil_malloc(sizeof(**fsuse));
diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
index 387237f..03f4924 100644
--- a/libsepol/cil/src/cil_binary.c
+++ b/libsepol/cil/src/cil_binary.c
@@ -2993,6 +2993,30 @@ exit:
 	return rc;
 }
 
+int cil_devicetreecon_to_policydb(policydb_t *pdb, struct cil_sort *devicetreecons)
+{
+	int rc = SEPOL_ERR;
+	uint32_t i = 0;
+	ocontext_t *tail = NULL;
+
+	for (i = 0; i < devicetreecons->count; i++) {
+		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_DEVICETREE], &tail);
+		struct cil_devicetreecon *cil_devicetreecon = devicetreecons->array[i];
+
+		new_ocon->u.name = cil_strdup(cil_devicetreecon->path);
+
+		rc = __cil_context_to_sepol_context(pdb, cil_devicetreecon->context, &new_ocon->context[0]);
+		if (rc != SEPOL_OK) {
+			goto exit;
+		}
+	}
+
+	return SEPOL_OK;
+
+exit:
+	return rc;
+}
+
 int cil_default_to_policydb(policydb_t *pdb, struct cil_default *def)
 {
 	struct cil_list_item *curr;
@@ -3340,6 +3364,11 @@ int __cil_contexts_to_policydb(policydb_t *pdb, const struct cil_db *db)
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
+
+		rc = cil_devicetreecon_to_policydb(pdb, db->devicetreecon);
+		if (rc != SEPOL_OK) {
+			goto exit;
+		}
 	}
 	return SEPOL_OK;
 exit:
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
index 1949d2b..d4ef73c 100644
--- a/libsepol/cil/src/cil_build_ast.c
+++ b/libsepol/cil/src/cil_build_ast.c
@@ -4529,6 +4529,69 @@ void cil_destroy_pcidevicecon(struct cil_pcidevicecon *pcidevicecon)
 	free(pcidevicecon);
 }
 
+int cil_gen_devicetreecon(__attribute__((unused)) struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node)
+{
+	enum cil_syntax syntax[] = {
+		CIL_SYN_STRING,
+		CIL_SYN_STRING,
+		CIL_SYN_STRING | CIL_SYN_LIST,
+		CIL_SYN_END
+	};
+	int syntax_len = sizeof(syntax)/sizeof(*syntax);
+	int rc = SEPOL_ERR;
+	struct cil_devicetreecon *devicetreecon = NULL;
+
+	if (db == NULL || parse_current == NULL || ast_node == NULL) {
+		goto exit;
+	}
+
+	rc = __cil_verify_syntax(parse_current, syntax, syntax_len);
+	if (rc != SEPOL_OK) {
+		goto exit;
+	}
+
+	cil_devicetreecon_init(&devicetreecon);
+
+	devicetreecon->path = parse_current->next->data;
+
+	if (parse_current->next->next->cl_head == NULL) {
+		devicetreecon->context_str = parse_current->next->next->data;
+	} else {
+		cil_context_init(&devicetreecon->context);
+
+		rc = cil_fill_context(parse_current->next->next->cl_head, devicetreecon->context);
+		if (rc != SEPOL_OK) {
+			goto exit;
+		}
+	}
+
+	ast_node->data = devicetreecon;
+	ast_node->flavor = CIL_DEVICETREECON;
+
+	return SEPOL_OK;
+
+exit:
+	cil_log(CIL_ERR, "Bad devicetreecon declaration at line %d of %s\n", 
+		parse_current->line, parse_current->path);
+	cil_destroy_devicetreecon(devicetreecon);
+	return rc;
+}
+
+void cil_destroy_devicetreecon(struct cil_devicetreecon *devicetreecon)
+{
+	if (devicetreecon == NULL) {
+		return;
+	}
+
+	free(devicetreecon->path);
+
+	if (devicetreecon->context_str == NULL && devicetreecon->context != NULL) {
+		cil_destroy_context(devicetreecon->context);
+	}
+
+	free(devicetreecon);
+}
+
 int cil_gen_fsuse(__attribute__((unused)) struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node)
 {
 	enum cil_syntax syntax[] = {
@@ -5806,6 +5869,9 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
 	} else if (parse_current->data == CIL_KEY_PCIDEVICECON) {
 		rc = cil_gen_pcidevicecon(db, parse_current, ast_node);
 		*finished = CIL_TREE_SKIP_NEXT;
+	} else if (parse_current->data == CIL_KEY_DEVICETREECON) {
+		rc = cil_gen_devicetreecon(db, parse_current, ast_node);
+		*finished = CIL_TREE_SKIP_NEXT;
 	} else if (parse_current->data == CIL_KEY_FSUSE) {
 		rc = cil_gen_fsuse(db, parse_current, ast_node);
 		*finished = CIL_TREE_SKIP_NEXT;
diff --git a/libsepol/cil/src/cil_build_ast.h b/libsepol/cil/src/cil_build_ast.h
index 1bd33ce..43bc7f6 100644
--- a/libsepol/cil/src/cil_build_ast.h
+++ b/libsepol/cil/src/cil_build_ast.h
@@ -182,6 +182,8 @@ int cil_gen_ioportcon(struct cil_db *db, struct cil_tree_node *parse_current, st
 void cil_destroy_ioportcon(struct cil_ioportcon *ioportcon);
 int cil_gen_pcidevicecon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
 void cil_destroy_pcidevicecon(struct cil_pcidevicecon *pcidevicecon);
+int cil_gen_devicetreecon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
+void cil_destroy_devicetreecon(struct cil_devicetreecon *devicetreecon);
 int cil_gen_fsuse(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
 void cil_destroy_fsuse(struct cil_fsuse *fsuse);
 void cil_destroy_param(struct cil_param *param);
diff --git a/libsepol/cil/src/cil_copy_ast.c b/libsepol/cil/src/cil_copy_ast.c
index 5a24555..199ce1c 100644
--- a/libsepol/cil/src/cil_copy_ast.c
+++ b/libsepol/cil/src/cil_copy_ast.c
@@ -1211,6 +1211,27 @@ int cil_copy_pcidevicecon(struct cil_db *db, void *data, void **copy, __attribut
 	return SEPOL_OK;
 }
 
+int cil_copy_devicetreecon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
+{
+	struct cil_devicetreecon *orig = data;
+	struct cil_devicetreecon *new = NULL;
+
+	cil_devicetreecon_init(&new);
+
+	new->path = orig->path;
+
+	if (orig->context_str != NULL) {
+		new->context_str = orig->context_str;
+	} else {
+		cil_context_init(&new->context);
+		cil_copy_fill_context(db, orig->context, new->context);
+	}
+
+	*copy = new;
+
+	return SEPOL_OK;
+}
+
 int cil_copy_fsuse(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
 {
 	struct cil_fsuse *orig = data;
@@ -1780,6 +1801,9 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u
 	case CIL_PCIDEVICECON:
 		copy_func = &cil_copy_pcidevicecon;
 		break;
+	case CIL_DEVICETREECON:
+		copy_func = &cil_copy_devicetreecon;
+		break;
 	case CIL_FSUSE:
 		copy_func = &cil_copy_fsuse;
 		break;
diff --git a/libsepol/cil/src/cil_flavor.h b/libsepol/cil/src/cil_flavor.h
index 7295b19..d839f68 100644
--- a/libsepol/cil/src/cil_flavor.h
+++ b/libsepol/cil/src/cil_flavor.h
@@ -102,6 +102,7 @@ enum cil_flavor {
 	CIL_IOMEMCON,
 	CIL_IOPORTCON,
 	CIL_PCIDEVICECON,
+	CIL_DEVICETREECON,
 	CIL_DEFAULTUSER,
 	CIL_DEFAULTROLE,
 	CIL_DEFAULTTYPE,
diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h
index 11a2085..a43d111 100644
--- a/libsepol/cil/src/cil_internal.h
+++ b/libsepol/cil/src/cil_internal.h
@@ -206,6 +206,7 @@ char *CIL_KEY_PIRQCON;
 char *CIL_KEY_IOMEMCON;
 char *CIL_KEY_IOPORTCON;
 char *CIL_KEY_PCIDEVICECON;
+char *CIL_KEY_DEVICETREECON;
 char *CIL_KEY_FSUSE;
 char *CIL_KEY_POLICYCAP;
 char *CIL_KEY_OPTIONAL;
@@ -273,6 +274,7 @@ struct cil_db {
 	struct cil_sort *iomemcon;
 	struct cil_sort *ioportcon;
 	struct cil_sort *pcidevicecon;
+	struct cil_sort *devicetreecon;
 	struct cil_sort *fsuse;
 	struct cil_list *userprefixes;
 	struct cil_list *selinuxusers;
@@ -738,6 +740,13 @@ struct cil_pcidevicecon {
 	struct cil_context *context;
 };
 
+struct cil_devicetreecon {
+	char *path;
+	char *context_str;
+	struct cil_context *context;
+};
+
+
 /* Ensure that CIL uses the same values as sepol services.h */
 enum cil_fsuse_types {
 	CIL_FSUSE_XATTR = SECURITY_FS_USE_XATTR,
@@ -933,6 +942,7 @@ void cil_pirqcon_init(struct cil_pirqcon **pirqcon);
 void cil_iomemcon_init(struct cil_iomemcon **iomemcon);
 void cil_ioportcon_init(struct cil_ioportcon **ioportcon);
 void cil_pcidevicecon_init(struct cil_pcidevicecon **pcidevicecon);
+void cil_devicetreecon_init(struct cil_devicetreecon **devicetreecon);
 void cil_fsuse_init(struct cil_fsuse **fsuse);
 void cil_constrain_init(struct cil_constrain **constrain);
 void cil_validatetrans_init(struct cil_validatetrans **validtrans);
diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
index e89f16b..633a5a1 100644
--- a/libsepol/cil/src/cil_post.c
+++ b/libsepol/cil/src/cil_post.c
@@ -296,6 +296,17 @@ int cil_post_pcidevicecon_compare(const void *a, const void *b)
 	return rc;
 }
 
+int cil_post_devicetreecon_compare(const void *a, const void *b)
+{
+	int rc = SEPOL_ERR;
+	struct cil_devicetreecon *adevicetreecon = *(struct cil_devicetreecon**)a;
+	struct cil_devicetreecon *bdevicetreecon = *(struct cil_devicetreecon**)b;
+
+	rc = strcmp(adevicetreecon->path, bdevicetreecon->path);
+
+	return rc;
+}
+
 int cil_post_fsuse_compare(const void *a, const void *b)
 {
 	int rc;
@@ -377,6 +388,9 @@ static int __cil_post_db_count_helper(struct cil_tree_node *node, uint32_t *fini
 	case CIL_PCIDEVICECON:
 		db->pcidevicecon->count++;
 		break;	
+	case CIL_DEVICETREECON:
+		db->devicetreecon->count++;
+		break;
 	case CIL_FSUSE:
 		db->fsuse->count++;
 		break;
@@ -540,6 +554,17 @@ static int __cil_post_db_array_helper(struct cil_tree_node *node, __attribute__(
 		sort->index++;
 		break;
 	}
+	case CIL_DEVICETREECON: {
+		struct cil_sort *sort = db->devicetreecon;
+		uint32_t count = sort->count;
+		uint32_t i = sort->index;
+		if (sort->array == NULL) {
+			sort->array = cil_malloc(sizeof(*sort->array)*count);
+		}
+		sort->array[i] = node->data;
+		sort->index++;
+		break;
+	}
 	default:
 		break;
 	}
@@ -1305,6 +1330,14 @@ static int __cil_post_db_cat_helper(struct cil_tree_node *node, uint32_t *finish
 		}
 		break;
 	}
+	case CIL_DEVICETREECON: {
+		struct cil_devicetreecon *devicetreecon = node->data;
+		rc = __evaluate_levelrange_expression(devicetreecon->context->range, db);
+		if (rc != SEPOL_OK) {
+			goto exit;
+		}
+		break;
+	}
 	case CIL_FSUSE: {
 		struct cil_fsuse *fsuse = node->data;
 		rc = __evaluate_levelrange_expression(fsuse->context->range, db);
@@ -1590,6 +1623,7 @@ static int cil_post_db(struct cil_db *db)
 	qsort(db->iomemcon->array, db->iomemcon->count, sizeof(db->iomemcon->array), cil_post_iomemcon_compare);
 	qsort(db->ioportcon->array, db->ioportcon->count, sizeof(db->ioportcon->array), cil_post_ioportcon_compare);
 	qsort(db->pcidevicecon->array, db->pcidevicecon->count, sizeof(db->pcidevicecon->array), cil_post_pcidevicecon_compare);
+	qsort(db->devicetreecon->array, db->devicetreecon->count, sizeof(db->devicetreecon->array), cil_post_devicetreecon_compare);
 
 exit:
 	return rc;
diff --git a/libsepol/cil/src/cil_reset_ast.c b/libsepol/cil/src/cil_reset_ast.c
index 170e612..92f7720 100644
--- a/libsepol/cil/src/cil_reset_ast.c
+++ b/libsepol/cil/src/cil_reset_ast.c
@@ -323,6 +323,13 @@ static void cil_reset_pcidevicecon(struct cil_pcidevicecon *pcidevicecon)
 	}
 }
 
+static void cil_reset_devicetreecon(struct cil_devicetreecon *devicetreecon)
+{
+	if (devicetreecon->context_str == NULL) {
+		cil_reset_context(devicetreecon->context);
+	}
+}
+
 static void cil_reset_fsuse(struct cil_fsuse *fsuse)
 {
 	if (fsuse->context_str == NULL) {
@@ -475,6 +482,9 @@ int __cil_reset_node(struct cil_tree_node *node,  __attribute__((unused)) uint32
 	case CIL_PCIDEVICECON:
 		cil_reset_pcidevicecon(node->data);
 		break;
+	case CIL_DEVICETREECON:
+		cil_reset_devicetreecon(node->data);
+		break;
 	case CIL_FSUSE:
 		cil_reset_fsuse(node->data);
 		break;
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
index e27f965..7d46fd5 100644
--- a/libsepol/cil/src/cil_resolve_ast.c
+++ b/libsepol/cil/src/cil_resolve_ast.c
@@ -1969,6 +1969,31 @@ exit:
 	return rc;
 }
 
+int cil_resolve_devicetreecon(struct cil_tree_node *current, void *extra_args)
+{
+	struct cil_devicetreecon *devicetreecon = current->data;
+	struct cil_symtab_datum *context_datum = NULL;
+	int rc = SEPOL_ERR;
+
+	if (devicetreecon->context_str != NULL) {
+		rc = cil_resolve_name(current, devicetreecon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum);
+		if (rc != SEPOL_OK) {
+			goto exit;
+		}
+		devicetreecon->context = (struct cil_context*)context_datum;
+	} else {
+		rc = cil_resolve_context(current, devicetreecon->context, extra_args);
+		if (rc != SEPOL_OK) {
+			goto exit;
+		}
+	}
+
+	return SEPOL_OK;
+
+exit:
+	return rc;
+}
+
 int cil_resolve_fsuse(struct cil_tree_node *current, void *extra_args)
 {
 	struct cil_fsuse *fsuse = current->data;
@@ -3185,6 +3210,9 @@ int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
 		case CIL_PCIDEVICECON:
 			rc = cil_resolve_pcidevicecon(node, args);
 			break;
+		case CIL_DEVICETREECON:
+			rc = cil_resolve_devicetreecon(node, args);
+			break;
 		case CIL_FSUSE:
 			rc = cil_resolve_fsuse(node, args);
 			break;
diff --git a/libsepol/cil/src/cil_tree.c b/libsepol/cil/src/cil_tree.c
index 81a1abc..6a731f2 100644
--- a/libsepol/cil/src/cil_tree.c
+++ b/libsepol/cil/src/cil_tree.c
@@ -1429,6 +1429,19 @@ void cil_tree_print_node(struct cil_tree_node *node)
 			cil_log(CIL_INFO, "\n");
 			return;
 		}
+		case CIL_DEVICETREECON: {
+			struct cil_devicetreecon *devicetreecon = node->data;
+
+			cil_log(CIL_INFO, "DEVICETREECON %s", devicetreecon->path);
+			if (devicetreecon->context != NULL) {
+				cil_tree_print_context(devicetreecon->context);
+			} else {
+				cil_log(CIL_INFO, " %s", devicetreecon->context_str);
+			}
+
+			cil_log(CIL_INFO, "\n");
+			return;
+		}
 		case CIL_FSUSE: {
 			struct cil_fsuse *fsuse = node->data;
 			cil_log(CIL_INFO, "FSUSE: ");
diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c
index 03e0fd1..399c94a 100644
--- a/libsepol/cil/src/cil_verify.c
+++ b/libsepol/cil/src/cil_verify.c
@@ -1181,6 +1181,27 @@ exit:
 	return rc;
 }
 
+int __cil_verify_devicetreecon(struct cil_db *db, struct cil_tree_node *node)
+{
+	int rc = SEPOL_ERR;
+	struct cil_devicetreecon *dt = node->data;
+	struct cil_context *ctx = dt->context;
+
+	/* Verify only when anonymous */
+	if (ctx->datum.name == NULL) {
+		rc = __cil_verify_context(db, ctx);
+		if (rc != SEPOL_OK) {
+			goto exit;
+		}
+	}
+
+	return SEPOL_OK;
+
+exit:
+	cil_log(CIL_ERR, "Invalid devicetreecon at line %d of %s\n", node->line, node->path);
+	return rc;
+}
+
 int __cil_verify_fsuse(struct cil_db *db, struct cil_tree_node *node)
 {
 	int rc = SEPOL_ERR;
@@ -1390,6 +1411,9 @@ int __cil_verify_helper(struct cil_tree_node *node, uint32_t *finished, void *ex
 		case CIL_PCIDEVICECON:
 			rc = __cil_verify_pcidevicecon(db, node);
 			break;
+		case CIL_DEVICETREECON:
+			rc = __cil_verify_devicetreecon(db, node);
+			break;
 		case CIL_FSUSE:
 			rc = __cil_verify_fsuse(db, node);
 			break;
diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h
index 946cbaf..31efc3a 100644
--- a/libsepol/include/sepol/policydb/policydb.h
+++ b/libsepol/include/sepol/policydb/policydb.h
@@ -375,6 +375,7 @@ typedef struct genfs {
 #define OCON_XEN_IOPORT     2    /* io ports */
 #define OCON_XEN_IOMEM	    3    /* io memory */
 #define OCON_XEN_PCIDEVICE  4    /* pci devices */
+#define OCON_XEN_DEVICETREE 5    /* device tree node */
 
 /* OCON_NUM needs to be the largest index in any platform's ocontext array */
 #define OCON_NUM   7
diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
index 3193ef5..a8b1115 100644
--- a/libsepol/src/expand.c
+++ b/libsepol/src/expand.c
@@ -2091,6 +2091,13 @@ static int ocontext_copy_xen(expand_state_t *state)
 			case OCON_XEN_PCIDEVICE:
 				n->u.device = c->u.device;
 				break;
+			case OCON_XEN_DEVICETREE:
+				n->u.name = strdup(c->u.name);
+				if (!n->u.name) {
+					ERR(state->handle, "Out of memory!");
+					return -1;
+				}
+				break;
 			default:
 				/* shouldn't get here */
 				ERR(state->handle, "Unknown ocontext");
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index d54eb9e..b45b662 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -70,7 +70,7 @@ static struct policydb_compat_info policydb_compat[] = {
 	 .type = POLICY_KERN,
 	 .version = POLICYDB_VERSION_XEN_DEVICETREE,
 	 .sym_num = SYM_NUM,
-	 .ocon_num = OCON_XEN_PCIDEVICE + 1,
+	 .ocon_num = OCON_XEN_DEVICETREE + 1,
 	 .target_platform = SEPOL_TARGET_XEN,
 	 },
 	{
@@ -2478,7 +2478,7 @@ static int ocontext_read_xen(struct policydb_compat_info *info,
 	policydb_t *p, struct policy_file *fp)
 {
 	unsigned int i, j;
-	size_t nel;
+	size_t nel, len;
 	ocontext_t *l, *c;
 	uint32_t buf[8];
 	int rc;
@@ -2555,6 +2555,20 @@ static int ocontext_read_xen(struct policydb_compat_info *info,
 				    (&c->context[0], p, fp))
 					return -1;
 				break;
+			case OCON_XEN_DEVICETREE:
+				rc = next_entry(buf, fp, sizeof(uint32_t));
+				if (rc < 0)
+					return -1;
+				len = le32_to_cpu(buf[1]);
+				c->u.name = malloc(len + 1);
+				if (!c->u.name)
+					return -1;
+				rc = next_entry(c->u.name, fp, len);
+				c->u.name[len] = 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");
diff --git a/libsepol/src/write.c b/libsepol/src/write.c
index 3452017..c97a4da 100644
--- a/libsepol/src/write.c
+++ b/libsepol/src/write.c
@@ -1211,7 +1211,7 @@ 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;
+	size_t nel, items, len;
 	uint32_t buf[32];
 	ocontext_t *c;
 	for (i = 0; i < info->ocon_num; i++) {
@@ -1288,6 +1288,18 @@ static int ocontext_write_xen(struct policydb_compat_info *info, policydb_t *p,
 				if (context_write(p, &c->context[0], fp))
 					return POLICYDB_ERROR;
 				break;
+			case OCON_XEN_DEVICETREE:
+				len = strlen(c->u.name);
+				buf[0] = cpu_to_le32(len);
+				items = put_entry(buf, sizeof(uint32_t), 1, fp);
+				if (items != 1)
+					return POLICYDB_ERROR;
+				items = put_entry(c->u.name, 1, len, fp);
+				if (items != len)
+					return POLICYDB_ERROR;
+				if (context_write(p, &c->context[0], fp))
+					return POLICYDB_ERROR;
+				break;
 			}
 		}
 	}
diff --git a/sepolgen/src/sepolgen/refparser.py b/sepolgen/src/sepolgen/refparser.py
index b453a29..83542d3 100644
--- a/sepolgen/src/sepolgen/refparser.py
+++ b/sepolgen/src/sepolgen/refparser.py
@@ -88,6 +88,7 @@ tokens = (
     'IOMEMCON',
     'IOPORTCON',
     'PCIDEVICECON',
+    'DEVICETREECON',
     #   object classes
     'CLASS',
     #   types and attributes
@@ -152,6 +153,7 @@ reserved = {
     'iomemcon' : 'IOMEMCON',
     'ioportcon' : 'IOPORTCON',
     'pcidevicecon' : 'PCIDEVICECON',
+    'devicetreecon' : 'DEVICETREECON',
     # object classes
     'class' : 'CLASS',
     # types and attributes
@@ -524,6 +526,7 @@ def p_policy_stmt(p):
                    | iomemcon
                    | ioportcon
                    | pcidevicecon
+                   | devicetreecon
     '''
     if p[1]:
         p[0] = [p[1]]
@@ -703,6 +706,14 @@ def p_pcidevicecon(p):
 
     p[0] = c
 
+def p_devicetreecon(p):
+    'devicetreecon : DEVICETREECON NUMBER context'
+    c = refpolicy.DevicetTeeCon()
+    c.path = 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 8ad64a9..b8ed5c1 100644
--- a/sepolgen/src/sepolgen/refpolicy.py
+++ b/sepolgen/src/sepolgen/refpolicy.py
@@ -687,6 +687,15 @@ class PciDeviceCon(Leaf):
     def to_string(self):
         return "pcidevicecon %s %s" % (self.device, str(self.context))
 
+class DeviceTreeCon(Leaf):
+    def __init__(self, parent=None):
+        Leaf.__init__(self, parent)
+        self.path = ""
+        self.context = None
+
+    def to_string(self):
+        return "devicetreecon %s %s" % (self.path, str(self.context))
+
 # Reference policy specific types
 
 def print_tree(head):
-- 
2.1.0

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

* [PATCH 3/3] libsepol, checkpolicy: add device tree ocontext nodes to Xen policy
@ 2015-03-17 20:43   ` Daniel De Graaf
  0 siblings, 0 replies; 14+ messages in thread
From: Daniel De Graaf @ 2015-03-17 20:43 UTC (permalink / raw)
  To: selinux; +Cc: xen-devel, Daniel De Graaf

In Xen on ARM, device tree nodes identified by a path (string) need to
be labeled by the security policy.

Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
---
 checkpolicy/policy_define.c                | 55 +++++++++++++++++++++++++
 checkpolicy/policy_define.h                |  1 +
 checkpolicy/policy_parse.y                 |  8 +++-
 checkpolicy/policy_scan.l                  |  2 +
 libsepol/cil/src/cil.c                     | 17 ++++++++
 libsepol/cil/src/cil_binary.c              | 29 +++++++++++++
 libsepol/cil/src/cil_build_ast.c           | 66 ++++++++++++++++++++++++++++++
 libsepol/cil/src/cil_build_ast.h           |  2 +
 libsepol/cil/src/cil_copy_ast.c            | 24 +++++++++++
 libsepol/cil/src/cil_flavor.h              |  1 +
 libsepol/cil/src/cil_internal.h            | 10 +++++
 libsepol/cil/src/cil_post.c                | 34 +++++++++++++++
 libsepol/cil/src/cil_reset_ast.c           | 10 +++++
 libsepol/cil/src/cil_resolve_ast.c         | 28 +++++++++++++
 libsepol/cil/src/cil_tree.c                | 13 ++++++
 libsepol/cil/src/cil_verify.c              | 24 +++++++++++
 libsepol/include/sepol/policydb/policydb.h |  1 +
 libsepol/src/expand.c                      |  7 ++++
 libsepol/src/policydb.c                    | 18 +++++++-
 libsepol/src/write.c                       | 14 ++++++-
 sepolgen/src/sepolgen/refparser.py         | 11 +++++
 sepolgen/src/sepolgen/refpolicy.py         |  9 ++++
 22 files changed, 379 insertions(+), 5 deletions(-)

diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c
index 66c1ff2..de01f6f 100644
--- a/checkpolicy/policy_define.c
+++ b/checkpolicy/policy_define.c
@@ -4116,6 +4116,61 @@ bad:
 	return -1;
 }
 
+int define_devicetree_context()
+{
+	ocontext_t *newc, *c, *l, *head;
+
+	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
+		yyerror("devicetreecon not supported for target");
+		return -1;
+	}
+
+	if (pass == 1) {
+		free(queue_remove(id_queue));
+		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.name = (char *)queue_remove(id_queue);
+	if (!newc->u.name) {
+		free(newc);
+		return -1;
+	}
+
+	if (parse_security_context(&newc->context[0])) {
+		free(newc->u.name);
+		free(newc);
+		return -1;
+	}
+
+	head = policydbp->ocontexts[OCON_XEN_DEVICETREE];
+	for (l = NULL, c = head; c; l = c, c = c->next) {
+		if (strcmp(newc->u.name, c->u.name) == 0) {
+			yyerror2("duplicate devicetree entry for '%s'", newc->u.name);
+			goto bad;
+		}
+	}
+
+	if (l)
+		l->next = newc;
+	else
+		policydbp->ocontexts[OCON_XEN_DEVICETREE] = newc;
+
+	return 0;
+
+bad:
+	free(newc->u.name);
+	free(newc);
+	return -1;
+}
+
 int define_port_context(unsigned int low, unsigned int high)
 {
 	ocontext_t *newc, *c, *l, *head;
diff --git a/checkpolicy/policy_define.h b/checkpolicy/policy_define.h
index 14d30e1..a87ced3 100644
--- a/checkpolicy/policy_define.h
+++ b/checkpolicy/policy_define.h
@@ -49,6 +49,7 @@ int define_pirq_context(unsigned int pirq);
 int define_iomem_context(uint64_t low, uint64_t high);
 int define_ioport_context(unsigned long low, unsigned long high);
 int define_pcidevice_context(unsigned long device);
+int define_devicetree_context(void);
 int define_range_trans(int class_specified);
 int define_role_allow(void);
 int define_role_trans(int class_specified);
diff --git a/checkpolicy/policy_parse.y b/checkpolicy/policy_parse.y
index e3899b9..8b81f04 100644
--- a/checkpolicy/policy_parse.y
+++ b/checkpolicy/policy_parse.y
@@ -130,7 +130,7 @@ typedef int (* require_func_t)(int pass);
 %token TARGET
 %token SAMEUSER
 %token FSCON PORTCON NETIFCON NODECON 
-%token PIRQCON IOMEMCON IOPORTCON PCIDEVICECON
+%token PIRQCON IOMEMCON IOPORTCON PCIDEVICECON DEVICETREECON
 %token FSUSEXATTR FSUSETASK FSUSETRANS
 %token GENFSCON
 %token U1 U2 U3 R1 R2 R3 T1 T2 T3 L1 L2 H1 H2
@@ -644,7 +644,8 @@ dev_contexts		: dev_context_def
 dev_context_def		: pirq_context_def |
 			  iomem_context_def |
 			  ioport_context_def |
-			  pci_context_def
+			  pci_context_def |
+			  dtree_context_def
 			;
 pirq_context_def 	: PIRQCON number security_context_def
 		        {if (define_pirq_context($2)) return -1;}
@@ -662,6 +663,9 @@ ioport_context_def	: IOPORTCON number security_context_def
 pci_context_def  	: PCIDEVICECON number security_context_def
 		        {if (define_pcidevice_context($2)) return -1;}
 		        ;
+dtree_context_def	: DEVICETREECON path security_context_def
+		        {if (define_devicetree_context()) return -1;}
+		        ;
 opt_fs_contexts         : fs_contexts 
                         |
                         ;
diff --git a/checkpolicy/policy_scan.l b/checkpolicy/policy_scan.l
index 6763c38..108edbc 100644
--- a/checkpolicy/policy_scan.l
+++ b/checkpolicy/policy_scan.l
@@ -187,6 +187,8 @@ ioportcon |
 IOPORTCON           		{ return(IOPORTCON);}
 pcidevicecon |
 PCIDEVICECON           		{ return(PCIDEVICECON);}
+devicetreecon |
+DEVICETREECON           	{ return(DEVICETREECON);}
 fs_use_xattr |
 FS_USE_XATTR			{ return(FSUSEXATTR);}
 fs_use_task |
diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
index a25f878..1594be6 100644
--- a/libsepol/cil/src/cil.c
+++ b/libsepol/cil/src/cil.c
@@ -189,6 +189,7 @@ static void cil_init_keys(void)
 	CIL_KEY_IOMEMCON = cil_strpool_add("iomemcon");
 	CIL_KEY_IOPORTCON = cil_strpool_add("ioportcon");
 	CIL_KEY_PCIDEVICECON = cil_strpool_add("pcidevicecon");
+	CIL_KEY_DEVICETREECON = cil_strpool_add("devicetreecon");
 	CIL_KEY_FSUSE = cil_strpool_add("fsuse");
 	CIL_KEY_POLICYCAP = cil_strpool_add("policycap");
 	CIL_KEY_OPTIONAL = cil_strpool_add("optional");
@@ -244,6 +245,7 @@ void cil_db_init(struct cil_db **db)
 	cil_sort_init(&(*db)->iomemcon);
 	cil_sort_init(&(*db)->ioportcon);
 	cil_sort_init(&(*db)->pcidevicecon);
+	cil_sort_init(&(*db)->devicetreecon);
 	cil_sort_init(&(*db)->fsuse);
 	cil_list_init(&(*db)->userprefixes, CIL_LIST_ITEM);
 	cil_list_init(&(*db)->selinuxusers, CIL_LIST_ITEM);
@@ -289,6 +291,7 @@ void cil_db_destroy(struct cil_db **db)
 	cil_sort_destroy(&(*db)->iomemcon);
 	cil_sort_destroy(&(*db)->ioportcon);
 	cil_sort_destroy(&(*db)->pcidevicecon);
+	cil_sort_destroy(&(*db)->devicetreecon);
 	cil_sort_destroy(&(*db)->fsuse);
 	cil_list_destroy(&(*db)->userprefixes, CIL_FALSE);
 	cil_list_destroy(&(*db)->selinuxusers, CIL_FALSE);
@@ -697,6 +700,9 @@ void cil_destroy_data(void **data, enum cil_flavor flavor)
 	case CIL_PCIDEVICECON:
 		cil_destroy_pcidevicecon(*data);
 		break;
+	case CIL_DEVICETREECON:
+		cil_destroy_devicetreecon(*data);
+		break;
 	case CIL_POLICYCAP:
 		cil_destroy_policycap(*data);
 		break;
@@ -1026,6 +1032,8 @@ const char * cil_node_to_string(struct cil_tree_node *node)
 		return CIL_KEY_IOPORTCON;
 	case CIL_PCIDEVICECON:
 		return CIL_KEY_PCIDEVICECON;
+	case CIL_DEVICETREECON:
+		return CIL_KEY_DEVICETREECON;
 	case CIL_POLICYCAP:
 		return CIL_KEY_POLICYCAP;
 	case CIL_DEFAULTUSER:
@@ -2181,6 +2189,15 @@ void cil_pcidevicecon_init(struct cil_pcidevicecon **pcidevicecon)
 	(*pcidevicecon)->context = NULL;
 }
 
+void cil_devicetreecon_init(struct cil_devicetreecon **dtcon)
+{
+	*dtcon = cil_malloc(sizeof(**dtcon));
+
+	(*dtcon)->path = NULL;
+	(*dtcon)->context_str = NULL;
+	(*dtcon)->context = NULL;
+}
+
 void cil_fsuse_init(struct cil_fsuse **fsuse)
 {
 	*fsuse = cil_malloc(sizeof(**fsuse));
diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
index 387237f..03f4924 100644
--- a/libsepol/cil/src/cil_binary.c
+++ b/libsepol/cil/src/cil_binary.c
@@ -2993,6 +2993,30 @@ exit:
 	return rc;
 }
 
+int cil_devicetreecon_to_policydb(policydb_t *pdb, struct cil_sort *devicetreecons)
+{
+	int rc = SEPOL_ERR;
+	uint32_t i = 0;
+	ocontext_t *tail = NULL;
+
+	for (i = 0; i < devicetreecons->count; i++) {
+		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_DEVICETREE], &tail);
+		struct cil_devicetreecon *cil_devicetreecon = devicetreecons->array[i];
+
+		new_ocon->u.name = cil_strdup(cil_devicetreecon->path);
+
+		rc = __cil_context_to_sepol_context(pdb, cil_devicetreecon->context, &new_ocon->context[0]);
+		if (rc != SEPOL_OK) {
+			goto exit;
+		}
+	}
+
+	return SEPOL_OK;
+
+exit:
+	return rc;
+}
+
 int cil_default_to_policydb(policydb_t *pdb, struct cil_default *def)
 {
 	struct cil_list_item *curr;
@@ -3340,6 +3364,11 @@ int __cil_contexts_to_policydb(policydb_t *pdb, const struct cil_db *db)
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
+
+		rc = cil_devicetreecon_to_policydb(pdb, db->devicetreecon);
+		if (rc != SEPOL_OK) {
+			goto exit;
+		}
 	}
 	return SEPOL_OK;
 exit:
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
index 1949d2b..d4ef73c 100644
--- a/libsepol/cil/src/cil_build_ast.c
+++ b/libsepol/cil/src/cil_build_ast.c
@@ -4529,6 +4529,69 @@ void cil_destroy_pcidevicecon(struct cil_pcidevicecon *pcidevicecon)
 	free(pcidevicecon);
 }
 
+int cil_gen_devicetreecon(__attribute__((unused)) struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node)
+{
+	enum cil_syntax syntax[] = {
+		CIL_SYN_STRING,
+		CIL_SYN_STRING,
+		CIL_SYN_STRING | CIL_SYN_LIST,
+		CIL_SYN_END
+	};
+	int syntax_len = sizeof(syntax)/sizeof(*syntax);
+	int rc = SEPOL_ERR;
+	struct cil_devicetreecon *devicetreecon = NULL;
+
+	if (db == NULL || parse_current == NULL || ast_node == NULL) {
+		goto exit;
+	}
+
+	rc = __cil_verify_syntax(parse_current, syntax, syntax_len);
+	if (rc != SEPOL_OK) {
+		goto exit;
+	}
+
+	cil_devicetreecon_init(&devicetreecon);
+
+	devicetreecon->path = parse_current->next->data;
+
+	if (parse_current->next->next->cl_head == NULL) {
+		devicetreecon->context_str = parse_current->next->next->data;
+	} else {
+		cil_context_init(&devicetreecon->context);
+
+		rc = cil_fill_context(parse_current->next->next->cl_head, devicetreecon->context);
+		if (rc != SEPOL_OK) {
+			goto exit;
+		}
+	}
+
+	ast_node->data = devicetreecon;
+	ast_node->flavor = CIL_DEVICETREECON;
+
+	return SEPOL_OK;
+
+exit:
+	cil_log(CIL_ERR, "Bad devicetreecon declaration at line %d of %s\n", 
+		parse_current->line, parse_current->path);
+	cil_destroy_devicetreecon(devicetreecon);
+	return rc;
+}
+
+void cil_destroy_devicetreecon(struct cil_devicetreecon *devicetreecon)
+{
+	if (devicetreecon == NULL) {
+		return;
+	}
+
+	free(devicetreecon->path);
+
+	if (devicetreecon->context_str == NULL && devicetreecon->context != NULL) {
+		cil_destroy_context(devicetreecon->context);
+	}
+
+	free(devicetreecon);
+}
+
 int cil_gen_fsuse(__attribute__((unused)) struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node)
 {
 	enum cil_syntax syntax[] = {
@@ -5806,6 +5869,9 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
 	} else if (parse_current->data == CIL_KEY_PCIDEVICECON) {
 		rc = cil_gen_pcidevicecon(db, parse_current, ast_node);
 		*finished = CIL_TREE_SKIP_NEXT;
+	} else if (parse_current->data == CIL_KEY_DEVICETREECON) {
+		rc = cil_gen_devicetreecon(db, parse_current, ast_node);
+		*finished = CIL_TREE_SKIP_NEXT;
 	} else if (parse_current->data == CIL_KEY_FSUSE) {
 		rc = cil_gen_fsuse(db, parse_current, ast_node);
 		*finished = CIL_TREE_SKIP_NEXT;
diff --git a/libsepol/cil/src/cil_build_ast.h b/libsepol/cil/src/cil_build_ast.h
index 1bd33ce..43bc7f6 100644
--- a/libsepol/cil/src/cil_build_ast.h
+++ b/libsepol/cil/src/cil_build_ast.h
@@ -182,6 +182,8 @@ int cil_gen_ioportcon(struct cil_db *db, struct cil_tree_node *parse_current, st
 void cil_destroy_ioportcon(struct cil_ioportcon *ioportcon);
 int cil_gen_pcidevicecon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
 void cil_destroy_pcidevicecon(struct cil_pcidevicecon *pcidevicecon);
+int cil_gen_devicetreecon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
+void cil_destroy_devicetreecon(struct cil_devicetreecon *devicetreecon);
 int cil_gen_fsuse(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
 void cil_destroy_fsuse(struct cil_fsuse *fsuse);
 void cil_destroy_param(struct cil_param *param);
diff --git a/libsepol/cil/src/cil_copy_ast.c b/libsepol/cil/src/cil_copy_ast.c
index 5a24555..199ce1c 100644
--- a/libsepol/cil/src/cil_copy_ast.c
+++ b/libsepol/cil/src/cil_copy_ast.c
@@ -1211,6 +1211,27 @@ int cil_copy_pcidevicecon(struct cil_db *db, void *data, void **copy, __attribut
 	return SEPOL_OK;
 }
 
+int cil_copy_devicetreecon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
+{
+	struct cil_devicetreecon *orig = data;
+	struct cil_devicetreecon *new = NULL;
+
+	cil_devicetreecon_init(&new);
+
+	new->path = orig->path;
+
+	if (orig->context_str != NULL) {
+		new->context_str = orig->context_str;
+	} else {
+		cil_context_init(&new->context);
+		cil_copy_fill_context(db, orig->context, new->context);
+	}
+
+	*copy = new;
+
+	return SEPOL_OK;
+}
+
 int cil_copy_fsuse(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
 {
 	struct cil_fsuse *orig = data;
@@ -1780,6 +1801,9 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u
 	case CIL_PCIDEVICECON:
 		copy_func = &cil_copy_pcidevicecon;
 		break;
+	case CIL_DEVICETREECON:
+		copy_func = &cil_copy_devicetreecon;
+		break;
 	case CIL_FSUSE:
 		copy_func = &cil_copy_fsuse;
 		break;
diff --git a/libsepol/cil/src/cil_flavor.h b/libsepol/cil/src/cil_flavor.h
index 7295b19..d839f68 100644
--- a/libsepol/cil/src/cil_flavor.h
+++ b/libsepol/cil/src/cil_flavor.h
@@ -102,6 +102,7 @@ enum cil_flavor {
 	CIL_IOMEMCON,
 	CIL_IOPORTCON,
 	CIL_PCIDEVICECON,
+	CIL_DEVICETREECON,
 	CIL_DEFAULTUSER,
 	CIL_DEFAULTROLE,
 	CIL_DEFAULTTYPE,
diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h
index 11a2085..a43d111 100644
--- a/libsepol/cil/src/cil_internal.h
+++ b/libsepol/cil/src/cil_internal.h
@@ -206,6 +206,7 @@ char *CIL_KEY_PIRQCON;
 char *CIL_KEY_IOMEMCON;
 char *CIL_KEY_IOPORTCON;
 char *CIL_KEY_PCIDEVICECON;
+char *CIL_KEY_DEVICETREECON;
 char *CIL_KEY_FSUSE;
 char *CIL_KEY_POLICYCAP;
 char *CIL_KEY_OPTIONAL;
@@ -273,6 +274,7 @@ struct cil_db {
 	struct cil_sort *iomemcon;
 	struct cil_sort *ioportcon;
 	struct cil_sort *pcidevicecon;
+	struct cil_sort *devicetreecon;
 	struct cil_sort *fsuse;
 	struct cil_list *userprefixes;
 	struct cil_list *selinuxusers;
@@ -738,6 +740,13 @@ struct cil_pcidevicecon {
 	struct cil_context *context;
 };
 
+struct cil_devicetreecon {
+	char *path;
+	char *context_str;
+	struct cil_context *context;
+};
+
+
 /* Ensure that CIL uses the same values as sepol services.h */
 enum cil_fsuse_types {
 	CIL_FSUSE_XATTR = SECURITY_FS_USE_XATTR,
@@ -933,6 +942,7 @@ void cil_pirqcon_init(struct cil_pirqcon **pirqcon);
 void cil_iomemcon_init(struct cil_iomemcon **iomemcon);
 void cil_ioportcon_init(struct cil_ioportcon **ioportcon);
 void cil_pcidevicecon_init(struct cil_pcidevicecon **pcidevicecon);
+void cil_devicetreecon_init(struct cil_devicetreecon **devicetreecon);
 void cil_fsuse_init(struct cil_fsuse **fsuse);
 void cil_constrain_init(struct cil_constrain **constrain);
 void cil_validatetrans_init(struct cil_validatetrans **validtrans);
diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
index e89f16b..633a5a1 100644
--- a/libsepol/cil/src/cil_post.c
+++ b/libsepol/cil/src/cil_post.c
@@ -296,6 +296,17 @@ int cil_post_pcidevicecon_compare(const void *a, const void *b)
 	return rc;
 }
 
+int cil_post_devicetreecon_compare(const void *a, const void *b)
+{
+	int rc = SEPOL_ERR;
+	struct cil_devicetreecon *adevicetreecon = *(struct cil_devicetreecon**)a;
+	struct cil_devicetreecon *bdevicetreecon = *(struct cil_devicetreecon**)b;
+
+	rc = strcmp(adevicetreecon->path, bdevicetreecon->path);
+
+	return rc;
+}
+
 int cil_post_fsuse_compare(const void *a, const void *b)
 {
 	int rc;
@@ -377,6 +388,9 @@ static int __cil_post_db_count_helper(struct cil_tree_node *node, uint32_t *fini
 	case CIL_PCIDEVICECON:
 		db->pcidevicecon->count++;
 		break;	
+	case CIL_DEVICETREECON:
+		db->devicetreecon->count++;
+		break;
 	case CIL_FSUSE:
 		db->fsuse->count++;
 		break;
@@ -540,6 +554,17 @@ static int __cil_post_db_array_helper(struct cil_tree_node *node, __attribute__(
 		sort->index++;
 		break;
 	}
+	case CIL_DEVICETREECON: {
+		struct cil_sort *sort = db->devicetreecon;
+		uint32_t count = sort->count;
+		uint32_t i = sort->index;
+		if (sort->array == NULL) {
+			sort->array = cil_malloc(sizeof(*sort->array)*count);
+		}
+		sort->array[i] = node->data;
+		sort->index++;
+		break;
+	}
 	default:
 		break;
 	}
@@ -1305,6 +1330,14 @@ static int __cil_post_db_cat_helper(struct cil_tree_node *node, uint32_t *finish
 		}
 		break;
 	}
+	case CIL_DEVICETREECON: {
+		struct cil_devicetreecon *devicetreecon = node->data;
+		rc = __evaluate_levelrange_expression(devicetreecon->context->range, db);
+		if (rc != SEPOL_OK) {
+			goto exit;
+		}
+		break;
+	}
 	case CIL_FSUSE: {
 		struct cil_fsuse *fsuse = node->data;
 		rc = __evaluate_levelrange_expression(fsuse->context->range, db);
@@ -1590,6 +1623,7 @@ static int cil_post_db(struct cil_db *db)
 	qsort(db->iomemcon->array, db->iomemcon->count, sizeof(db->iomemcon->array), cil_post_iomemcon_compare);
 	qsort(db->ioportcon->array, db->ioportcon->count, sizeof(db->ioportcon->array), cil_post_ioportcon_compare);
 	qsort(db->pcidevicecon->array, db->pcidevicecon->count, sizeof(db->pcidevicecon->array), cil_post_pcidevicecon_compare);
+	qsort(db->devicetreecon->array, db->devicetreecon->count, sizeof(db->devicetreecon->array), cil_post_devicetreecon_compare);
 
 exit:
 	return rc;
diff --git a/libsepol/cil/src/cil_reset_ast.c b/libsepol/cil/src/cil_reset_ast.c
index 170e612..92f7720 100644
--- a/libsepol/cil/src/cil_reset_ast.c
+++ b/libsepol/cil/src/cil_reset_ast.c
@@ -323,6 +323,13 @@ static void cil_reset_pcidevicecon(struct cil_pcidevicecon *pcidevicecon)
 	}
 }
 
+static void cil_reset_devicetreecon(struct cil_devicetreecon *devicetreecon)
+{
+	if (devicetreecon->context_str == NULL) {
+		cil_reset_context(devicetreecon->context);
+	}
+}
+
 static void cil_reset_fsuse(struct cil_fsuse *fsuse)
 {
 	if (fsuse->context_str == NULL) {
@@ -475,6 +482,9 @@ int __cil_reset_node(struct cil_tree_node *node,  __attribute__((unused)) uint32
 	case CIL_PCIDEVICECON:
 		cil_reset_pcidevicecon(node->data);
 		break;
+	case CIL_DEVICETREECON:
+		cil_reset_devicetreecon(node->data);
+		break;
 	case CIL_FSUSE:
 		cil_reset_fsuse(node->data);
 		break;
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
index e27f965..7d46fd5 100644
--- a/libsepol/cil/src/cil_resolve_ast.c
+++ b/libsepol/cil/src/cil_resolve_ast.c
@@ -1969,6 +1969,31 @@ exit:
 	return rc;
 }
 
+int cil_resolve_devicetreecon(struct cil_tree_node *current, void *extra_args)
+{
+	struct cil_devicetreecon *devicetreecon = current->data;
+	struct cil_symtab_datum *context_datum = NULL;
+	int rc = SEPOL_ERR;
+
+	if (devicetreecon->context_str != NULL) {
+		rc = cil_resolve_name(current, devicetreecon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum);
+		if (rc != SEPOL_OK) {
+			goto exit;
+		}
+		devicetreecon->context = (struct cil_context*)context_datum;
+	} else {
+		rc = cil_resolve_context(current, devicetreecon->context, extra_args);
+		if (rc != SEPOL_OK) {
+			goto exit;
+		}
+	}
+
+	return SEPOL_OK;
+
+exit:
+	return rc;
+}
+
 int cil_resolve_fsuse(struct cil_tree_node *current, void *extra_args)
 {
 	struct cil_fsuse *fsuse = current->data;
@@ -3185,6 +3210,9 @@ int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
 		case CIL_PCIDEVICECON:
 			rc = cil_resolve_pcidevicecon(node, args);
 			break;
+		case CIL_DEVICETREECON:
+			rc = cil_resolve_devicetreecon(node, args);
+			break;
 		case CIL_FSUSE:
 			rc = cil_resolve_fsuse(node, args);
 			break;
diff --git a/libsepol/cil/src/cil_tree.c b/libsepol/cil/src/cil_tree.c
index 81a1abc..6a731f2 100644
--- a/libsepol/cil/src/cil_tree.c
+++ b/libsepol/cil/src/cil_tree.c
@@ -1429,6 +1429,19 @@ void cil_tree_print_node(struct cil_tree_node *node)
 			cil_log(CIL_INFO, "\n");
 			return;
 		}
+		case CIL_DEVICETREECON: {
+			struct cil_devicetreecon *devicetreecon = node->data;
+
+			cil_log(CIL_INFO, "DEVICETREECON %s", devicetreecon->path);
+			if (devicetreecon->context != NULL) {
+				cil_tree_print_context(devicetreecon->context);
+			} else {
+				cil_log(CIL_INFO, " %s", devicetreecon->context_str);
+			}
+
+			cil_log(CIL_INFO, "\n");
+			return;
+		}
 		case CIL_FSUSE: {
 			struct cil_fsuse *fsuse = node->data;
 			cil_log(CIL_INFO, "FSUSE: ");
diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c
index 03e0fd1..399c94a 100644
--- a/libsepol/cil/src/cil_verify.c
+++ b/libsepol/cil/src/cil_verify.c
@@ -1181,6 +1181,27 @@ exit:
 	return rc;
 }
 
+int __cil_verify_devicetreecon(struct cil_db *db, struct cil_tree_node *node)
+{
+	int rc = SEPOL_ERR;
+	struct cil_devicetreecon *dt = node->data;
+	struct cil_context *ctx = dt->context;
+
+	/* Verify only when anonymous */
+	if (ctx->datum.name == NULL) {
+		rc = __cil_verify_context(db, ctx);
+		if (rc != SEPOL_OK) {
+			goto exit;
+		}
+	}
+
+	return SEPOL_OK;
+
+exit:
+	cil_log(CIL_ERR, "Invalid devicetreecon at line %d of %s\n", node->line, node->path);
+	return rc;
+}
+
 int __cil_verify_fsuse(struct cil_db *db, struct cil_tree_node *node)
 {
 	int rc = SEPOL_ERR;
@@ -1390,6 +1411,9 @@ int __cil_verify_helper(struct cil_tree_node *node, uint32_t *finished, void *ex
 		case CIL_PCIDEVICECON:
 			rc = __cil_verify_pcidevicecon(db, node);
 			break;
+		case CIL_DEVICETREECON:
+			rc = __cil_verify_devicetreecon(db, node);
+			break;
 		case CIL_FSUSE:
 			rc = __cil_verify_fsuse(db, node);
 			break;
diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h
index 946cbaf..31efc3a 100644
--- a/libsepol/include/sepol/policydb/policydb.h
+++ b/libsepol/include/sepol/policydb/policydb.h
@@ -375,6 +375,7 @@ typedef struct genfs {
 #define OCON_XEN_IOPORT     2    /* io ports */
 #define OCON_XEN_IOMEM	    3    /* io memory */
 #define OCON_XEN_PCIDEVICE  4    /* pci devices */
+#define OCON_XEN_DEVICETREE 5    /* device tree node */
 
 /* OCON_NUM needs to be the largest index in any platform's ocontext array */
 #define OCON_NUM   7
diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
index 3193ef5..a8b1115 100644
--- a/libsepol/src/expand.c
+++ b/libsepol/src/expand.c
@@ -2091,6 +2091,13 @@ static int ocontext_copy_xen(expand_state_t *state)
 			case OCON_XEN_PCIDEVICE:
 				n->u.device = c->u.device;
 				break;
+			case OCON_XEN_DEVICETREE:
+				n->u.name = strdup(c->u.name);
+				if (!n->u.name) {
+					ERR(state->handle, "Out of memory!");
+					return -1;
+				}
+				break;
 			default:
 				/* shouldn't get here */
 				ERR(state->handle, "Unknown ocontext");
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index d54eb9e..b45b662 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -70,7 +70,7 @@ static struct policydb_compat_info policydb_compat[] = {
 	 .type = POLICY_KERN,
 	 .version = POLICYDB_VERSION_XEN_DEVICETREE,
 	 .sym_num = SYM_NUM,
-	 .ocon_num = OCON_XEN_PCIDEVICE + 1,
+	 .ocon_num = OCON_XEN_DEVICETREE + 1,
 	 .target_platform = SEPOL_TARGET_XEN,
 	 },
 	{
@@ -2478,7 +2478,7 @@ static int ocontext_read_xen(struct policydb_compat_info *info,
 	policydb_t *p, struct policy_file *fp)
 {
 	unsigned int i, j;
-	size_t nel;
+	size_t nel, len;
 	ocontext_t *l, *c;
 	uint32_t buf[8];
 	int rc;
@@ -2555,6 +2555,20 @@ static int ocontext_read_xen(struct policydb_compat_info *info,
 				    (&c->context[0], p, fp))
 					return -1;
 				break;
+			case OCON_XEN_DEVICETREE:
+				rc = next_entry(buf, fp, sizeof(uint32_t));
+				if (rc < 0)
+					return -1;
+				len = le32_to_cpu(buf[1]);
+				c->u.name = malloc(len + 1);
+				if (!c->u.name)
+					return -1;
+				rc = next_entry(c->u.name, fp, len);
+				c->u.name[len] = 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");
diff --git a/libsepol/src/write.c b/libsepol/src/write.c
index 3452017..c97a4da 100644
--- a/libsepol/src/write.c
+++ b/libsepol/src/write.c
@@ -1211,7 +1211,7 @@ 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;
+	size_t nel, items, len;
 	uint32_t buf[32];
 	ocontext_t *c;
 	for (i = 0; i < info->ocon_num; i++) {
@@ -1288,6 +1288,18 @@ static int ocontext_write_xen(struct policydb_compat_info *info, policydb_t *p,
 				if (context_write(p, &c->context[0], fp))
 					return POLICYDB_ERROR;
 				break;
+			case OCON_XEN_DEVICETREE:
+				len = strlen(c->u.name);
+				buf[0] = cpu_to_le32(len);
+				items = put_entry(buf, sizeof(uint32_t), 1, fp);
+				if (items != 1)
+					return POLICYDB_ERROR;
+				items = put_entry(c->u.name, 1, len, fp);
+				if (items != len)
+					return POLICYDB_ERROR;
+				if (context_write(p, &c->context[0], fp))
+					return POLICYDB_ERROR;
+				break;
 			}
 		}
 	}
diff --git a/sepolgen/src/sepolgen/refparser.py b/sepolgen/src/sepolgen/refparser.py
index b453a29..83542d3 100644
--- a/sepolgen/src/sepolgen/refparser.py
+++ b/sepolgen/src/sepolgen/refparser.py
@@ -88,6 +88,7 @@ tokens = (
     'IOMEMCON',
     'IOPORTCON',
     'PCIDEVICECON',
+    'DEVICETREECON',
     #   object classes
     'CLASS',
     #   types and attributes
@@ -152,6 +153,7 @@ reserved = {
     'iomemcon' : 'IOMEMCON',
     'ioportcon' : 'IOPORTCON',
     'pcidevicecon' : 'PCIDEVICECON',
+    'devicetreecon' : 'DEVICETREECON',
     # object classes
     'class' : 'CLASS',
     # types and attributes
@@ -524,6 +526,7 @@ def p_policy_stmt(p):
                    | iomemcon
                    | ioportcon
                    | pcidevicecon
+                   | devicetreecon
     '''
     if p[1]:
         p[0] = [p[1]]
@@ -703,6 +706,14 @@ def p_pcidevicecon(p):
 
     p[0] = c
 
+def p_devicetreecon(p):
+    'devicetreecon : DEVICETREECON NUMBER context'
+    c = refpolicy.DevicetTeeCon()
+    c.path = 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 8ad64a9..b8ed5c1 100644
--- a/sepolgen/src/sepolgen/refpolicy.py
+++ b/sepolgen/src/sepolgen/refpolicy.py
@@ -687,6 +687,15 @@ class PciDeviceCon(Leaf):
     def to_string(self):
         return "pcidevicecon %s %s" % (self.device, str(self.context))
 
+class DeviceTreeCon(Leaf):
+    def __init__(self, parent=None):
+        Leaf.__init__(self, parent)
+        self.path = ""
+        self.context = None
+
+    def to_string(self):
+        return "devicetreecon %s %s" % (self.path, str(self.context))
+
 # Reference policy specific types
 
 def print_tree(head):
-- 
2.1.0

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

* Re: [PATCH v3 0/3] Xen/FLASK policy updates for device contexts
  2015-03-17 20:43 [PATCH v3 0/3] Xen/FLASK policy updates for device contexts Daniel De Graaf
                   ` (2 preceding siblings ...)
  2015-03-17 20:43   ` Daniel De Graaf
@ 2015-03-18 12:38 ` Stephen Smalley
  2015-03-20 16:59 ` Richard Haines
  2015-03-20 16:59 ` Richard Haines
  5 siblings, 0 replies; 14+ messages in thread
From: Stephen Smalley @ 2015-03-18 12:38 UTC (permalink / raw)
  To: Daniel De Graaf, selinux; +Cc: xen-devel

On 03/17/2015 04:43 PM, Daniel De Graaf wrote:
> In order to support assigning security lables to ARM device tree nodes
> in Xen's XSM policy, a new ocontext type is needed in the security
> policy.
> 
> In addition to adding the new ocontext, the existing I/O memory range
> ocontext is expanded to 64 bits in order to support hardware with more
> than 44 bits of physical address space (32-bit count of 4K pages).
> 
> Changes from v2:
>  - Clean up printf format strings for 32-bit builds
> 
> Changes from v1:
>  - Use policy version 30 instead of forking the version numbers for Xen;
>    this removes the need for v1's patch 3.
>  - Report an error when attempting to use an I/O memory range that
>    requires a 64-bit representation with an old policy output version
>    that cannot support this
>  - Fix a few incorrect references to PCIDEVICECON
>  - Reorder patches to clarify the allowed characterset of device tree
>    paths
> 
> [PATCH 1/3] checkpolicy: Expand allowed character set in paths
> [PATCH 2/3] libsepol, checkpolicy: widen Xen IOMEM ocontext entries
> [PATCH 3/3] libsepol, checkpolicy: add device tree ocontext nodes to

Thanks, applied all three.

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

* Re: [PATCH v3 0/3] Xen/FLASK policy updates for device contexts
  2015-03-17 20:43 [PATCH v3 0/3] Xen/FLASK policy updates for device contexts Daniel De Graaf
                   ` (4 preceding siblings ...)
  2015-03-20 16:59 ` Richard Haines
@ 2015-03-20 16:59 ` Richard Haines
  2015-03-23 13:20   ` Steve Lawrence
  2015-03-23 13:20   ` Steve Lawrence
  5 siblings, 2 replies; 14+ messages in thread
From: Richard Haines @ 2015-03-20 16:59 UTC (permalink / raw)
  To: Daniel De Graaf, selinux; +Cc: xen-devel

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

I've been testing this and found a few problems:

1) I could not read a policy with sedispol (in the checkpolicy/test directory)
    when the devicetreecon statement was included (checkpolicy built ok).
    I've attached a patch that fixes this problem and included CIL Ref Guide
   updates for the new features.

2) When building policy with the CIL compiler secilc I get core dumps but
    only if I include the devicetreecon statement. I think its related to not releasing
    the devicetreepath "path" when sepol_policydb_free is called. I've been
    trying to track it down and failed - any ideas !!!
   sedispol will read the generated CIL policy with the above fix applied.


Richard



----- Original Message -----
> From: Daniel De Graaf <dgdegra@tycho.nsa.gov>
> To: selinux@tycho.nsa.gov
> Cc: xen-devel@lists.xenproject.org
> Sent: Tuesday, 17 March 2015, 20:43
> Subject: [PATCH v3 0/3] Xen/FLASK policy updates for device contexts
> 
> In order to support assigning security lables to ARM device tree nodes
> in Xen's XSM policy, a new ocontext type is needed in the security
> policy.
> 
> In addition to adding the new ocontext, the existing I/O memory range
> ocontext is expanded to 64 bits in order to support hardware with more
> than 44 bits of physical address space (32-bit count of 4K pages).
> 
> Changes from v2:
> - Clean up printf format strings for 32-bit builds
> 
> Changes from v1:
> - Use policy version 30 instead of forking the version numbers for Xen;
>    this removes the need for v1's patch 3.
> - Report an error when attempting to use an I/O memory range that
>    requires a 64-bit representation with an old policy output version
>    that cannot support this
> - Fix a few incorrect references to PCIDEVICECON
> - Reorder patches to clarify the allowed characterset of device tree
>    paths
> 
> [PATCH 1/3] checkpolicy: Expand allowed character set in paths
> [PATCH 2/3] libsepol, checkpolicy: widen Xen IOMEM ocontext entries
> [PATCH 3/3] libsepol, checkpolicy: add device tree ocontext nodes to
> _______________________________________________
> Selinux mailing list
> Selinux@tycho.nsa.gov
> To unsubscribe, send email to Selinux-leave@tycho.nsa.gov.
> To get help, send an email containing "help" to 
> Selinux-request@tycho.nsa.gov.
> 

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-libsepol-Fix-reading-Xen-policy-with-devicetreecon.patch --]
[-- Type: text/x-patch; name="0001-libsepol-Fix-reading-Xen-policy-with-devicetreecon.patch", Size: 5041 bytes --]

From 12f17f0022784a7b57aa355dc8c4e5c8d4b9a99d Mon Sep 17 00:00:00 2001
From: Richard Haines <richard_c_haines@btinternet.com>
Date: Fri, 20 Mar 2015 14:18:31 +0000
Subject: [PATCH] libsepol: Fix reading Xen policy with devicetreecon

Policy failed to read with devicetreecon statement.

Added devicetreecon statement to CIL policy.cil and updated the CIL
Reference Guide.

Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
---
 libsepol/cil/docs/cil_xen_statements.xml | 44 ++++++++++++++++++++++++++++++++
 libsepol/cil/test/policy.cil             |  1 +
 libsepol/src/policydb.c                  |  4 ++-
 3 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/libsepol/cil/docs/cil_xen_statements.xml b/libsepol/cil/docs/cil_xen_statements.xml
index 1035b68..45865c6 100644
--- a/libsepol/cil/docs/cil_xen_statements.xml
+++ b/libsepol/cil/docs/cil_xen_statements.xml
@@ -3,6 +3,7 @@
 
    <sect1>
       <title>Xen Statements</title>
+      <para>Policy version 30 introduced the <literal><link linkend="devicetreecon">context</link></literal> statement and also expanded the existing I/O memory range to 64 bits in order to support hardware with more than 44 bits of physical address space (32-bit count of 4K pages).</para>
       <para>See the <ulink url="http://xenbits.xen.org/docs/4.2-testing/misc/xsm-flask.txt">"XSM/FLASK Configuration"</ulink> document for further information (<ulink url="http://xenbits.xen.org/docs/4.2-testing/misc/xsm-flask.txt"></ulink>)</para>
       <sect2 id="iomemcon">
          <title>iomemcon</title>
@@ -180,4 +181,47 @@
          <programlisting><![CDATA[(pirqcon 33 (unconfined.user object_r unconfined.object low_low))]]></programlisting>
       </sect2>
 
+      <sect2 id="devicetreecon">
+         <title>devicetreecon</title>
+         <para>Label device tree nodes.</para>
+         <para><emphasis role="bold">Statement definition:</emphasis></para>
+         <programlisting><![CDATA[(devicetreecon path context_id)]]></programlisting>
+         <para><emphasis role="bold">Where:</emphasis></para>
+         <informaltable frame="all">
+            <tgroup cols="2">
+            <colspec colwidth="2 *"/>
+            <colspec colwidth="6 *"/>
+               <tbody>
+               <row>
+                  <entry>
+                     <para><literal>devicetreecon</literal></para>
+                  </entry>
+                  <entry>
+                     <para>The <literal>devicetreecon</literal> keyword.</para>
+                  </entry>
+               </row>
+               <row>
+                  <entry>
+                     <para><literal>path</literal></para>
+                  </entry>
+                  <entry>
+                     <para>The device tree path. If this contains spaces enclose within <literal>""</literal>.</para>
+                  </entry>
+               </row>
+               <row>
+                  <entry>
+                     <para><literal>context_id</literal></para>
+                  </entry>
+                  <entry>
+                     <para>A previously declared <literal><link linkend="context">context</link></literal> identifier or an anonymous security context (<literal><link linkend="user">user</link> <link linkend="role">role</link> <link linkend="type">type</link> <link linkend="levelrange">levelrange</link></literal>), the range MUST be defined whether the policy is MLS/MCS enabled or not.</para>
+                  </entry>
+               </row>
+            </tbody></tgroup>
+         </informaltable>
+
+         <para><emphasis role="bold">Example:</emphasis></para>
+         <para>An anonymous context for the specified path:</para>
+         <programlisting><![CDATA[(devicetreecon "/this is/a/path" (unconfined.user object_r unconfined.object low_low))]]></programlisting>
+      </sect2>
+
    </sect1>
diff --git a/libsepol/cil/test/policy.cil b/libsepol/cil/test/policy.cil
index 9c76cad..25c8545 100644
--- a/libsepol/cil/test/policy.cil
+++ b/libsepol/cil/test/policy.cil
@@ -250,6 +250,7 @@
 	(iomemcon (0 255) system_u_bin_t_l2h)
 	(ioportcon (22 22) system_u_bin_t_l2h)
 	(pcidevicecon 345 system_u_bin_t_l2h)
+	(devicetreecon "/this is/a/path" system_u_bin_t_l2h)
 
 	(constrain (files (read)) (not (or (and (eq t1 exec_t) (eq t2 bin_t)) (eq r1 r2))))
 	(constrain char_w (not (or (and (eq t1 exec_t) (eq t2 bin_t)) (eq r1 r2))))
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index b45b662..ceac33d 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -2559,11 +2559,13 @@ static int ocontext_read_xen(struct policydb_compat_info *info,
 				rc = next_entry(buf, fp, sizeof(uint32_t));
 				if (rc < 0)
 					return -1;
-				len = le32_to_cpu(buf[1]);
+				len = le32_to_cpu(buf[0]);
 				c->u.name = malloc(len + 1);
 				if (!c->u.name)
 					return -1;
 				rc = next_entry(c->u.name, fp, len);
+				if (rc < 0)
+					return -1;
 				c->u.name[len] = 0;
 				if (context_read_and_validate
 				    (&c->context[0], p, fp))
-- 
2.1.0


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

* Re: [PATCH v3 0/3] Xen/FLASK policy updates for device contexts
  2015-03-17 20:43 [PATCH v3 0/3] Xen/FLASK policy updates for device contexts Daniel De Graaf
                   ` (3 preceding siblings ...)
  2015-03-18 12:38 ` [PATCH v3 0/3] Xen/FLASK policy updates for device contexts Stephen Smalley
@ 2015-03-20 16:59 ` Richard Haines
  2015-03-20 16:59 ` Richard Haines
  5 siblings, 0 replies; 14+ messages in thread
From: Richard Haines @ 2015-03-20 16:59 UTC (permalink / raw)
  To: Daniel De Graaf, selinux; +Cc: xen-devel

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

I've been testing this and found a few problems:

1) I could not read a policy with sedispol (in the checkpolicy/test directory)
    when the devicetreecon statement was included (checkpolicy built ok).
    I've attached a patch that fixes this problem and included CIL Ref Guide
   updates for the new features.

2) When building policy with the CIL compiler secilc I get core dumps but
    only if I include the devicetreecon statement. I think its related to not releasing
    the devicetreepath "path" when sepol_policydb_free is called. I've been
    trying to track it down and failed - any ideas !!!
   sedispol will read the generated CIL policy with the above fix applied.


Richard



----- Original Message -----
> From: Daniel De Graaf <dgdegra@tycho.nsa.gov>
> To: selinux@tycho.nsa.gov
> Cc: xen-devel@lists.xenproject.org
> Sent: Tuesday, 17 March 2015, 20:43
> Subject: [PATCH v3 0/3] Xen/FLASK policy updates for device contexts
> 
> In order to support assigning security lables to ARM device tree nodes
> in Xen's XSM policy, a new ocontext type is needed in the security
> policy.
> 
> In addition to adding the new ocontext, the existing I/O memory range
> ocontext is expanded to 64 bits in order to support hardware with more
> than 44 bits of physical address space (32-bit count of 4K pages).
> 
> Changes from v2:
> - Clean up printf format strings for 32-bit builds
> 
> Changes from v1:
> - Use policy version 30 instead of forking the version numbers for Xen;
>    this removes the need for v1's patch 3.
> - Report an error when attempting to use an I/O memory range that
>    requires a 64-bit representation with an old policy output version
>    that cannot support this
> - Fix a few incorrect references to PCIDEVICECON
> - Reorder patches to clarify the allowed characterset of device tree
>    paths
> 
> [PATCH 1/3] checkpolicy: Expand allowed character set in paths
> [PATCH 2/3] libsepol, checkpolicy: widen Xen IOMEM ocontext entries
> [PATCH 3/3] libsepol, checkpolicy: add device tree ocontext nodes to
> _______________________________________________
> Selinux mailing list
> Selinux@tycho.nsa.gov
> To unsubscribe, send email to Selinux-leave@tycho.nsa.gov.
> To get help, send an email containing "help" to 
> Selinux-request@tycho.nsa.gov.
> 

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-libsepol-Fix-reading-Xen-policy-with-devicetreecon.patch --]
[-- Type: text/x-patch; name="0001-libsepol-Fix-reading-Xen-policy-with-devicetreecon.patch", Size: 5041 bytes --]

From 12f17f0022784a7b57aa355dc8c4e5c8d4b9a99d Mon Sep 17 00:00:00 2001
From: Richard Haines <richard_c_haines@btinternet.com>
Date: Fri, 20 Mar 2015 14:18:31 +0000
Subject: [PATCH] libsepol: Fix reading Xen policy with devicetreecon

Policy failed to read with devicetreecon statement.

Added devicetreecon statement to CIL policy.cil and updated the CIL
Reference Guide.

Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
---
 libsepol/cil/docs/cil_xen_statements.xml | 44 ++++++++++++++++++++++++++++++++
 libsepol/cil/test/policy.cil             |  1 +
 libsepol/src/policydb.c                  |  4 ++-
 3 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/libsepol/cil/docs/cil_xen_statements.xml b/libsepol/cil/docs/cil_xen_statements.xml
index 1035b68..45865c6 100644
--- a/libsepol/cil/docs/cil_xen_statements.xml
+++ b/libsepol/cil/docs/cil_xen_statements.xml
@@ -3,6 +3,7 @@
 
    <sect1>
       <title>Xen Statements</title>
+      <para>Policy version 30 introduced the <literal><link linkend="devicetreecon">context</link></literal> statement and also expanded the existing I/O memory range to 64 bits in order to support hardware with more than 44 bits of physical address space (32-bit count of 4K pages).</para>
       <para>See the <ulink url="http://xenbits.xen.org/docs/4.2-testing/misc/xsm-flask.txt">"XSM/FLASK Configuration"</ulink> document for further information (<ulink url="http://xenbits.xen.org/docs/4.2-testing/misc/xsm-flask.txt"></ulink>)</para>
       <sect2 id="iomemcon">
          <title>iomemcon</title>
@@ -180,4 +181,47 @@
          <programlisting><![CDATA[(pirqcon 33 (unconfined.user object_r unconfined.object low_low))]]></programlisting>
       </sect2>
 
+      <sect2 id="devicetreecon">
+         <title>devicetreecon</title>
+         <para>Label device tree nodes.</para>
+         <para><emphasis role="bold">Statement definition:</emphasis></para>
+         <programlisting><![CDATA[(devicetreecon path context_id)]]></programlisting>
+         <para><emphasis role="bold">Where:</emphasis></para>
+         <informaltable frame="all">
+            <tgroup cols="2">
+            <colspec colwidth="2 *"/>
+            <colspec colwidth="6 *"/>
+               <tbody>
+               <row>
+                  <entry>
+                     <para><literal>devicetreecon</literal></para>
+                  </entry>
+                  <entry>
+                     <para>The <literal>devicetreecon</literal> keyword.</para>
+                  </entry>
+               </row>
+               <row>
+                  <entry>
+                     <para><literal>path</literal></para>
+                  </entry>
+                  <entry>
+                     <para>The device tree path. If this contains spaces enclose within <literal>""</literal>.</para>
+                  </entry>
+               </row>
+               <row>
+                  <entry>
+                     <para><literal>context_id</literal></para>
+                  </entry>
+                  <entry>
+                     <para>A previously declared <literal><link linkend="context">context</link></literal> identifier or an anonymous security context (<literal><link linkend="user">user</link> <link linkend="role">role</link> <link linkend="type">type</link> <link linkend="levelrange">levelrange</link></literal>), the range MUST be defined whether the policy is MLS/MCS enabled or not.</para>
+                  </entry>
+               </row>
+            </tbody></tgroup>
+         </informaltable>
+
+         <para><emphasis role="bold">Example:</emphasis></para>
+         <para>An anonymous context for the specified path:</para>
+         <programlisting><![CDATA[(devicetreecon "/this is/a/path" (unconfined.user object_r unconfined.object low_low))]]></programlisting>
+      </sect2>
+
    </sect1>
diff --git a/libsepol/cil/test/policy.cil b/libsepol/cil/test/policy.cil
index 9c76cad..25c8545 100644
--- a/libsepol/cil/test/policy.cil
+++ b/libsepol/cil/test/policy.cil
@@ -250,6 +250,7 @@
 	(iomemcon (0 255) system_u_bin_t_l2h)
 	(ioportcon (22 22) system_u_bin_t_l2h)
 	(pcidevicecon 345 system_u_bin_t_l2h)
+	(devicetreecon "/this is/a/path" system_u_bin_t_l2h)
 
 	(constrain (files (read)) (not (or (and (eq t1 exec_t) (eq t2 bin_t)) (eq r1 r2))))
 	(constrain char_w (not (or (and (eq t1 exec_t) (eq t2 bin_t)) (eq r1 r2))))
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index b45b662..ceac33d 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -2559,11 +2559,13 @@ static int ocontext_read_xen(struct policydb_compat_info *info,
 				rc = next_entry(buf, fp, sizeof(uint32_t));
 				if (rc < 0)
 					return -1;
-				len = le32_to_cpu(buf[1]);
+				len = le32_to_cpu(buf[0]);
 				c->u.name = malloc(len + 1);
 				if (!c->u.name)
 					return -1;
 				rc = next_entry(c->u.name, fp, len);
+				if (rc < 0)
+					return -1;
 				c->u.name[len] = 0;
 				if (context_read_and_validate
 				    (&c->context[0], p, fp))
-- 
2.1.0


[-- Attachment #3: Type: text/plain, Size: 126 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

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

* Re: [PATCH v3 0/3] Xen/FLASK policy updates for device contexts
  2015-03-20 16:59 ` Richard Haines
  2015-03-23 13:20   ` Steve Lawrence
@ 2015-03-23 13:20   ` Steve Lawrence
  2015-03-23 14:22     ` Richard Haines
  2015-03-23 14:22     ` Richard Haines
  1 sibling, 2 replies; 14+ messages in thread
From: Steve Lawrence @ 2015-03-23 13:20 UTC (permalink / raw)
  To: Richard Haines, Daniel De Graaf, selinux; +Cc: xen-devel

I think there may be a typo in the documentation update. It says:

Policy version 30 introduced the <literal><link
linkend="devicetreecon">context</link></literal>

Should "context" be "devicetreecon"?

Otherwise, this patch looks good to me.

As far as issue 2, I think I've tracked it down to an errant free() in
cil_destroy_devicetreecon. CIL uses string interning to reduce the
amount of memory used, so strings rarely need to be free'd. And if they
are, it results in a double free when the string intern pool is
destroyed. The below patch should fix it. Can you give it a test and
make sure it works for you?

- Steve


diff --git a/libsepol/cil/src/cil_build_ast.c
b/libsepol/cil/src/cil_build_ast.c
index 973b2d7..92c3e09 100644
--- a/libsepol/cil/src/cil_build_ast.c
+++ b/libsepol/cil/src/cil_build_ast.c
@@ -4583,8 +4583,6 @@ void cil_destroy_devicetreecon(struct
cil_devicetreecon *devicetreecon)
 		return;
 	}

-	free(devicetreecon->path);
-
 	if (devicetreecon->context_str == NULL && devicetreecon->context !=
NULL) {
 		cil_destroy_context(devicetreecon->context);
 	}



On 03/20/2015 12:59 PM, Richard Haines wrote:
> I've been testing this and found a few problems:
> 
> 1) I could not read a policy with sedispol (in the checkpolicy/test directory)
>     when the devicetreecon statement was included (checkpolicy built ok).
>     I've attached a patch that fixes this problem and included CIL Ref Guide
>    updates for the new features.
> 
> 2) When building policy with the CIL compiler secilc I get core dumps but
>     only if I include the devicetreecon statement. I think its related to not releasing
>     the devicetreepath "path" when sepol_policydb_free is called. I've been
>     trying to track it down and failed - any ideas !!!
>    sedispol will read the generated CIL policy with the above fix applied.
> 
> 
> Richard
> 
> 
> 
> ----- Original Message -----
>> From: Daniel De Graaf <dgdegra@tycho.nsa.gov>
>> To: selinux@tycho.nsa.gov
>> Cc: xen-devel@lists.xenproject.org
>> Sent: Tuesday, 17 March 2015, 20:43
>> Subject: [PATCH v3 0/3] Xen/FLASK policy updates for device contexts
>>
>> In order to support assigning security lables to ARM device tree nodes
>> in Xen's XSM policy, a new ocontext type is needed in the security
>> policy.
>>
>> In addition to adding the new ocontext, the existing I/O memory range
>> ocontext is expanded to 64 bits in order to support hardware with more
>> than 44 bits of physical address space (32-bit count of 4K pages).
>>
>> Changes from v2:
>> - Clean up printf format strings for 32-bit builds
>>
>> Changes from v1:
>> - Use policy version 30 instead of forking the version numbers for Xen;
>>    this removes the need for v1's patch 3.
>> - Report an error when attempting to use an I/O memory range that
>>    requires a 64-bit representation with an old policy output version
>>    that cannot support this
>> - Fix a few incorrect references to PCIDEVICECON
>> - Reorder patches to clarify the allowed characterset of device tree
>>    paths
>>
>> [PATCH 1/3] checkpolicy: Expand allowed character set in paths
>> [PATCH 2/3] libsepol, checkpolicy: widen Xen IOMEM ocontext entries
>> [PATCH 3/3] libsepol, checkpolicy: add device tree ocontext nodes to
>> _______________________________________________
>> Selinux mailing list
>> Selinux@tycho.nsa.gov
>> To unsubscribe, send email to Selinux-leave@tycho.nsa.gov.
>> To get help, send an email containing "help" to 
>> Selinux-request@tycho.nsa.gov.
>>
>>
>> _______________________________________________
>> Selinux mailing list
>> Selinux@tycho.nsa.gov
>> To unsubscribe, send email to Selinux-leave@tycho.nsa.gov.
>> To get help, send an email containing "help" to Selinux-request@tycho.nsa.gov.

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

* Re: [PATCH v3 0/3] Xen/FLASK policy updates for device contexts
  2015-03-20 16:59 ` Richard Haines
@ 2015-03-23 13:20   ` Steve Lawrence
  2015-03-23 13:20   ` Steve Lawrence
  1 sibling, 0 replies; 14+ messages in thread
From: Steve Lawrence @ 2015-03-23 13:20 UTC (permalink / raw)
  To: Richard Haines, Daniel De Graaf, selinux; +Cc: xen-devel

I think there may be a typo in the documentation update. It says:

Policy version 30 introduced the <literal><link
linkend="devicetreecon">context</link></literal>

Should "context" be "devicetreecon"?

Otherwise, this patch looks good to me.

As far as issue 2, I think I've tracked it down to an errant free() in
cil_destroy_devicetreecon. CIL uses string interning to reduce the
amount of memory used, so strings rarely need to be free'd. And if they
are, it results in a double free when the string intern pool is
destroyed. The below patch should fix it. Can you give it a test and
make sure it works for you?

- Steve


diff --git a/libsepol/cil/src/cil_build_ast.c
b/libsepol/cil/src/cil_build_ast.c
index 973b2d7..92c3e09 100644
--- a/libsepol/cil/src/cil_build_ast.c
+++ b/libsepol/cil/src/cil_build_ast.c
@@ -4583,8 +4583,6 @@ void cil_destroy_devicetreecon(struct
cil_devicetreecon *devicetreecon)
 		return;
 	}

-	free(devicetreecon->path);
-
 	if (devicetreecon->context_str == NULL && devicetreecon->context !=
NULL) {
 		cil_destroy_context(devicetreecon->context);
 	}



On 03/20/2015 12:59 PM, Richard Haines wrote:
> I've been testing this and found a few problems:
> 
> 1) I could not read a policy with sedispol (in the checkpolicy/test directory)
>     when the devicetreecon statement was included (checkpolicy built ok).
>     I've attached a patch that fixes this problem and included CIL Ref Guide
>    updates for the new features.
> 
> 2) When building policy with the CIL compiler secilc I get core dumps but
>     only if I include the devicetreecon statement. I think its related to not releasing
>     the devicetreepath "path" when sepol_policydb_free is called. I've been
>     trying to track it down and failed - any ideas !!!
>    sedispol will read the generated CIL policy with the above fix applied.
> 
> 
> Richard
> 
> 
> 
> ----- Original Message -----
>> From: Daniel De Graaf <dgdegra@tycho.nsa.gov>
>> To: selinux@tycho.nsa.gov
>> Cc: xen-devel@lists.xenproject.org
>> Sent: Tuesday, 17 March 2015, 20:43
>> Subject: [PATCH v3 0/3] Xen/FLASK policy updates for device contexts
>>
>> In order to support assigning security lables to ARM device tree nodes
>> in Xen's XSM policy, a new ocontext type is needed in the security
>> policy.
>>
>> In addition to adding the new ocontext, the existing I/O memory range
>> ocontext is expanded to 64 bits in order to support hardware with more
>> than 44 bits of physical address space (32-bit count of 4K pages).
>>
>> Changes from v2:
>> - Clean up printf format strings for 32-bit builds
>>
>> Changes from v1:
>> - Use policy version 30 instead of forking the version numbers for Xen;
>>    this removes the need for v1's patch 3.
>> - Report an error when attempting to use an I/O memory range that
>>    requires a 64-bit representation with an old policy output version
>>    that cannot support this
>> - Fix a few incorrect references to PCIDEVICECON
>> - Reorder patches to clarify the allowed characterset of device tree
>>    paths
>>
>> [PATCH 1/3] checkpolicy: Expand allowed character set in paths
>> [PATCH 2/3] libsepol, checkpolicy: widen Xen IOMEM ocontext entries
>> [PATCH 3/3] libsepol, checkpolicy: add device tree ocontext nodes to
>> _______________________________________________
>> Selinux mailing list
>> Selinux@tycho.nsa.gov
>> To unsubscribe, send email to Selinux-leave@tycho.nsa.gov.
>> To get help, send an email containing "help" to 
>> Selinux-request@tycho.nsa.gov.
>>
>>
>> _______________________________________________
>> Selinux mailing list
>> Selinux@tycho.nsa.gov
>> To unsubscribe, send email to Selinux-leave@tycho.nsa.gov.
>> To get help, send an email containing "help" to Selinux-request@tycho.nsa.gov.

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

* Re: [PATCH v3 0/3] Xen/FLASK policy updates for device contexts
  2015-03-23 13:20   ` Steve Lawrence
@ 2015-03-23 14:22     ` Richard Haines
  2015-03-23 14:22     ` Richard Haines
  1 sibling, 0 replies; 14+ messages in thread
From: Richard Haines @ 2015-03-23 14:22 UTC (permalink / raw)
  To: Steve Lawrence, Daniel De Graaf, selinux; +Cc: xen-devel

Steve,
I've added comments below (all working now thanks) and also found another problem

as the path was not being released. With this patch secilc/valgrind with a good xen
policy will not show any memory errors:

diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index b45b662..d1c0018 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -1274,7 +1274,7 @@ void ocontext_xen_free(ocontext_t **ocontexts)
             c = c->next;
             context_destroy(&ctmp->context[0]);
             context_destroy(&ctmp->context[1]);
-            if (i == OCON_ISID)
+            if (i == OCON_ISID || i == OCON_XEN_DEVICETREE)
                 free(ctmp->u.name);
             free(ctmp);
         }




----- Original Message -----
> From: Steve Lawrence <slawrence@tresys.com>
> To: Richard Haines <richard_c_haines@btinternet.com>; Daniel De Graaf <dgdegra@tycho.nsa.gov>; "selinux@tycho.nsa.gov" <selinux@tycho.nsa.gov>
> Cc: "xen-devel@lists.xenproject.org" <xen-devel@lists.xenproject.org>
> Sent: Monday, 23 March 2015, 13:20
> Subject: Re: [PATCH v3 0/3] Xen/FLASK policy updates for device contexts
> 
> I think there may be a typo in the documentation update. It says:
> 
> Policy version 30 introduced the <literal><link
> linkend="devicetreecon">context</link></literal>
> 
> Should "context" be "devicetreecon"?
Yes

> 
> Otherwise, this patch looks good to me.
> 
> As far as issue 2, I think I've tracked it down to an errant free() in
> cil_destroy_devicetreecon. CIL uses string interning to reduce the
> amount of memory used, so strings rarely need to be free'd. And if they
> are, it results in a double free when the string intern pool is
> destroyed. 

This patch worked fine - thanks
> The below patch should fix it. Can you give it a test and
> make sure it works for you?
> 
> - Steve
> 
> 
> diff --git a/libsepol/cil/src/cil_build_ast.c
> b/libsepol/cil/src/cil_build_ast.c
> index 973b2d7..92c3e09 100644
> --- a/libsepol/cil/src/cil_build_ast.cdiff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index b45b662..d1c0018 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -1274,7 +1274,7 @@ void ocontext_xen_free(ocontext_t **ocontexts)
             c = c->next;
             context_destroy(&ctmp->context[0]);
             context_destroy(&ctmp->context[1]);
-            if (i == OCON_ISID)
+            if (i == OCON_ISID || i == OCON_XEN_DEVICETREE)
                 free(ctmp->u.name);
             free(ctmp);
         }

> +++ b/libsepol/cil/src/cil_build_ast.c
> @@ -4583,8 +4583,6 @@ void cil_destroy_devicetreecon(struct
> cil_devicetreecon *devicetreecon)
>         return;
>     }
> 
> -    free(devicetreecon->path);
> -
>     if (devicetreecon->context_str == NULL && 
> devicetreecon->context !=
> NULL) {
>         cil_destroy_context(devicetreecon->context);
>     }
> 
> 
> 
> On 03/20/2015 12:59 PM, Richard Haines wrote:
>>  I've been testing this and found a few problems:
>> 
>>  1) I could not read a policy with sedispol (in the checkpolicy/test 
> directory)
>>      when the devicetreecon statement was included (checkpolicy built ok).
>>      I've attached a patch that fixes this problem and included CIL Ref 
> Guide
>>     updates for the new features.
>> 
>>  2) When building policy with the CIL compiler secilc I get core dumps but
>>      only if I include the devicetreecon statement. I think its related to 
> not releasing
>>      the devicetreepath "path" when sepol_policydb_free is called. 
> I've been
>>      trying to track it down and failed - any ideas !!!
>>     sedispol will read the generated CIL policy with the above fix applied.
>> 
>> 
>>  Richard
>> 
>> 
>> 
>>  ----- Original Message -----
>>>  From: Daniel De Graaf <dgdegra@tycho.nsa.gov>
>>>  To: selinux@tycho.nsa.gov
>>>  Cc: xen-devel@lists.xenproject.org
>>>  Sent: Tuesday, 17 March 2015, 20:43
>>>  Subject: [PATCH v3 0/3] Xen/FLASK policy updates for device contexts
>>> 
>>>  In order to support assigning security lables to ARM device tree nodes
>>>  in Xen's XSM policy, a new ocontext type is needed in the security
>>>  policy.
>>> 
>>>  In addition to adding the new ocontext, the existing I/O memory range
>>>  ocontext is expanded to 64 bits in order to support hardware with more
>>>  than 44 bits of physical address space (32-bit count of 4K pages).
>>> 
>>>  Changes from v2:
>>>  - Clean up printf format strings for 32-bit builds
>>> 
>>>  Changes from v1:
>>>  - Use policy version 30 instead of forking the version numbers for Xen;
>>>     this removes the need for v1's patch 3.
>>>  - Report an error when attempting to use an I/O memory range that
>>>     requires a 64-bit representation with an old policy output version
>>>     that cannot support this
>>>  - Fix a few incorrect references to PCIDEVICECON
>>>  - Reorder patches to clarify the allowed characterset of device tree
>>>     paths
>>> 
>>>  [PATCH 1/3] checkpolicy: Expand allowed character set in paths
>>>  [PATCH 2/3] libsepol, checkpolicy: widen Xen IOMEM ocontext entries
>>>  [PATCH 3/3] libsepol, checkpolicy: add device tree ocontext nodes to
>>>  _______________________________________________
>>>  Selinux mailing list
>>>  Selinux@tycho.nsa.gov
>>>  To unsubscribe, send email to Selinux-leave@tycho.nsa.gov.
>>>  To get help, send an email containing "help" to 
>>>  Selinux-request@tycho.nsa.gov.
> 
>>> 
>>> 
>>>  _______________________________________________
>>>  Selinux mailing list
>>>  Selinux@tycho.nsa.gov
>>>  To unsubscribe, send email to Selinux-leave@tycho.nsa.gov.
>>>  To get help, send an email containing "help" to 
> Selinux-request@tycho.nsa.gov.
> 

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

* Re: [PATCH v3 0/3] Xen/FLASK policy updates for device contexts
  2015-03-23 13:20   ` Steve Lawrence
  2015-03-23 14:22     ` Richard Haines
@ 2015-03-23 14:22     ` Richard Haines
  1 sibling, 0 replies; 14+ messages in thread
From: Richard Haines @ 2015-03-23 14:22 UTC (permalink / raw)
  To: Steve Lawrence, Daniel De Graaf, selinux; +Cc: xen-devel

Steve,
I've added comments below (all working now thanks) and also found another problem

as the path was not being released. With this patch secilc/valgrind with a good xen
policy will not show any memory errors:

diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index b45b662..d1c0018 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -1274,7 +1274,7 @@ void ocontext_xen_free(ocontext_t **ocontexts)
             c = c->next;
             context_destroy(&ctmp->context[0]);
             context_destroy(&ctmp->context[1]);
-            if (i == OCON_ISID)
+            if (i == OCON_ISID || i == OCON_XEN_DEVICETREE)
                 free(ctmp->u.name);
             free(ctmp);
         }




----- Original Message -----
> From: Steve Lawrence <slawrence@tresys.com>
> To: Richard Haines <richard_c_haines@btinternet.com>; Daniel De Graaf <dgdegra@tycho.nsa.gov>; "selinux@tycho.nsa.gov" <selinux@tycho.nsa.gov>
> Cc: "xen-devel@lists.xenproject.org" <xen-devel@lists.xenproject.org>
> Sent: Monday, 23 March 2015, 13:20
> Subject: Re: [PATCH v3 0/3] Xen/FLASK policy updates for device contexts
> 
> I think there may be a typo in the documentation update. It says:
> 
> Policy version 30 introduced the <literal><link
> linkend="devicetreecon">context</link></literal>
> 
> Should "context" be "devicetreecon"?
Yes

> 
> Otherwise, this patch looks good to me.
> 
> As far as issue 2, I think I've tracked it down to an errant free() in
> cil_destroy_devicetreecon. CIL uses string interning to reduce the
> amount of memory used, so strings rarely need to be free'd. And if they
> are, it results in a double free when the string intern pool is
> destroyed. 

This patch worked fine - thanks
> The below patch should fix it. Can you give it a test and
> make sure it works for you?
> 
> - Steve
> 
> 
> diff --git a/libsepol/cil/src/cil_build_ast.c
> b/libsepol/cil/src/cil_build_ast.c
> index 973b2d7..92c3e09 100644
> --- a/libsepol/cil/src/cil_build_ast.cdiff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index b45b662..d1c0018 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -1274,7 +1274,7 @@ void ocontext_xen_free(ocontext_t **ocontexts)
             c = c->next;
             context_destroy(&ctmp->context[0]);
             context_destroy(&ctmp->context[1]);
-            if (i == OCON_ISID)
+            if (i == OCON_ISID || i == OCON_XEN_DEVICETREE)
                 free(ctmp->u.name);
             free(ctmp);
         }

> +++ b/libsepol/cil/src/cil_build_ast.c
> @@ -4583,8 +4583,6 @@ void cil_destroy_devicetreecon(struct
> cil_devicetreecon *devicetreecon)
>         return;
>     }
> 
> -    free(devicetreecon->path);
> -
>     if (devicetreecon->context_str == NULL && 
> devicetreecon->context !=
> NULL) {
>         cil_destroy_context(devicetreecon->context);
>     }
> 
> 
> 
> On 03/20/2015 12:59 PM, Richard Haines wrote:
>>  I've been testing this and found a few problems:
>> 
>>  1) I could not read a policy with sedispol (in the checkpolicy/test 
> directory)
>>      when the devicetreecon statement was included (checkpolicy built ok).
>>      I've attached a patch that fixes this problem and included CIL Ref 
> Guide
>>     updates for the new features.
>> 
>>  2) When building policy with the CIL compiler secilc I get core dumps but
>>      only if I include the devicetreecon statement. I think its related to 
> not releasing
>>      the devicetreepath "path" when sepol_policydb_free is called. 
> I've been
>>      trying to track it down and failed - any ideas !!!
>>     sedispol will read the generated CIL policy with the above fix applied.
>> 
>> 
>>  Richard
>> 
>> 
>> 
>>  ----- Original Message -----
>>>  From: Daniel De Graaf <dgdegra@tycho.nsa.gov>
>>>  To: selinux@tycho.nsa.gov
>>>  Cc: xen-devel@lists.xenproject.org
>>>  Sent: Tuesday, 17 March 2015, 20:43
>>>  Subject: [PATCH v3 0/3] Xen/FLASK policy updates for device contexts
>>> 
>>>  In order to support assigning security lables to ARM device tree nodes
>>>  in Xen's XSM policy, a new ocontext type is needed in the security
>>>  policy.
>>> 
>>>  In addition to adding the new ocontext, the existing I/O memory range
>>>  ocontext is expanded to 64 bits in order to support hardware with more
>>>  than 44 bits of physical address space (32-bit count of 4K pages).
>>> 
>>>  Changes from v2:
>>>  - Clean up printf format strings for 32-bit builds
>>> 
>>>  Changes from v1:
>>>  - Use policy version 30 instead of forking the version numbers for Xen;
>>>     this removes the need for v1's patch 3.
>>>  - Report an error when attempting to use an I/O memory range that
>>>     requires a 64-bit representation with an old policy output version
>>>     that cannot support this
>>>  - Fix a few incorrect references to PCIDEVICECON
>>>  - Reorder patches to clarify the allowed characterset of device tree
>>>     paths
>>> 
>>>  [PATCH 1/3] checkpolicy: Expand allowed character set in paths
>>>  [PATCH 2/3] libsepol, checkpolicy: widen Xen IOMEM ocontext entries
>>>  [PATCH 3/3] libsepol, checkpolicy: add device tree ocontext nodes to
>>>  _______________________________________________
>>>  Selinux mailing list
>>>  Selinux@tycho.nsa.gov
>>>  To unsubscribe, send email to Selinux-leave@tycho.nsa.gov.
>>>  To get help, send an email containing "help" to 
>>>  Selinux-request@tycho.nsa.gov.
> 
>>> 
>>> 
>>>  _______________________________________________
>>>  Selinux mailing list
>>>  Selinux@tycho.nsa.gov
>>>  To unsubscribe, send email to Selinux-leave@tycho.nsa.gov.
>>>  To get help, send an email containing "help" to 
> Selinux-request@tycho.nsa.gov.
> 

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

end of thread, other threads:[~2015-03-23 14:27 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-17 20:43 [PATCH v3 0/3] Xen/FLASK policy updates for device contexts Daniel De Graaf
2015-03-17 20:43 ` [PATCH 1/3] checkpolicy: Expand allowed character set in paths Daniel De Graaf
2015-03-17 20:43   ` Daniel De Graaf
2015-03-17 20:43 ` [PATCH 2/3] libsepol, checkpolicy: widen Xen IOMEM ocontext entries Daniel De Graaf
2015-03-17 20:43   ` Daniel De Graaf
2015-03-17 20:43 ` [PATCH 3/3] libsepol, checkpolicy: add device tree ocontext nodes to Xen policy Daniel De Graaf
2015-03-17 20:43   ` Daniel De Graaf
2015-03-18 12:38 ` [PATCH v3 0/3] Xen/FLASK policy updates for device contexts Stephen Smalley
2015-03-20 16:59 ` Richard Haines
2015-03-20 16:59 ` Richard Haines
2015-03-23 13:20   ` Steve Lawrence
2015-03-23 13:20   ` Steve Lawrence
2015-03-23 14:22     ` Richard Haines
2015-03-23 14:22     ` Richard Haines

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.