All of lore.kernel.org
 help / color / mirror / Atom feed
* v1 Add role attribute support to libsepol
@ 2011-05-29  4:36 Harry Ciao
  2011-05-29  4:36 ` [v1 PATCH 1/6] Add role attribute support when compiling modules Harry Ciao
                   ` (5 more replies)
  0 siblings, 6 replies; 10+ messages in thread
From: Harry Ciao @ 2011-05-29  4:36 UTC (permalink / raw)
  To: cpebenito, sds, method, jmorris, eparis; +Cc: selinux



Comments
---------

    Support adding one role attribute into another.
    
    When the link process is completed, the types type_set_t and roles
    ebitmap in a role attribute are settled, then we could go on scan
    all role attributes in the base.p_roles table checking if any non-zero
    bit in its roles ebitmap is indeed another role attribute.
    
    If this is the case, then we need to escalate the roles ebitmap of
    the sub-attribute into that of the parent attribute, and remove the
    sub-attribute from parent's roles ebitmap.
    
    Since sub-attribute's roles ebitmap may further contain other role
    attributes, we need to re-scan the updated parent's roles ebitmap.
    
    Also if a loop dependency is detected, no escalation of sub-attribute's
    roles ebitmap is needed.


    In order to highlight this patch I've decided to introduce a new
    separate commit, while all the rest 5 commits are the same as v0.


Tests of adding one role attribute into another
------------------------------------------------
   
1. Apply the patch for rpm.* and selinuxuti.*, to introduce rpm_roles and
   semanage_roles attributes and eliminate the "chain of run interfaces",
   make policy.X and dump its hexdump, check out the policy value for
   related identifiers:
   
   0035b00: 5f74 0500 0000 4103 0000 0100 0000 0000  _t....A.........
   0035b10: 0000 7270 6d5f 7407 0000 0042 0300 0001  ..rpm_t....
   
   rpm_t: policy value = 0x341
   
   0040460: 740c 0000 0075 0700 0001 0000 0000 0000  t....u..........
   0040470: 0072 706d 5f73 6372 6970 745f 740f 0000  .rpm_script_t.
   
   rpm_script_t: policy value = 0x775
   
   004c900: 6563 7572 6974 795f 740a 0000 001e 0c00  ecurity_t.......
   004c910: 0001 0000 0000 0000 0073 656d 616e 6167  .........semanag
   004c920: 655f 7409 0000 001f 0c00 0003 0000 0000  e_t
   
   semanage_t: policy value = 0xc1e
   
   004c760: 0a00 0000 140c 0000 0100 0000 0000 0000  ................
   004c770: 7365 7466 696c 6573 5f74 1400 0000 ec0a  setfiles_t......
   
   setfiles_t: policy value = 0xc14
   
   00484e0: 740d 0000 008b 0a00 0001 0000 0000 0000  t...............
   00484f0: 006c 6f61 645f 706f 6c69 6379 5f74 0c00  .load_policy_t..
   
   load_policy_t: policy value = 0xa8b
   
   
2. Check out rpm_roles.types ebitmap:
   
   002d2c0: 0000 0400 0000 0000 0000 0900 0000 0f00  ................
   002d2d0: 0000 0000 0000 7270 6d5f 726f 6c65 7340  ......rpm_roles@
   002d2e0: 0000 0040 0000 0001 0000 0000 0000 0000  ...@............
   002d2f0: 4000 0000 0000 0040 0000 0080 0700 0002  @......@........
   002d300: 0000 0040 0300 0001 0000 0000 0000 0040  ...@...........@
   002d310: 0700 0000 0000 0000 0010 000b 0000 0010  ................
   002d320: 0000 0000 0000 006e 785f 7365 7276 6572  .......
   
   rpm_roles: policy value = 0x0f
   	dominates:
  		mz = 0x40, highbit = 0x40, node = 1
		startbit = 0, map: 00 4000 0000 0000 00 
			policy value: 0x0f(rpm_roles)
   	types.types:
   		mz = 0x40, highbit = 0x780, node = 2
   		startbit = 0x340, map: 01 0000 0000 0000 00
			policy value: 0x341(rpm_t)
   		startbit = 0x740, map: 00 0000 0000 0010 00
			policy value: 0x775(rpm_script_t)
   
   
3. Check out semanage_roles.types ebitmap:
   
   002caa0: 0000 0000 0e00 0000 0800 0000 0000 0000  ................
   002cab0: 7365 6d61 6e61 6765 5f72 6f6c 6573 4000  semanage_roles@.
   002cac0: 0000 4000 0000 0100 0000 0000 0000 8000  ..@.............
   002cad0: 0000 0000 0000 4000 0000 400c 0000 0200  ......@...@.....
   002cae0: 0000 800a 0000 0004 0000 0000 0000 000c  ................
   002caf0: 0000 0000 0820 0000 0000 1000 0000 0900  ..... ..........
   002cb00: 0000 0000 0000 726f 6c65 5f61 7474 7269  ......
   
   semanage_roles: policy value = 0x08
   	dominates:
  		mz = 0x40, highbit = 0x40, node = 1, 
		startbit = 0, map: 8000 0000 0000 0000 
			policy value: 8(semanage_roles)
   	types.types:
   		mz = 0x40, highbit = 0xc40 node = 2
		startbit = 0xa80, map: 0004 0000 0000 0000
			policy value: 0xa8b(load_policy_t)
		startbit = 0xc00, map: 0000 0820 0000 0000
			policy value: 0xc14(setfiles_t), 0xc1e(semanage_t)
   
   
4. Verify that once rpm_roles attribute becomes a sub-attribute of
   semanage_roles attribute, then all regular roles belonging to rpm_roles
   such as sysadm_r should be able to type all those types of the parent role
   attribute's types(that is, semanage_roles.types):
   
   002ccc0: 0000 0800 0000 0b00 0000 0000 0000 7379  ..............sy
   002ccd0: 7361 646d 5f72 4000 0000 4000 0000 0100  sadm_r@...@.....
   002cce0: 0000 0000 0000 0004 0000 0000 0000 4000  ..............@.
   002ccf0: 0000 800d 0000 2d00 0000 8000 0000 0000  ......-.........
   ...
   002cd70: 5808, 4003 0000 0906 0200 0000 0000, 8003  X.@.............
   ...
   002cdf0: 4000 0000 0900 c006 0000 0000 0008 0000  @...............
   002ce00: 0000, 4007 0000 4000 0000 0000 1006, 8007  ..@...@.........
   002ce10: 0000 0000 000a 0000 0000 c007 0000 0080  ................
   ...
   002ce90: 8000, 400a 0000 0000 0000 0000 0040, 800a  ..@..........@..
   002cea0: 0000 0004 0002 0000 0000 c00a 0000 0000  ................
   002ceb0: 0000 8000 0000 000b 0000 0000 0080 0080  ................
   002cec0: 0000 c00b 0000 0000 0000 1000 0000, 000c  ................
   002ced0: 0000 0000 3820 0004 0000 400c 0000 0400  ....8 ....@.....
   ...
   
   sysadm_r: policy value = 0x0b
   	dominates:
   		mz = 0x40, highbit = 0x40, node = 1
   		startbit = 0x0, map: 0004 0000 0000 0000
			policy value: 0x0b(sysadm_r)
   	types.types:
   		mz = 0x40, highbit = 0xd80, node = 0x2d
   		startbit = 0x340, map: 0906 0200 0000 0000
   			policy value: 341(rpm_t), 344, 34a, 34b
   
   		startbit = 0x740, map: 4000 0000 0000 1006
   			policy value: 747, 775(rpm_script_t), 77a, 77b
   
   		startbit = 0xa80, map: 0004 0002 0000 0000
   			policy value: a8b(load_policy_t), a9a
   
   		startbit = 0xc00, map: 0000 3820 0004 0000 
   			policy value: c14(setfiles_t), c15, c16, c1e(semanage_t)
   
   
5. Extra loop depenency tests.
   
5.1 When there is no loop dependency between rpm_roles and semanage_roles
   attributes, the secadm_r that belongs to semanage_roles attributes is
   not able to type those types of the rpm_roles.types, such as rpm_t or
   rpm_script_t:
   
   002cb60: 0000 0a00 0000 0000 0000 7365 6361 646d  ..........secadm
   002cb70: 5f72 4000 0000 4000 0000 0100 0000 0000  _r@...@.........
   002cb80: 0000 0002 0000 0000 0000 4000 0000 400d  ..........@...@.
   002cb90: 0000 1900 0000 8000 0000 0000 0000 0200  ................
   ...
   002cbe0: 0000 0400 0200 0000 1800, 4003 0000 0002  ..........@.....
   002cbf0: 0000 0000 0000 c003 0000 0000 0000 0000  ................
   ...
   002cc30: 0800 4006 0000 0000 0000 0000 0100, 4007  ..@...........@.
   002cc40: 0000 0000 0000 0000 2000 4009 0000 0000  ........ .@.....
   002cc50: 0000 0000 0420 8009 0000 0000 0820 0000  ..... ....... ..
   
   secadm_r:
   	types.types:
   		mz = 0x40, highbit = 0xd40, node = 0x19
   		startbit = 0x340, map: 0002 0000 0000 0000
   			policy value: 34a, ... 
   		
   		startbit = 0x740, map: 0000 0000 0000 2000
   			policy value: 776
   
   
5.2 Add below statements in selinuxutil.te to create a loop dependcy
   between rpm_roles and semanage_roles attributes:
   
   attribute rpm_roles ROLE;
   roleattribute semanage_roles rpm_roles;
   
   Then rebuild policy.X in modular way, the loop dependency should be
   properly handled, and secadm_r that belongs to the semanage_roles
   should be able to type all those types in rpm_roles.types ebitmap,
   such as rpm_t and rpm_script_t:
   
   002cb60: 0000 0a00 0000 0000 0000 7365 6361 646d  ..........secadm
   002cb70: 5f72 4000 0000 4000 0000 0100 0000 0000  _r@...@.........
   002cb80: 0000 0002 0000 0000 0000 4000 0000 400d  ..........@...@.
   002cb90: 0000 1900 0000 8000 0000 0000 0000 0200  ................
   ...
   002cbe0: 0000 0400 0200 0000 1800, 4003 0000 0102  ..........@.....
   002cbf0: 0000 0000 0000 c003 0000 0000 0000 0000  ................
   ...
   002cc30: 0800 4006 0000 0000 0000 0000 0100, 4007  ..@...........@.
   002cc40: 0000 0000 0000 0000 3000 4009 0000 0000  ........0.@.....
   002cc50: 0000 0000 0420 8009 0000 0000 0820 0000  ..... ....... ..
   
   secadm_r:
   	types.types:
   		mz = 0x40, highbit = 0xd40, node = 0x19
   		startbit = 0x340, map: 0102 0000 0000 0000
   			policy value: 341(rpm_t), ... 
   		
   		startbit = 0x740, map: 0000 0000 0000 3000
   			policy value: 775(rpm_script_t), 776

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

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

* [v1 PATCH 1/6] Add role attribute support when compiling modules.
  2011-05-29  4:36 v1 Add role attribute support to libsepol Harry Ciao
@ 2011-05-29  4:36 ` Harry Ciao
  2011-05-29 22:57   ` Joshua Brindle
  2011-05-29  4:36 ` [v1 PATCH 2/6] Add role attribute support when generating pp files Harry Ciao
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 10+ messages in thread
From: Harry Ciao @ 2011-05-29  4:36 UTC (permalink / raw)
  To: cpebenito, sds, method, jmorris, eparis; +Cc: selinux

1. Add a uint32_t "flavor" field and an ebitmap "roles" to the
role_datum_t structure;

2. Modify the attribute declaration rule to add support to declare
role attribute as well as type attribute;

3. Modify declare_role() to setup role_datum_t.flavor according
to the isattr argument;

4. Add a new roleattribute rule and its handler, which will record
the regular role's (policy value - 1) into the role attribute's
role_datum_t.roles ebitmap;

5. Modify the syntax for the role_types rule only to define the
role-type associations;

6. Add a new role_attr rule to support the declaration of a single
role, and the role attribute that the role belongs to;

7. Check if the new_role used in role transition is a regular role;

8. Make the role-types rule no longer used to declare a regular role
but solely aimed for declaring role-types associations;

FIXME:
How to pass a second argument to require_attribute(), to indicate
if the attribute is of role or type ?

Signed-off-by: Harry Ciao <qingtao.cao@windriver.com>
---
 checkpolicy/module_compiler.c              |   69 ++++++++++++-
 checkpolicy/module_compiler.h              |    3 +-
 checkpolicy/policy_define.c                |  149 +++++++++++++++++++++++++++-
 checkpolicy/policy_define.h                |    4 +-
 checkpolicy/policy_parse.y                 |   17 +++-
 checkpolicy/policy_scan.l                  |    2 +
 libsepol/include/sepol/policydb/policydb.h |    4 +
 libsepol/src/policydb.c                    |    2 +
 8 files changed, 239 insertions(+), 11 deletions(-)

diff --git a/checkpolicy/module_compiler.c b/checkpolicy/module_compiler.c
index 0946ff6..20b6f4a 100644
--- a/checkpolicy/module_compiler.c
+++ b/checkpolicy/module_compiler.c
@@ -200,7 +200,7 @@ static int role_implicit_bounds(hashtab_t roles_tab,
 	return 0;
 }
 
-role_datum_t *declare_role(void)
+role_datum_t *declare_role(unsigned char isattr)
 {
 	char *id = queue_remove(id_queue), *dest_id = NULL;
 	role_datum_t *role = NULL, *dest_role = NULL;
@@ -217,7 +217,7 @@ role_datum_t *declare_role(void)
 		return NULL;
 	}
 	role_datum_init(role);
-
+	role->flavor = isattr ? ROLE_ATTRIB : ROLE_ROLE;
 	retval =
 	    declare_symbol(SYM_ROLES, id, (hashtab_datum_t *) role, &value,
 			   &value);
@@ -254,6 +254,7 @@ role_datum_t *declare_role(void)
 			}
 			role_datum_init(dest_role);
 			dest_role->s.value = value;
+			dest_role->flavor = isattr ? ROLE_ATTRIB : ROLE_ROLE;
 			if (role_implicit_bounds(roles_tab, dest_id, dest_role)) {
 				free(dest_id);
 				role_datum_destroy(dest_role);
@@ -548,6 +549,55 @@ type_datum_t *get_local_type(char *id, uint32_t value, unsigned char isattr)
 	return dest_typdatum;
 }
 
+/* Return a role_datum_t for the local avrule_decl with the given ID.
+ * If it does not exist, create one with the same value as 'value'.
+ * This function assumes that the ID is within scope.  c.f.,
+ * is_id_in_scope().
+ *
+ * NOTE: this function usurps ownership of id afterwards.  The caller
+ * shall not reference it nor free() it afterwards.
+ */
+role_datum_t *get_local_role(char *id, uint32_t value, unsigned char isattr)
+{
+	role_datum_t *dest_roledatum;
+	hashtab_t roles_tab;
+
+	assert(stack_top->type == 1);
+
+	if (stack_top->parent == NULL) {
+		/* in global, so use global symbol table */
+		roles_tab = policydbp->p_roles.table;
+	} else {
+		roles_tab = stack_top->decl->p_roles.table;
+	}
+
+	dest_roledatum = hashtab_search(roles_tab, id);
+	if (!dest_roledatum) {
+		dest_roledatum = (role_datum_t *)malloc(sizeof(role_datum_t));
+		if (dest_roledatum == NULL) {
+			free(id);
+			return NULL;
+		}
+
+		role_datum_init(dest_roledatum);
+		dest_roledatum->s.value = value;
+		dest_roledatum->flavor = isattr ? ROLE_ATTRIB : ROLE_ROLE;
+
+		if (hashtab_insert(roles_tab, id, dest_roledatum)) {
+			free(id);
+			role_datum_destroy(dest_roledatum);
+			free(dest_roledatum);
+			return NULL;
+		}
+	} else {
+		free(id);
+		if (dest_roledatum->flavor != isattr ? ROLE_ATTRIB : ROLE_ROLE)
+			return NULL;
+	}
+	
+	return dest_roledatum;
+}
+
 /* Given the current parse stack, returns 1 if a requirement would be
  * allowed here or 0 if not.  For example, the ELSE branch may never
  * have its own requirements.
@@ -812,7 +862,7 @@ int require_class(int pass)
 	return -1;
 }
 
-int require_role(int pass)
+static int require_role_or_attribute(int pass, unsigned char isattr)
 {
 	char *id = queue_remove(id_queue);
 	role_datum_t *role = NULL;
@@ -831,6 +881,7 @@ int require_role(int pass)
 		return -1;
 	}
 	role_datum_init(role);
+	role->flavor = isattr ? ROLE_ATTRIB : ROLE_ROLE;
 	retval =
 	    require_symbol(SYM_ROLES, id, (hashtab_datum_t *) role,
 			   &role->s.value, &role->s.value);
@@ -870,6 +921,11 @@ int require_role(int pass)
 	}
 }
 
+int require_role(int pass)
+{
+	return require_role_or_attribute(pass, 0);
+}
+
 static int require_type_or_attribute(int pass, unsigned char isattr)
 {
 	char *id = queue_remove(id_queue);
@@ -930,6 +986,13 @@ int require_type(int pass)
 
 int require_attribute(int pass)
 {
+/*
+ * FIXME:
+ * In order to support to require a role attribute,
+ * We should add another argument to indicate if the required attribute 
+ * is of role or type. If it is a role attribute, then call
+ *	return require_role_or_attribute(pass, 1);
+ */
 	return require_type_or_attribute(pass, 1);
 }
 
diff --git a/checkpolicy/module_compiler.h b/checkpolicy/module_compiler.h
index ae33753..ce7a90a 100644
--- a/checkpolicy/module_compiler.h
+++ b/checkpolicy/module_compiler.h
@@ -30,11 +30,12 @@ int declare_symbol(uint32_t symbol_type,
 		   hashtab_key_t key, hashtab_datum_t datum,
 		   uint32_t * dest_value, uint32_t * datum_value);
 
-role_datum_t *declare_role(void);
+role_datum_t *declare_role(unsigned char isattr);
 type_datum_t *declare_type(unsigned char primary, unsigned char isattr);
 user_datum_t *declare_user(void);
 
 type_datum_t *get_local_type(char *id, uint32_t value, unsigned char isattr);
+role_datum_t *get_local_role(char *id, uint32_t value, unsigned char isattr);
 
 /* Add a symbol to the current avrule_block's require section.  Note
  * that a module may not both declare and require the same symbol.
diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c
index f75a682..a15bfa6 100644
--- a/checkpolicy/policy_define.c
+++ b/checkpolicy/policy_define.c
@@ -965,16 +965,24 @@ int define_level(void)
 	return 0;
 }
 
-int define_attrib(void)
+int define_attrib(char *kind)
 {
 	if (pass == 2) {
 		free(queue_remove(id_queue));
 		return 0;
 	}
 
-	if (declare_type(TRUE, TRUE) == NULL) {
+	if (strcmp(kind, "type") == 0) {
+		if (declare_type(TRUE, TRUE) == NULL)
+			return -1;
+	} else if (strcmp(kind, "role") == 0) {
+		if (declare_role(TRUE) == NULL)
+			return -1;
+	} else {
+		/* only support type and role attributes by far */
 		return -1;
 	}
+
 	return 0;
 }
 
@@ -1774,6 +1782,9 @@ int define_te_avtab(int which)
 	return 0;
 }
 
+/* The role-types rule is no longer used to declare regular role or
+ * role attribute, but solely aimed for declaring role-types associations.
+ */
 int define_role_types(void)
 {
 	role_datum_t *role;
@@ -1786,9 +1797,25 @@ int define_role_types(void)
 		return 0;
 	}
 
-	if ((role = declare_role()) == NULL) {
+	id = (char *)queue_remove(id_queue);
+	if (!id) {
+		yyerror("no role name for role-types rule?");
 		return -1;
 	}
+
+	if (!is_id_in_scope(SYM_ROLES, id)) {
+		yyerror2("role %s is not within scope", id);
+		free(id);
+		return -1;
+	}
+
+	role = hashtab_search(policydbp->p_roles.table, id);
+	if (!role) {
+		yyerror2("unknown role %s", id);
+		free(id);
+		return -1;
+	}
+
 	while ((id = queue_remove(id_queue))) {
 		if (set_types(&role->types, id, &add, 0))
 			return -1;
@@ -1797,6 +1824,117 @@ int define_role_types(void)
 	return 0;
 }
 
+int define_role_attr(void)
+{
+	char *id;
+	role_datum_t *r, *attr;
+
+	if (pass == 2) {
+		while ((id = queue_remove(id_queue)))
+			free(id);
+		return 0;
+	}
+	
+	if ((r = declare_role(FALSE)) == NULL)
+		return -1;
+
+	while ((id = queue_remove(id_queue))) {
+		if (!is_id_in_scope(SYM_ROLES, id)) {
+			yyerror2("attribute %s is not within scope", id);
+			free(id);
+			return -1;
+		}
+		attr = hashtab_search(policydbp->p_roles.table, id);
+		if (!attr) {
+			/* treat it as a fatal error */
+			yyerror2("role attribute %s is not declared", id);
+			free(id);
+			return -1;
+		}
+
+		if (attr->flavor != ROLE_ATTRIB) {
+			yyerror2("%s is a regular role, not an attribute", id);
+			free(id);
+			return -1;
+		}
+
+		if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) {
+			yyerror("Out of memory!");
+			return -1;
+		}
+
+		if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) {
+			yyerror("out of memory");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+int define_roleattribute(void)
+{
+	char *id;
+	role_datum_t *r, *attr;
+
+	if (pass == 2) {
+		while ((id = queue_remove(id_queue)))
+			free(id);
+		return 0;
+	}
+
+	id = (char *)queue_remove(id_queue);
+	if (!id) {
+		yyerror("no role name for roleattribute definition?");
+		return -1;
+	}
+
+	if (!is_id_in_scope(SYM_ROLES, id)) {
+		yyerror2("role %s is not within scope", id);
+		free(id);
+		return -1;
+	}
+	r = hashtab_search(policydbp->p_roles.table, id);
+	if (!r || r->flavor != ROLE_ROLE) {
+		yyerror2("unknown role %s, or not a regular role", id);
+		free(id);
+		return -1;
+	}
+
+	while ((id = queue_remove(id_queue))) {
+		if (!is_id_in_scope(SYM_ROLES, id)) {
+			yyerror2("attribute %s is not within scope", id);
+			free(id);
+			return -1;
+		}
+		attr = hashtab_search(policydbp->p_roles.table, id);
+		if (!attr) {
+			/* treat it as a fatal error */
+			yyerror2("role attribute %s is not declared", id);
+			free(id);
+			return -1;
+		}
+
+		if (attr->flavor != ROLE_ATTRIB) {
+			yyerror2("%s is a regular role, not an attribute", id);
+			free(id);
+			return -1;
+		}
+
+		if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) {
+			yyerror("Out of memory!");
+			return -1;
+		}
+
+		if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) {
+			yyerror("out of memory");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
 role_datum_t *merge_roles_dom(role_datum_t * r1, role_datum_t * r2)
 {
 	role_datum_t *new;
@@ -2138,6 +2276,11 @@ int define_role_trans(int class_specified)
 		goto bad;
 	}
 
+	if (role->flavor != ROLE_ROLE) {
+		yyerror2("the new role %s must be a regular role", id);
+		goto bad;
+	}
+
 	/* This ebitmap business is just to ensure that there are not conflicting role_trans rules */
 	if (role_set_expand(&roles, &e_roles, policydbp, NULL))
 		goto bad;
diff --git a/checkpolicy/policy_define.h b/checkpolicy/policy_define.h
index 890a6af..c21e549 100644
--- a/checkpolicy/policy_define.h
+++ b/checkpolicy/policy_define.h
@@ -18,7 +18,7 @@ avrule_t *define_cond_pol_list(avrule_t *avlist, avrule_t *stmt);
 avrule_t *define_cond_te_avtab(int which);
 avrule_t *define_cond_filename_trans(void);
 cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void* arg2);
-int define_attrib(void);
+int define_attrib(char *kind);
 int define_av_perms(int inherits);
 int define_bool(void);
 int define_category(void);
@@ -48,6 +48,8 @@ int define_range_trans(int class_specified);
 int define_role_allow(void);
 int define_role_trans(int class_specified);
 int define_role_types(void);
+int define_role_attr(void);
+int define_roleattribute(void);
 int define_filename_trans(void);
 int define_sens(void);
 int define_te_avtab(int which);
diff --git a/checkpolicy/policy_parse.y b/checkpolicy/policy_parse.y
index 8274d36..71c1971 100644
--- a/checkpolicy/policy_parse.y
+++ b/checkpolicy/policy_parse.y
@@ -90,6 +90,7 @@ typedef int (* require_func_t)();
 %token INHERITS
 %token SID
 %token ROLE
+%token ROLEATTRIBUTE
 %token ROLES
 %token TYPEALIAS
 %token TYPEATTRIBUTE
@@ -256,6 +257,8 @@ rbac_decl		: role_type_def
                         | role_dominance
                         | role_trans_def
  			| role_allow_def
+			| roleattribute_def
+			| role_attr_def
 			;
 te_decl			: attribute_def
                         | type_def
@@ -269,7 +272,11 @@ te_decl			: attribute_def
 			| permissive_def
 			;
 attribute_def           : ATTRIBUTE identifier ';'
-                        { if (define_attrib()) return -1;}
+                        { if (define_attrib("type")) return -1;}
+			| ATTRIBUTE identifier TYPE ';'
+			{ if (define_attrib("type")) return -1;}
+			| ATTRIBUTE identifier ROLE ';'
+			{ if (define_attrib("role")) return -1;}
                         ;
 type_def		: TYPE identifier alias_def opt_attr_list ';'
                         {if (define_type(1)) return -1;}
@@ -417,8 +424,9 @@ neverallow_def		: NEVERALLOW names names ':' names names  ';'
 		        ;
 role_type_def		: ROLE identifier TYPES names ';'
 			{if (define_role_types()) return -1;}
- 			| ROLE identifier';'
- 			{if (define_role_types()) return -1;}
+			;
+role_attr_def		: ROLE identifier opt_attr_list ';'
+ 			{if (define_role_attr()) return -1;}
                         ;
 role_dominance		: DOMINANCE '{' roles '}'
 			;
@@ -440,6 +448,9 @@ role_def		: ROLE identifier_push ';'
 			| ROLE identifier_push '{' roles '}'
                         {$$ = define_role_dom((role_datum_t*)$4); if ($$ == 0) return -1;}
 			;
+roleattribute_def	: ROLEATTRIBUTE identifier id_comma_list ';'
+			{if (define_roleattribute()) return -1;}
+			;
 opt_constraints         : constraints
                         |
                         ;
diff --git a/checkpolicy/policy_scan.l b/checkpolicy/policy_scan.l
index 427c189..2efa8e5 100644
--- a/checkpolicy/policy_scan.l
+++ b/checkpolicy/policy_scan.l
@@ -76,6 +76,8 @@ ROLE |
 role				{ return(ROLE); }
 ROLES |
 roles				{ return(ROLES); }
+ROLEATTRIBUTE |
+roleattribute			{ return(ROLEATTRIBUTE);}
 TYPES |
 types				{ return(TYPES); }
 TYPEALIAS |
diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h
index eebf1a9..b59ab2e 100644
--- a/libsepol/include/sepol/policydb/policydb.h
+++ b/libsepol/include/sepol/policydb/policydb.h
@@ -120,6 +120,10 @@ typedef struct role_datum {
 	type_set_t types;	/* set of authorized types for role */
 	ebitmap_t cache;	/* This is an expanded set used for context validation during parsing */
 	uint32_t bounds;	/* bounds role, if exist */
+#define ROLE_ROLE 0		/* regular role in kernel policies */
+#define ROLE_ATTRIB 1		/* attribute */
+	uint32_t flavor;
+	ebitmap_t roles;	/* roles with this attribute */
 } role_datum_t;
 
 typedef struct role_trans {
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index 6d8ff91..feb35ae 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -350,6 +350,7 @@ void role_datum_init(role_datum_t * x)
 	ebitmap_init(&x->dominates);
 	type_set_init(&x->types);
 	ebitmap_init(&x->cache);
+	ebitmap_init(&x->roles);
 }
 
 void role_datum_destroy(role_datum_t * x)
@@ -358,6 +359,7 @@ void role_datum_destroy(role_datum_t * x)
 		ebitmap_destroy(&x->dominates);
 		type_set_destroy(&x->types);
 		ebitmap_destroy(&x->cache);
+		ebitmap_destroy(&x->roles);
 	}
 }
 
-- 
1.7.0.4


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

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

* [v1 PATCH 2/6] Add role attribute support when generating pp files.
  2011-05-29  4:36 v1 Add role attribute support to libsepol Harry Ciao
  2011-05-29  4:36 ` [v1 PATCH 1/6] Add role attribute support when compiling modules Harry Ciao
@ 2011-05-29  4:36 ` Harry Ciao
  2011-05-29  4:36 ` [v1 PATCH 3/6] Add role attribute support when linking modules Harry Ciao
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Harry Ciao @ 2011-05-29  4:36 UTC (permalink / raw)
  To: cpebenito, sds, method, jmorris, eparis; +Cc: selinux

Add support to read/write the flavor flag and roles ebitmap in the
role_datum_t structure from/to policy module.

Note: since the role ebitmap would be expanded and won't be written
into kernel policy, kernel SELinux security server needs no change,
we don't have to introduce a new maximum version for the userspace
SELinux security server neither.

Signed-off-by: Harry Ciao <qingtao.cao@windriver.com>
---
 libsepol/src/policydb.c |   11 +++++++++++
 libsepol/src/write.c    |   10 ++++++++++
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index feb35ae..1e3abac 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -2071,6 +2071,17 @@ static int role_read(policydb_t * p
 		if (type_set_read(&role->types, fp))
 			goto bad;
 	}
+	
+	if (p->policy_type != POLICY_KERN) {
+		rc = next_entry(buf, fp, sizeof(uint32_t));
+		if (rc < 0)
+			goto bad;
+
+		role->flavor = le32_to_cpu(buf[0]);
+
+		if (ebitmap_read(&role->roles, fp))
+			goto bad;
+	}
 
 	if (strcmp(key, OBJECT_R) == 0) {
 		if (role->s.value != OBJECT_R_VAL) {
diff --git a/libsepol/src/write.c b/libsepol/src/write.c
index 9657e6c..03ac7b0 100644
--- a/libsepol/src/write.c
+++ b/libsepol/src/write.c
@@ -996,6 +996,16 @@ static int role_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr)
 			return POLICYDB_ERROR;
 	}
 
+	if (p->policy_type != POLICY_KERN) {
+		buf[0] = cpu_to_le32(role->flavor);
+		items = put_entry(buf, sizeof(uint32_t), 1, fp);
+		if (items != 1)
+			return POLICYDB_ERROR;
+
+		if (ebitmap_write(&role->roles, fp))
+			return POLICYDB_ERROR;
+	}
+
 	return POLICYDB_SUCCESS;
 }
 
-- 
1.7.0.4


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

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

* [v1 PATCH 3/6] Add role attribute support when linking modules.
  2011-05-29  4:36 v1 Add role attribute support to libsepol Harry Ciao
  2011-05-29  4:36 ` [v1 PATCH 1/6] Add role attribute support when compiling modules Harry Ciao
  2011-05-29  4:36 ` [v1 PATCH 2/6] Add role attribute support when generating pp files Harry Ciao
@ 2011-05-29  4:36 ` Harry Ciao
  2011-05-29  4:36 ` [v1 PATCH 4/6] Add role attribute support when expanding role_datum_t Harry Ciao
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Harry Ciao @ 2011-05-29  4:36 UTC (permalink / raw)
  To: cpebenito, sds, method, jmorris, eparis; +Cc: selinux

Make the flavor flag and the roles ebitmap in role_datum_t structure
properly handled during module link process:

1. the flavor flag is copied into the base module;

2. if both the current module and the base module have defined or
required the same role, check if there is a discrepency in flavor;

3. remap the roles ebitmap and merge into its counterpart in the
base module;

Signed-off-by: Harry Ciao <qingtao.cao@windriver.com>
---
 libsepol/src/link.c |   42 ++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/libsepol/src/link.c b/libsepol/src/link.c
index 23dbb1b..53fcff9 100644
--- a/libsepol/src/link.c
+++ b/libsepol/src/link.c
@@ -312,7 +312,25 @@ static int role_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
 	role = (role_datum_t *) datum;
 
 	base_role = hashtab_search(state->base->p_roles.table, id);
-	if (base_role == NULL) {
+	if (base_role != NULL) {
+		/* role already exists.  check that it is what this
+		 * module expected.  duplicate declarations (e.g., two
+		 * modules both declare role foo_r) is checked during
+		 * scope_copy_callback(). */
+		if (role->flavor == ROLE_ATTRIB
+		    && base_role->flavor != ROLE_ATTRIB) {
+			ERR(state->handle,
+			    "%s: Expected %s to be a role attribute, but it was already declared as a regular role.",
+			    state->cur_mod_name, id);
+			return -1;
+		} else if (role->flavor != ROLE_ATTRIB
+			   && base_role->flavor == ROLE_ATTRIB) {
+			ERR(state->handle,
+			    "%s: Expected %s to be a regular role, but it was already declared as a role attribute.",
+			    state->cur_mod_name, id);
+			return -1;
+		}
+	} else {
 		if (state->verbose)
 			INFO(state->handle, "copying role %s", id);
 
@@ -326,8 +344,9 @@ static int role_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
 		}
 		role_datum_init(new_role);
 
-		/* new_role's dominates and types field will be copied
+		/* new_role's dominates, types and roles field will be copied
 		 * during role_fix_callback() */
+		new_role->flavor = role->flavor;
 		new_role->s.value = state->base->p_roles.nprim + 1;
 
 		ret = hashtab_insert(state->base->p_roles.table,
@@ -346,6 +365,7 @@ static int role_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
 			goto cleanup;
 		}
 		role_datum_init(new_role);
+		new_role->flavor = base_role->flavor;
 		new_role->s.value = base_role->s.value;
 		if ((new_id = strdup(id)) == NULL) {
 			goto cleanup;
@@ -1046,6 +1066,24 @@ static int role_fix_callback(hashtab_key_t key, hashtab_datum_t datum,
 		goto cleanup;
 	}
 	ebitmap_destroy(&e_tmp);
+	
+	if (role->flavor == ROLE_ATTRIB) {
+		ebitmap_init(&e_tmp);
+		ebitmap_for_each_bit(&role->roles, rnode, i) {
+			if (ebitmap_node_get_bit(rnode, i)) {
+				assert(mod->map[SYM_ROLES][i]);
+				if (ebitmap_set_bit
+				    (&e_tmp, mod->map[SYM_ROLES][i] - 1, 1)) {
+					goto cleanup;
+				}
+			}
+		}
+		if (ebitmap_union(&dest_role->roles, &e_tmp)) {
+			goto cleanup;
+		}
+		ebitmap_destroy(&e_tmp);
+	}
+
 	return 0;
 
       cleanup:
-- 
1.7.0.4


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

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

* [v1 PATCH 4/6] Add role attribute support when expanding role_datum_t.
  2011-05-29  4:36 v1 Add role attribute support to libsepol Harry Ciao
                   ` (2 preceding siblings ...)
  2011-05-29  4:36 ` [v1 PATCH 3/6] Add role attribute support when linking modules Harry Ciao
@ 2011-05-29  4:36 ` Harry Ciao
  2011-05-29  4:36 ` [v1 PATCH 5/6] Add role attribute support when expanding role_set_t Harry Ciao
  2011-05-29  4:51 ` v1 Add role attribute support to libsepol HarryCiao
  5 siblings, 0 replies; 10+ messages in thread
From: Harry Ciao @ 2011-05-29  4:36 UTC (permalink / raw)
  To: cpebenito, sds, method, jmorris, eparis; +Cc: selinux

1. Copy the flavor flag into its counterpart in the out module;

2. Fix all role attributes in the base module:
2.1 remap the roles ebitmap and merge into its counterpart in the
out module;
2.2 escalate the types.types ebitmap of its counterpart in the out
module, to the counterparts for all the regular roles that belongs
to the current role attribute.

The role_fix_callback() must be called after role_copy_callback()
so that state->rolemap[] is available.

Signed-off-by: Harry Ciao <qingtao.cao@windriver.com>
---
 libsepol/src/expand.c |   76 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 76 insertions(+), 0 deletions(-)

diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
index b1af365..1a94cb4 100644
--- a/libsepol/src/expand.c
+++ b/libsepol/src/expand.c
@@ -664,6 +664,74 @@ static int role_remap_dominates(hashtab_key_t key __attribute__ ((unused)), hash
 	return 0;
 }
 
+/* For the role attribute in the base module, escalate its counterpart's
+ * types.types ebitmap in the out module to the counterparts of all the
+ * regular role that belongs to the current role attribute. Note, must be
+ * invoked after role_copy_callback so that state->rolemap is available.
+ */
+static int role_fix_callback(hashtab_key_t key, hashtab_datum_t datum,
+			     void *data)
+{
+	char *id, *base_reg_role_id;
+	role_datum_t *role, *new_role, *regular_role;
+	expand_state_t *state;
+	ebitmap_node_t *rnode;
+	unsigned int i;
+	ebitmap_t mapped_roles;
+
+	id = key;
+	role = (role_datum_t *)datum;
+	state = (expand_state_t *)data;
+
+	if (strcmp(id, OBJECT_R) == 0) {
+		/* object_r is never a role attribute by far */
+		return 0;
+	}
+
+	if (role->flavor != ROLE_ATTRIB)
+		return 0;
+
+	if (state->verbose)
+		INFO(state->handle, "fixing role attribute %s", id);
+
+	new_role =
+		(role_datum_t *)hashtab_search(state->out->p_roles.table, id);
+
+	assert(new_role != NULL);
+	assert(new_role->flavor == ROLE_ATTRIB);
+
+	ebitmap_init(&mapped_roles);
+	if (map_ebitmap(&role->roles, &mapped_roles, state->rolemap))
+		return -1;
+	if (ebitmap_union(&new_role->roles, &mapped_roles)) {
+		ERR(state->handle, "Out of memory!");
+		ebitmap_destroy(&mapped_roles);
+		return -1;
+	}
+	ebitmap_destroy(&mapped_roles);
+
+	ebitmap_for_each_bit(&role->roles, rnode, i) {
+		if (ebitmap_node_get_bit(rnode, i)) {
+			/* take advantage of sym_val_to_name[]
+			 * of the base module */
+			base_reg_role_id = state->base->p_role_val_to_name[i];
+			regular_role = (role_datum_t *)hashtab_search(
+						state->out->p_roles.table,
+						base_reg_role_id);
+			assert(regular_role != NULL);
+			assert(regular_role->flavor == ROLE_ROLE);
+
+			if (ebitmap_union(&regular_role->types.types, 
+					  &new_role->types.types)) {
+				ERR(state->handle, "Out of memory!");
+				return -1;
+			}
+		}
+	}
+	
+	return 0;
+}
+
 static int role_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
 			      void *data)
 {
@@ -709,6 +777,7 @@ static int role_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
 		}
 
 		state->out->p_roles.nprim++;
+		new_role->flavor = role->flavor;
 		new_role->s.value = state->out->p_roles.nprim;
 		state->rolemap[role->s.value - 1] = new_role->s.value;
 		ret = hashtab_insert(state->out->p_roles.table,
@@ -2673,6 +2742,10 @@ int expand_module(sepol_handle_t * handle,
 	if (hashtab_map(state.base->p_roles.table,
 			role_bounds_copy_callback, &state))
 		goto cleanup;
+	/* escalate the type_set_t in a role attribute to all regular roles
+	 * that belongs to it. */
+	if (hashtab_map(state.base->p_roles.table, role_fix_callback, &state))
+		goto cleanup;
 
 	/* copy MLS's sensitivity level and categories - this needs to be done
 	 * before expanding users (they need to be indexed too) */
@@ -2725,6 +2798,9 @@ int expand_module(sepol_handle_t * handle,
 		if (hashtab_map
 		    (decl->p_roles.table, role_copy_callback, &state))
 			goto cleanup;
+		if (hashtab_map
+		    (decl->p_roles.table, role_fix_callback, &state))
+			goto cleanup;
 
 		/* copy users */
 		if (hashtab_map
-- 
1.7.0.4


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

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

* [v1 PATCH 5/6] Add role attribute support when expanding role_set_t.
  2011-05-29  4:36 v1 Add role attribute support to libsepol Harry Ciao
                   ` (3 preceding siblings ...)
  2011-05-29  4:36 ` [v1 PATCH 4/6] Add role attribute support when expanding role_datum_t Harry Ciao
@ 2011-05-29  4:36 ` Harry Ciao
  2011-05-29  4:51 ` v1 Add role attribute support to libsepol HarryCiao
  5 siblings, 0 replies; 10+ messages in thread
From: Harry Ciao @ 2011-05-29  4:36 UTC (permalink / raw)
  To: cpebenito, sds, method, jmorris, eparis; +Cc: selinux

When the rolemap and pointer to the base module are available, if
a non-zero bit in role_set_t.roles is a role attribute, expand it
before remap.

Note, during module compile the rolemap may not be available, the
potential duplicates of a regular role and the role attribute that
the regular role belongs to could be properly handled by
copy_role_allow() and copy_role_trans() during module expansion.

Take advantage of the role_val_to_struct[] of the base module, since
when role_set_expand() is invoked, the role_val_to_struct[] of the
out module may have not been established yet.

Also cleanup the error handling of role_set_expand().

Signed-off-by: Harry Ciao <qingtao.cao@windriver.com>
---
 checkpolicy/policy_define.c              |    2 +-
 libsepol/include/sepol/policydb/expand.h |    2 +-
 libsepol/src/expand.c                    |   57 ++++++++++++++++++++++++------
 libsepol/src/policydb.c                  |    2 +-
 libsepol/src/users.c                     |    4 +-
 5 files changed, 51 insertions(+), 16 deletions(-)

diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c
index a15bfa6..402912e 100644
--- a/checkpolicy/policy_define.c
+++ b/checkpolicy/policy_define.c
@@ -2282,7 +2282,7 @@ int define_role_trans(int class_specified)
 	}
 
 	/* This ebitmap business is just to ensure that there are not conflicting role_trans rules */
-	if (role_set_expand(&roles, &e_roles, policydbp, NULL))
+	if (role_set_expand(&roles, &e_roles, policydbp, NULL, NULL))
 		goto bad;
 
 	if (type_set_expand(&types, &e_types, policydbp, 1))
diff --git a/libsepol/include/sepol/policydb/expand.h b/libsepol/include/sepol/policydb/expand.h
index 059b065..31e25ec 100644
--- a/libsepol/include/sepol/policydb/expand.h
+++ b/libsepol/include/sepol/policydb/expand.h
@@ -60,7 +60,7 @@ extern int expand_convert_type_set(policydb_t * p, uint32_t * typemap,
 				   unsigned char alwaysexpand);
 extern int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p,
 			   unsigned char alwaysexpand);
-extern int role_set_expand(role_set_t * x, ebitmap_t * r, policydb_t * p, uint32_t * rolemap);
+extern int role_set_expand(role_set_t * x, ebitmap_t * r, policydb_t * out, policydb_t * base, uint32_t * rolemap);
 extern int mls_semantic_level_expand(mls_semantic_level_t *sl, mls_level_t *l,
                                      policydb_t *p, sepol_handle_t *h);
 extern int mls_semantic_range_expand(mls_semantic_range_t *sr, mls_range_t *r,
diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
index 1a94cb4..b6babb3 100644
--- a/libsepol/src/expand.c
+++ b/libsepol/src/expand.c
@@ -982,7 +982,7 @@ static int user_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
 	ebitmap_init(&tmp_union);
 
 	/* get global roles for this user */
-	if (role_set_expand(&user->roles, &tmp_union, state->base, state->rolemap)) {
+	if (role_set_expand(&user->roles, &tmp_union, state->out, state->base, state->rolemap)) {
 		ERR(state->handle, "Out of memory!");
 		ebitmap_destroy(&tmp_union);
 		return -1;
@@ -1160,12 +1160,12 @@ static int copy_role_allows(expand_state_t * state, role_allow_rule_t * rules)
 		ebitmap_init(&roles);
 		ebitmap_init(&new_roles);
 
-		if (role_set_expand(&cur->roles, &roles, state->out, state->rolemap)) {
+		if (role_set_expand(&cur->roles, &roles, state->out, state->base, state->rolemap)) {
 			ERR(state->handle, "Out of memory!");
 			return -1;
 		}
 
-		if (role_set_expand(&cur->new_roles, &new_roles, state->out, state->rolemap)) {
+		if (role_set_expand(&cur->new_roles, &new_roles, state->out, state->base, state->rolemap)) {
 			ERR(state->handle, "Out of memory!");
 			return -1;
 		}
@@ -1229,7 +1229,7 @@ static int copy_role_trans(expand_state_t * state, role_trans_rule_t * rules)
 		ebitmap_init(&roles);
 		ebitmap_init(&types);
 
-		if (role_set_expand(&cur->roles, &roles, state->out, state->rolemap)) {
+		if (role_set_expand(&cur->roles, &roles, state->out, state->base, state->rolemap)) {
 			ERR(state->handle, "Out of memory!");
 			return -1;
 		}
@@ -2268,14 +2268,23 @@ int expand_rule(sepol_handle_t * handle,
 	return retval;
 }
 
-int role_set_expand(role_set_t * x, ebitmap_t * r, policydb_t * p, uint32_t * rolemap)
+/* Expand a role set into an ebitmap containing the roles.
+ * This handles the attribute and flags.
+ * Attribute expansion depends on if the rolemap is available.
+ * During module compile the rolemap is not available, the
+ * possible duplicates of a regular role and the role attribute
+ * the regular role belongs to could be properly handled by
+ * copy_role_trans and copy_role_allow.
+ */
+int role_set_expand(role_set_t * x, ebitmap_t * r, policydb_t * out, policydb_t * base, uint32_t * rolemap)
 {
 	unsigned int i;
 	ebitmap_node_t *rnode;
-	ebitmap_t mapped_roles;
+	ebitmap_t mapped_roles, roles;
+	policydb_t *p = out;
+	role_datum_t *role;
 
 	ebitmap_init(r);
-	ebitmap_init(&mapped_roles);
 
 	if (x->flags & ROLE_STAR) {
 		for (i = 0; i < p->p_roles.nprim++; i++)
@@ -2284,22 +2293,43 @@ int role_set_expand(role_set_t * x, ebitmap_t * r, policydb_t * p, uint32_t * ro
 		return 0;
 	}
 
+	ebitmap_init(&mapped_roles);
+	ebitmap_init(&roles);
+	
 	if (rolemap) {
-		if (map_ebitmap(&x->roles, &mapped_roles, rolemap))
-			return -1;
+		assert(base != NULL);
+		ebitmap_for_each_bit(&x->roles, rnode, i) {
+			if (ebitmap_node_get_bit(rnode, i)) {
+				/* take advantage of p_role_val_to_struct[]
+				 * of the base module */
+				role = base->role_val_to_struct[i];
+				assert(role != NULL);
+				if (role->flavor == ROLE_ATTRIB) {
+					if (ebitmap_union(&roles,
+							  &role->roles))
+						goto bad;
+				} else {
+					if (ebitmap_set_bit(&roles, i, 1))
+						goto bad;
+				}
+			}
+		}
+		if (map_ebitmap(&roles, &mapped_roles, rolemap))
+			goto bad;
 	} else {
 		if (ebitmap_cpy(&mapped_roles, &x->roles))
-			return -1;
+			goto bad;
 	}
 
 	ebitmap_for_each_bit(&mapped_roles, rnode, i) {
 		if (ebitmap_node_get_bit(rnode, i)) {
 			if (ebitmap_set_bit(r, i, 1))
-				return -1;
+				goto bad;
 		}
 	}
 
 	ebitmap_destroy(&mapped_roles);
+	ebitmap_destroy(&roles);
 
 	/* if role is to be complimented, invert the entire bitmap here */
 	if (x->flags & ROLE_COMP) {
@@ -2314,6 +2344,11 @@ int role_set_expand(role_set_t * x, ebitmap_t * r, policydb_t * p, uint32_t * ro
 		}
 	}
 	return 0;
+
+bad:
+	ebitmap_destroy(&mapped_roles);
+	ebitmap_destroy(&roles);
+	return -1;
 }
 
 /* Expand a type set into an ebitmap containing the types. This
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index 1e3abac..4187f09 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -698,7 +698,7 @@ int policydb_user_cache(hashtab_key_t key
 	p = (policydb_t *) arg;
 
 	ebitmap_destroy(&user->cache);
-	if (role_set_expand(&user->roles, &user->cache, p, NULL)) {
+	if (role_set_expand(&user->roles, &user->cache, p, NULL, NULL)) {
 		return -1;
 	}
 
diff --git a/libsepol/src/users.c b/libsepol/src/users.c
index 17e1426..693210d 100644
--- a/libsepol/src/users.c
+++ b/libsepol/src/users.c
@@ -259,8 +259,8 @@ int sepol_user_modify(sepol_handle_t * handle,
 		name = NULL;
 
 		/* Expand roles */
-		if (role_set_expand
-		    (&usrdatum->roles, &usrdatum->cache, policydb, NULL)) {
+		if (role_set_expand(&usrdatum->roles, &usrdatum->cache,
+				    policydb, NULL, NULL)) {
 			ERR(handle, "unable to expand role set");
 			goto err;
 		}
-- 
1.7.0.4


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

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

* RE: v1 Add role attribute support to libsepol
  2011-05-29  4:36 v1 Add role attribute support to libsepol Harry Ciao
                   ` (4 preceding siblings ...)
  2011-05-29  4:36 ` [v1 PATCH 5/6] Add role attribute support when expanding role_set_t Harry Ciao
@ 2011-05-29  4:51 ` HarryCiao
  2011-05-29 10:41   ` HarryCiao
  5 siblings, 1 reply; 10+ messages in thread
From: HarryCiao @ 2011-05-29  4:51 UTC (permalink / raw)
  To: qingtao.cao, Christopher J. PeBenito, Stephen Smalley, method,
	jmorris, eparis
  Cc: selinux-mailing-list


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


Attach the refpolicy patch to test adding one role attribute into another.

> From: qingtao.cao@windriver.com
> To: cpebenito@tresys.com; sds@tycho.nsa.gov; method@manicmethod.com; jmorris@namei.org; eparis@parisplace.org
> CC: selinux@tycho.nsa.gov
> Subject: v1 Add role attribute support to libsepol
> Date: Sun, 29 May 2011 12:36:53 +0800
> 
> 
> 
> Comments
> ---------
> 
>     Support adding one role attribute into another.
>     
>     When the link process is completed, the types type_set_t and roles
>     ebitmap in a role attribute are settled, then we could go on scan
>     all role attributes in the base.p_roles table checking if any non-zero
>     bit in its roles ebitmap is indeed another role attribute.
>     
>     If this is the case, then we need to escalate the roles ebitmap of
>     the sub-attribute into that of the parent attribute, and remove the
>     sub-attribute from parent's roles ebitmap.
>     
>     Since sub-attribute's roles ebitmap may further contain other role
>     attributes, we need to re-scan the updated parent's roles ebitmap.
>     
>     Also if a loop dependency is detected, no escalation of sub-attribute's
>     roles ebitmap is needed.
> 
> 
>     In order to highlight this patch I've decided to introduce a new
>     separate commit, while all the rest 5 commits are the same as v0.
> 
> 
> Tests of adding one role attribute into another
> ------------------------------------------------
>    
> 1. Apply the patch for rpm.* and selinuxuti.*, to introduce rpm_roles and
>    semanage_roles attributes and eliminate the "chain of run interfaces",
>    make policy.X and dump its hexdump, check out the policy value for
>    related identifiers:
>    
>    0035b00: 5f74 0500 0000 4103 0000 0100 0000 0000  _t....A.........
>    0035b10: 0000 7270 6d5f 7407 0000 0042 0300 0001  ..rpm_t....
>    
>    rpm_t: policy value = 0x341
>    
>    0040460: 740c 0000 0075 0700 0001 0000 0000 0000  t....u..........
>    0040470: 0072 706d 5f73 6372 6970 745f 740f 0000  .rpm_script_t.
>    
>    rpm_script_t: policy value = 0x775
>    
>    004c900: 6563 7572 6974 795f 740a 0000 001e 0c00  ecurity_t.......
>    004c910: 0001 0000 0000 0000 0073 656d 616e 6167  .........semanag
>    004c920: 655f 7409 0000 001f 0c00 0003 0000 0000  e_t
>    
>    semanage_t: policy value = 0xc1e
>    
>    004c760: 0a00 0000 140c 0000 0100 0000 0000 0000  ................
>    004c770: 7365 7466 696c 6573 5f74 1400 0000 ec0a  setfiles_t......
>    
>    setfiles_t: policy value = 0xc14
>    
>    00484e0: 740d 0000 008b 0a00 0001 0000 0000 0000  t...............
>    00484f0: 006c 6f61 645f 706f 6c69 6379 5f74 0c00  .load_policy_t..
>    
>    load_policy_t: policy value = 0xa8b
>    
>    
> 2. Check out rpm_roles.types ebitmap:
>    
>    002d2c0: 0000 0400 0000 0000 0000 0900 0000 0f00  ................
>    002d2d0: 0000 0000 0000 7270 6d5f 726f 6c65 7340  ......rpm_roles@
>    002d2e0: 0000 0040 0000 0001 0000 0000 0000 0000  ...@............
>    002d2f0: 4000 0000 0000 0040 0000 0080 0700 0002  @......@........
>    002d300: 0000 0040 0300 0001 0000 0000 0000 0040  ...@...........@
>    002d310: 0700 0000 0000 0000 0010 000b 0000 0010  ................
>    002d320: 0000 0000 0000 006e 785f 7365 7276 6572  .......
>    
>    rpm_roles: policy value = 0x0f
>    	dominates:
>   		mz = 0x40, highbit = 0x40, node = 1
> 		startbit = 0, map: 00 4000 0000 0000 00 
> 			policy value: 0x0f(rpm_roles)
>    	types.types:
>    		mz = 0x40, highbit = 0x780, node = 2
>    		startbit = 0x340, map: 01 0000 0000 0000 00
> 			policy value: 0x341(rpm_t)
>    		startbit = 0x740, map: 00 0000 0000 0010 00
> 			policy value: 0x775(rpm_script_t)
>    
>    
> 3. Check out semanage_roles.types ebitmap:
>    
>    002caa0: 0000 0000 0e00 0000 0800 0000 0000 0000  ................
>    002cab0: 7365 6d61 6e61 6765 5f72 6f6c 6573 4000  semanage_roles@.
>    002cac0: 0000 4000 0000 0100 0000 0000 0000 8000  ..@.............
>    002cad0: 0000 0000 0000 4000 0000 400c 0000 0200  ......@...@.....
>    002cae0: 0000 800a 0000 0004 0000 0000 0000 000c  ................
>    002caf0: 0000 0000 0820 0000 0000 1000 0000 0900  ..... ..........
>    002cb00: 0000 0000 0000 726f 6c65 5f61 7474 7269  ......
>    
>    semanage_roles: policy value = 0x08
>    	dominates:
>   		mz = 0x40, highbit = 0x40, node = 1, 
> 		startbit = 0, map: 8000 0000 0000 0000 
> 			policy value: 8(semanage_roles)
>    	types.types:
>    		mz = 0x40, highbit = 0xc40 node = 2
> 		startbit = 0xa80, map: 0004 0000 0000 0000
> 			policy value: 0xa8b(load_policy_t)
> 		startbit = 0xc00, map: 0000 0820 0000 0000
> 			policy value: 0xc14(setfiles_t), 0xc1e(semanage_t)
>    
>    
> 4. Verify that once rpm_roles attribute becomes a sub-attribute of
>    semanage_roles attribute, then all regular roles belonging to rpm_roles
>    such as sysadm_r should be able to type all those types of the parent role
>    attribute's types(that is, semanage_roles.types):
>    
>    002ccc0: 0000 0800 0000 0b00 0000 0000 0000 7379  ..............sy
>    002ccd0: 7361 646d 5f72 4000 0000 4000 0000 0100  sadm_r@...@.....
>    002cce0: 0000 0000 0000 0004 0000 0000 0000 4000  ..............@.
>    002ccf0: 0000 800d 0000 2d00 0000 8000 0000 0000  ......-.........
>    ...
>    002cd70: 5808, 4003 0000 0906 0200 0000 0000, 8003  X.@.............
>    ...
>    002cdf0: 4000 0000 0900 c006 0000 0000 0008 0000  @...............
>    002ce00: 0000, 4007 0000 4000 0000 0000 1006, 8007  ..@...@.........
>    002ce10: 0000 0000 000a 0000 0000 c007 0000 0080  ................
>    ...
>    002ce90: 8000, 400a 0000 0000 0000 0000 0040, 800a  ..@..........@..
>    002cea0: 0000 0004 0002 0000 0000 c00a 0000 0000  ................
>    002ceb0: 0000 8000 0000 000b 0000 0000 0080 0080  ................
>    002cec0: 0000 c00b 0000 0000 0000 1000 0000, 000c  ................
>    002ced0: 0000 0000 3820 0004 0000 400c 0000 0400  ....8 ....@.....
>    ...
>    
>    sysadm_r: policy value = 0x0b
>    	dominates:
>    		mz = 0x40, highbit = 0x40, node = 1
>    		startbit = 0x0, map: 0004 0000 0000 0000
> 			policy value: 0x0b(sysadm_r)
>    	types.types:
>    		mz = 0x40, highbit = 0xd80, node = 0x2d
>    		startbit = 0x340, map: 0906 0200 0000 0000
>    			policy value: 341(rpm_t), 344, 34a, 34b
>    
>    		startbit = 0x740, map: 4000 0000 0000 1006
>    			policy value: 747, 775(rpm_script_t), 77a, 77b
>    
>    		startbit = 0xa80, map: 0004 0002 0000 0000
>    			policy value: a8b(load_policy_t), a9a
>    
>    		startbit = 0xc00, map: 0000 3820 0004 0000 
>    			policy value: c14(setfiles_t), c15, c16, c1e(semanage_t)
>    
>    
> 5. Extra loop depenency tests.
>    
> 5.1 When there is no loop dependency between rpm_roles and semanage_roles
>    attributes, the secadm_r that belongs to semanage_roles attributes is
>    not able to type those types of the rpm_roles.types, such as rpm_t or
>    rpm_script_t:
>    
>    002cb60: 0000 0a00 0000 0000 0000 7365 6361 646d  ..........secadm
>    002cb70: 5f72 4000 0000 4000 0000 0100 0000 0000  _r@...@.........
>    002cb80: 0000 0002 0000 0000 0000 4000 0000 400d  ..........@...@.
>    002cb90: 0000 1900 0000 8000 0000 0000 0000 0200  ................
>    ...
>    002cbe0: 0000 0400 0200 0000 1800, 4003 0000 0002  ..........@.....
>    002cbf0: 0000 0000 0000 c003 0000 0000 0000 0000  ................
>    ...
>    002cc30: 0800 4006 0000 0000 0000 0000 0100, 4007  ..@...........@.
>    002cc40: 0000 0000 0000 0000 2000 4009 0000 0000  ........ .@.....
>    002cc50: 0000 0000 0420 8009 0000 0000 0820 0000  ..... ....... ..
>    
>    secadm_r:
>    	types.types:
>    		mz = 0x40, highbit = 0xd40, node = 0x19
>    		startbit = 0x340, map: 0002 0000 0000 0000
>    			policy value: 34a, ... 
>    		
>    		startbit = 0x740, map: 0000 0000 0000 2000
>    			policy value: 776
>    
>    
> 5.2 Add below statements in selinuxutil.te to create a loop dependcy
>    between rpm_roles and semanage_roles attributes:
>    
>    attribute rpm_roles ROLE;
>    roleattribute semanage_roles rpm_roles;
>    
>    Then rebuild policy.X in modular way, the loop dependency should be
>    properly handled, and secadm_r that belongs to the semanage_roles
>    should be able to type all those types in rpm_roles.types ebitmap,
>    such as rpm_t and rpm_script_t:
>    
>    002cb60: 0000 0a00 0000 0000 0000 7365 6361 646d  ..........secadm
>    002cb70: 5f72 4000 0000 4000 0000 0100 0000 0000  _r@...@.........
>    002cb80: 0000 0002 0000 0000 0000 4000 0000 400d  ..........@...@.
>    002cb90: 0000 1900 0000 8000 0000 0000 0000 0200  ................
>    ...
>    002cbe0: 0000 0400 0200 0000 1800, 4003 0000 0102  ..........@.....
>    002cbf0: 0000 0000 0000 c003 0000 0000 0000 0000  ................
>    ...
>    002cc30: 0800 4006 0000 0000 0000 0000 0100, 4007  ..@...........@.
>    002cc40: 0000 0000 0000 0000 3000 4009 0000 0000  ........0.@.....
>    002cc50: 0000 0000 0420 8009 0000 0000 0820 0000  ..... ....... ..
>    
>    secadm_r:
>    	types.types:
>    		mz = 0x40, highbit = 0xd40, node = 0x19
>    		startbit = 0x340, map: 0102 0000 0000 0000
>    			policy value: 341(rpm_t), ... 
>    		
>    		startbit = 0x740, map: 0000 0000 0000 3000
>    			policy value: 775(rpm_script_t), 776
> 
> --
> This message was distributed to subscribers of the selinux mailing list.
> If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
> the words "unsubscribe selinux" without quotes as the message.
 		 	   		  

[-- Attachment #1.2: Type: text/html, Size: 11111 bytes --]

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Test-adding-one-role-attribute-into-another.patch --]
[-- Type: text/x-patch, Size: 3921 bytes --]

From 16829156f34aedf220a132062d6efeb4cfec15e5 Mon Sep 17 00:00:00 2001
From: Harry Ciao <qingtao.cao@windriver.com>
Date: Sun, 29 May 2011 12:47:42 +0800
Subject: [PATCH 1/1] Test adding one role attribute into another.


Signed-off-by: Harry Ciao <qingtao.cao@windriver.com>
---
 policy/modules/admin/rpm.if          |   14 ++++++++++----
 policy/modules/admin/rpm.te          |   11 +++++++++++
 policy/modules/system/selinuxutil.if |   12 +++++++++---
 policy/modules/system/selinuxutil.te |   16 ++++++++++++++++
 4 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/policy/modules/admin/rpm.if b/policy/modules/admin/rpm.if
index d33daa8..7a7a4fe 100644
--- a/policy/modules/admin/rpm.if
+++ b/policy/modules/admin/rpm.if
@@ -82,10 +82,16 @@ interface(`rpm_run',`
 	')
 
 	rpm_domtrans($1)
-	role $2 types { rpm_t rpm_script_t };
-	seutil_run_loadpolicy(rpm_script_t, $2)
-	seutil_run_semanage(rpm_script_t, $2)
-	seutil_run_setfiles(rpm_script_t, $2)
+
+	# should require not declare an attribute here
+	attribute rpm_roles ROLE;	
+
+	roleattribute $2 rpm_roles;
+
+#	role $2 types { rpm_t rpm_script_t };
+#	seutil_run_loadpolicy(rpm_script_t, $2)
+#	seutil_run_semanage(rpm_script_t, $2)
+#	seutil_run_setfiles(rpm_script_t, $2)
 ')
 
 ########################################
diff --git a/policy/modules/admin/rpm.te b/policy/modules/admin/rpm.te
index 47a8f7d..d216048 100644
--- a/policy/modules/admin/rpm.te
+++ b/policy/modules/admin/rpm.te
@@ -192,6 +192,17 @@ seutil_manage_bin_policy(rpm_t)
 userdom_use_user_terminals(rpm_t)
 userdom_use_unpriv_users_fds(rpm_t)
 
+# Test: add one role attribute into another
+attribute rpm_roles ROLE;
+role rpm_roles types { rpm_t rpm_script_t };
+seutil_run_semanage(rpm_script_t, rpm_roles)
+# semanage_t could transition into load_policy_t and setfiles_t
+# so there is no need to explicitly invoke seutil_run_loadpolicy()
+# and seutil_run_setfiles() for the rpm_script_t
+#seutil_run_loadpolicy(rpm_script_t, rpm_roles)
+#seutil_run_setfiles(rpm_script_t, rpm_roles)
+
+
 optional_policy(`
 	cron_system_entry(rpm_t, rpm_exec_t)
 ')
diff --git a/policy/modules/system/selinuxutil.if b/policy/modules/system/selinuxutil.if
index 170e2c7..31a11ec 100644
--- a/policy/modules/system/selinuxutil.if
+++ b/policy/modules/system/selinuxutil.if
@@ -1030,10 +1030,16 @@ interface(`seutil_run_semanage',`
 		type semanage_t;
 	')
 
+	# should require not declare an attribute here
+	attribute semanage_roles ROLE;	
+
 	seutil_domtrans_semanage($1)
-	seutil_run_setfiles(semanage_t, $2)
-	seutil_run_loadpolicy(semanage_t, $2)
-	role $2 types semanage_t;
+
+	roleattribute $2 semanage_roles;
+
+#	seutil_run_setfiles(semanage_t, $2)
+#	seutil_run_loadpolicy(semanage_t, $2)
+#	role $2 types semanage_t;
 ')
 
 ########################################
diff --git a/policy/modules/system/selinuxutil.te b/policy/modules/system/selinuxutil.te
index 65e0698..5ef0e35 100644
--- a/policy/modules/system/selinuxutil.te
+++ b/policy/modules/system/selinuxutil.te
@@ -482,6 +482,22 @@ seutil_manage_default_contexts(semanage_t)
 userdom_read_user_home_content_files(semanage_t)
 userdom_read_user_tmp_files(semanage_t)
 
+# Declare a semanage_role which is able to type all kinds of
+# domains provided by selinuxutil.pp
+attribute semanage_roles ROLE;
+role semanage_roles types { semanage_t setfiles_t load_policy_t };
+
+# Administrator only needs to invoke seutil_run_semanage(), while
+# semanage_t is able to transition into other domains provided by
+# selinuxutil.pp
+seutil_run_setfiles(semanage_t, semanage_roles)
+seutil_run_loadpolicy(semanage_t, semanage_roles)
+
+# A role attribute loop dependency test
+# should require rather than declare the role attribute here
+#attribute rpm_roles ROLE;
+#roleattribute semanage_roles rpm_roles;
+
 ifdef(`distro_debian',`
 	files_read_var_lib_files(semanage_t)
 	files_read_var_lib_symlinks(semanage_t)
-- 
1.7.0.4


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

* RE: v1 Add role attribute support to libsepol
  2011-05-29  4:51 ` v1 Add role attribute support to libsepol HarryCiao
@ 2011-05-29 10:41   ` HarryCiao
  0 siblings, 0 replies; 10+ messages in thread
From: HarryCiao @ 2011-05-29 10:41 UTC (permalink / raw)
  To: Christopher J. PeBenito, Stephen Smalley, method, jmorris, eparis
  Cc: selinux-mailing-list


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


Hi,

Sorry I seems to have some problem to send the last 6/6 patch by git send-mail, try again and re-send it by attachment. 

This 6/6 patch adds support to adding one role attribute into another, while the first 5 patches are the same as v0.

Thanks!
Harry

From: harrytaurus2002@hotmail.com
To: qingtao.cao@windriver.com; cpebenito@tresys.com; sds@tycho.nsa.gov; method@manicmethod.com; jmorris@namei.org; eparis@parisplace.org
CC: selinux@tycho.nsa.gov
Subject: RE: v1 Add role attribute support to libsepol
Date: Sun, 29 May 2011 04:51:26 +0000








Attach the refpolicy patch to test adding one role attribute into another.

> From: qingtao.cao@windriver.com
> To: cpebenito@tresys.com; sds@tycho.nsa.gov; method@manicmethod.com; jmorris@namei.org; eparis@parisplace.org
> CC: selinux@tycho.nsa.gov
> Subject: v1 Add role attribute support to libsepol
> Date: Sun, 29 May 2011 12:36:53 +0800
> 
> 
> 
> Comments
> ---------
> 
>     Support adding one role attribute into another.
>     
>     When the link process is completed, the types type_set_t and roles
>     ebitmap in a role attribute are settled, then we could go on scan
>     all role attributes in the base.p_roles table checking if any non-zero
>     bit in its roles ebitmap is indeed another role attribute.
>     
>     If this is the case, then we need to escalate the roles ebitmap of
>     the sub-attribute into that of the parent attribute, a!
 nd remove the
>     sub-attribute from parent's roles ebitmap.
>     
>     Since sub-attribute's roles ebitmap may further contain other role
>     attributes, we need to re-scan the updated parent's roles ebitmap.
>     
>     Also if a loop dependency is detected, no escalation of sub-attribute's
>     roles ebitmap is needed.
> 
> 
>     In order to highlight this patch I've decided to introduce a new
>     separate commit, while all the rest 5 commits are the same as v0.
> 
> 
> Tests of adding one role attribute into another
> ------------------------------------------------
>    
> 1. Apply the patch for rpm.* and selinuxuti.*, to introduce rpm_roles and
>    semanage_roles attributes and eliminate the "chain of run interfaces",
>    make policy.X and dump its hexdump, check out the policy value for
>    related identifiers:
>    
>    0!
 035b00: 5f74 0500 0000 4103 0000 0100 0000 0000  _t....A.........
&
gt;    0035b10: 0000 7270 6d5f 7407 0000 0042 0300 0001  ..rpm_t....
>    
>    rpm_t: policy value = 0x341
>    
>    0040460: 740c 0000 0075 0700 0001 0000 0000 0000  t....u..........
>    0040470: 0072 706d 5f73 6372 6970 745f 740f 0000  .rpm_script_t.
>    
>    rpm_script_t: policy value = 0x775
>    
>    004c900: 6563 7572 6974 795f 740a 0000 001e 0c00  ecurity_t.......
>    004c910: 0001 0000 0000 0000 0073 656d 616e 6167  .........semanag
>    004c920: 655f 7409 0000 001f 0c00 0003 0000 0000  e_t
>    
>    semanage_t: policy value = 0xc1e
>    
>    004c760: 0a00 0000 140c 0000 0100 0000 0000 0000  ................
>    004c770: 7365 7466 696c 6573 5f74 1400 0000 ec0a  setfiles_t......
>    
>    setfiles_t: policy value = 0xc14
>    
>    00484e0: 740d 0000 008b 0a00 0001 0000 0000 0000  t...............
>    00484f0: 006c 6f61 645f 706f 6c!
 69 6379 5f74 0c00  .load_policy_t..
>    
>    load_policy_t: policy value = 0xa8b
>    
>    
> 2. Check out rpm_roles.types ebitmap:
>    
>    002d2c0: 0000 0400 0000 0000 0000 0900 0000 0f00  ................
>    002d2d0: 0000 0000 0000 7270 6d5f 726f 6c65 7340  ......rpm_roles@
>    002d2e0: 0000 0040 0000 0001 0000 0000 0000 0000  ...@............
>    002d2f0: 4000 0000 0000 0040 0000 0080 0700 0002  @......@........
>    002d300: 0000 0040 0300 0001 0000 0000 0000 0040  ...@...........@
>    002d310: 0700 0000 0000 0000 0010 000b 0000 0010  ................
>    002d320: 0000 0000 0000 006e 785f 7365 7276 6572  .......
>    
>    rpm_roles: policy value = 0x0f
>    	dominates:
>   		mz = 0x40, highbit = 0x40, node = 1
> 		startbit = 0, map: 00 4000 0000 0000 00 
> 			policy value: 0x0f(rpm_roles)
>    	types.types:
>    		mz = 0x40, highbit !
 = 0x780, node = 2
>    		startbit = 0x340, map: 01 0000 0000 000
0 00
> 			policy value: 0x341(rpm_t)
>    		startbit = 0x740, map: 00 0000 0000 0010 00
> 			policy value: 0x775(rpm_script_t)
>    
>    
> 3. Check out semanage_roles.types ebitmap:
>    
>    002caa0: 0000 0000 0e00 0000 0800 0000 0000 0000  ................
>    002cab0: 7365 6d61 6e61 6765 5f72 6f6c 6573 4000  semanage_roles@.
>    002cac0: 0000 4000 0000 0100 0000 0000 0000 8000  ..@.............
>    002cad0: 0000 0000 0000 4000 0000 400c 0000 0200  ......@...@.....
>    002cae0: 0000 800a 0000 0004 0000 0000 0000 000c  ................
>    002caf0: 0000 0000 0820 0000 0000 1000 0000 0900  ..... ..........
>    002cb00: 0000 0000 0000 726f 6c65 5f61 7474 7269  ......
>    
>    semanage_roles: policy value = 0x08
>    	dominates:
>   		mz = 0x40, highbit = 0x40, node = 1, 
> 		startbit = 0, map: 8000 0000 0000 0000 
> 			policy value: 8(semanage_rol!
 es)
>    	types.types:
>    		mz = 0x40, highbit = 0xc40 node = 2
> 		startbit = 0xa80, map: 0004 0000 0000 0000
> 			policy value: 0xa8b(load_policy_t)
> 		startbit = 0xc00, map: 0000 0820 0000 0000
> 			policy value: 0xc14(setfiles_t), 0xc1e(semanage_t)
>    
>    
> 4. Verify that once rpm_roles attribute becomes a sub-attribute of
>    semanage_roles attribute, then all regular roles belonging to rpm_roles
>    such as sysadm_r should be able to type all those types of the parent role
>    attribute's types(that is, semanage_roles.types):
>    
>    002ccc0: 0000 0800 0000 0b00 0000 0000 0000 7379  ..............sy
>    002ccd0: 7361 646d 5f72 4000 0000 4000 0000 0100  sadm_r@...@.....
>    002cce0: 0000 0000 0000 0004 0000 0000 0000 4000  ..............@.
>    002ccf0: 0000 800d 0000 2d00 0000 8000 0000 0000  ......-.........
>    ...
>    002cd70: 5808, 40!
 03 0000 0906 0200 0000 0000, 8003  X.@.............
>    ...

>    002cdf0: 4000 0000 0900 c006 0000 0000 0008 0000  @...............
>    002ce00: 0000, 4007 0000 4000 0000 0000 1006, 8007  ..@...@.........
>    002ce10: 0000 0000 000a 0000 0000 c007 0000 0080  ................
>    ...
>    002ce90: 8000, 400a 0000 0000 0000 0000 0040, 800a  ..@..........@..
>    002cea0: 0000 0004 0002 0000 0000 c00a 0000 0000  ................
>    002ceb0: 0000 8000 0000 000b 0000 0000 0080 0080  ................
>    002cec0: 0000 c00b 0000 0000 0000 1000 0000, 000c  ................
>    002ced0: 0000 0000 3820 0004 0000 400c 0000 0400  ....8 ....@.....
>    ...
>    
>    sysadm_r: policy value = 0x0b
>    	dominates:
>    		mz = 0x40, highbit = 0x40, node = 1
>    		startbit = 0x0, map: 0004 0000 0000 0000
> 			policy value: 0x0b(sysadm_r)
>    	types.types:
>    		mz = 0x40, highbit = 0xd80, node = 0x2d
>    		startbit = 0x340, map: !
 0906 0200 0000 0000
>    			policy value: 341(rpm_t), 344, 34a, 34b
>    
>    		startbit = 0x740, map: 4000 0000 0000 1006
>    			policy value: 747, 775(rpm_script_t), 77a, 77b
>    
>    		startbit = 0xa80, map: 0004 0002 0000 0000
>    			policy value: a8b(load_policy_t), a9a
>    
>    		startbit = 0xc00, map: 0000 3820 0004 0000 
>    			policy value: c14(setfiles_t), c15, c16, c1e(semanage_t)
>    
>    
> 5. Extra loop depenency tests.
>    
> 5.1 When there is no loop dependency between rpm_roles and semanage_roles
>    attributes, the secadm_r that belongs to semanage_roles attributes is
>    not able to type those types of the rpm_roles.types, such as rpm_t or
>    rpm_script_t:
>    
>    002cb60: 0000 0a00 0000 0000 0000 7365 6361 646d  ..........secadm
>    002cb70: 5f72 4000 0000 4000 0000 0100 0000 0000  _r@...@.........
>    00!
 2cb80: 0000 0002 0000 0000 0000 4000 0000 400d  ..........@...@.
&g
t;    002cb90: 0000 1900 0000 8000 0000 0000 0000 0200  ................
>    ...
>    002cbe0: 0000 0400 0200 0000 1800, 4003 0000 0002  ..........@.....
>    002cbf0: 0000 0000 0000 c003 0000 0000 0000 0000  ................
>    ...
>    002cc30: 0800 4006 0000 0000 0000 0000 0100, 4007  ..@...........@.
>    002cc40: 0000 0000 0000 0000 2000 4009 0000 0000  ........ .@.....
>    002cc50: 0000 0000 0420 8009 0000 0000 0820 0000  ..... ....... ..
>    
>    secadm_r:
>    	types.types:
>    		mz = 0x40, highbit = 0xd40, node = 0x19
>    		startbit = 0x340, map: 0002 0000 0000 0000
>    			policy value: 34a, ... 
>    		
>    		startbit = 0x740, map: 0000 0000 0000 2000
>    			policy value: 776
>    
>    
> 5.2 Add below statements in selinuxutil.te to create a loop dependcy
>    between rpm_roles and semanage_roles attributes:
>    
>    att!
 ribute rpm_roles ROLE;
>    roleattribute semanage_roles rpm_roles;
>    
>    Then rebuild policy.X in modular way, the loop dependency should be
>    properly handled, and secadm_r that belongs to the semanage_roles
>    should be able to type all those types in rpm_roles.types ebitmap,
>    such as rpm_t and rpm_script_t:
>    
>    002cb60: 0000 0a00 0000 0000 0000 7365 6361 646d  ..........secadm
>    002cb70: 5f72 4000 0000 4000 0000 0100 0000 0000  _r@...@.........
>    002cb80: 0000 0002 0000 0000 0000 4000 0000 400d  ..........@...@.
>    002cb90: 0000 1900 0000 8000 0000 0000 0000 0200  ................
>    ...
>    002cbe0: 0000 0400 0200 0000 1800, 4003 0000 0102  ..........@.....
>    002cbf0: 0000 0000 0000 c003 0000 0000 0000 0000  ................
>    ...
>    002cc30: 0800 4006 0000 0000 0000 0000 0100, 4007  ..@...........@.
>    002cc40: 0000 0000 0000 !
 0000 3000 4009 0000 0000  ........0.@.....
>    002cc50: 0000 00
00 0420 8009 0000 0000 0820 0000  ..... ....... ..
>    
>    secadm_r:
>    	types.types:
>    		mz = 0x40, highbit = 0xd40, node = 0x19
>    		startbit = 0x340, map: 0102 0000 0000 0000
>    			policy value: 341(rpm_t), ... 
>    		
>    		startbit = 0x740, map: 0000 0000 0000 3000
>    			policy value: 775(rpm_script_t), 776
> 
> --
> This message was distributed to subscribers of the selinux mailing list.
> If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
> the words "unsubscribe selinux" without quotes as the message.
 		 	   		  

[-- Attachment #1.2: Type: text/html, Size: 12000 bytes --]

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0006-Support-adding-one-role-attribute-into-another.patch --]
[-- Type: text/x-patch, Size: 3925 bytes --]

From c4f111176422eeb385eff04be801c27db0ca4ca3 Mon Sep 17 00:00:00 2001
From: Harry Ciao <qingtao.cao@windriver.com>
Date: Sun, 29 May 2011 11:50:40 +0800
Subject: [v1 PATCH 6/6] Support adding one role attribute into another.

When the link process is completed, the types type_set_t and roles
ebitmap in a role attribute are settled, then we could go on scan
all role attributes in the base.p_roles table checking if any non-zero
bit in its roles ebitmap is indeed another role attribute.

If this is the case, then we need to escalate the roles ebitmap of
the sub-attribute into that of the parent attribute, and remove the
sub-attribute from parent's roles ebitmap.

Since sub-attribute's roles ebitmap may further contain other role
attributes, we need to re-scan the updated parent's roles ebitmap.

Also if a loop dependency is detected, no escalation of sub-attribute's
roles ebitmap is needed.

Signed-off-by: Harry Ciao <qingtao.cao@windriver.com>
---
 checkpolicy/policy_define.c |    5 ++-
 libsepol/src/link.c         |   62 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c
index 402912e..6f48c50 100644
--- a/checkpolicy/policy_define.c
+++ b/checkpolicy/policy_define.c
@@ -1895,8 +1895,9 @@ int define_roleattribute(void)
 		return -1;
 	}
 	r = hashtab_search(policydbp->p_roles.table, id);
-	if (!r || r->flavor != ROLE_ROLE) {
-		yyerror2("unknown role %s, or not a regular role", id);
+	/* We support adding one role attribute into another */
+	if (!r) {
+		yyerror2("unknown role %s", id);
 		free(id);
 		return -1;
 	}
diff --git a/libsepol/src/link.c b/libsepol/src/link.c
index 53fcff9..3a6fa5a 100644
--- a/libsepol/src/link.c
+++ b/libsepol/src/link.c
@@ -2335,6 +2335,62 @@ static int prepare_base(link_state_t * state, uint32_t num_mod_decls)
 	return 0;
 }
 
+static int expand_role_attributes(hashtab_key_t key, hashtab_datum_t datum,
+				  void * data)
+{
+	char *id;
+	role_datum_t *role, *sub_attr;
+	link_state_t *state;
+	unsigned int i;
+	ebitmap_node_t *rnode;
+
+	id = key;
+	role = (role_datum_t *)datum;
+	state = (link_state_t *)data;
+
+	if (strcmp(id, OBJECT_R) == 0){
+		/* object_r is never a role attribute by far */
+		return 0;
+	}
+
+	if (role->flavor != ROLE_ATTRIB)
+		return 0;
+
+	if (state->verbose)
+		INFO(state->handle, "expanding role attribute %s", id);
+
+restart:
+	ebitmap_for_each_bit(&role->roles, rnode, i) {
+		if (ebitmap_node_get_bit(rnode, i)) {
+			sub_attr = state->base->role_val_to_struct[i];
+			if (sub_attr->flavor != ROLE_ATTRIB)
+				continue;
+			
+			/* remove the sub role attribute from the parent
+			 * role attribute's roles ebitmap */
+			if (ebitmap_set_bit(&role->roles, i, 0))
+				return -1;
+
+			/* loop dependency of role attributes */
+			if (sub_attr->s.value == role->s.value)
+				continue;
+
+			/* now go on to expand a sub role attribute
+			 * by escalating its roles ebitmap */
+			if (ebitmap_union(&role->roles, &sub_attr->roles)) {
+				ERR(state->handle, "Out of memory!");
+				return -1;
+			}
+			
+			/* sub_attr->roles may contain other role attributes,
+			 * re-scan the parent role attribute's roles ebitmap */
+			goto restart;
+		}
+	}
+
+	return 0;
+}
+
 /* Link a set of modules into a base module. This process is somewhat
  * similar to an actual compiler: it requires a set of order dependent
  * steps.  The base and every module must have been indexed prior to
@@ -2455,6 +2511,12 @@ int link_modules(sepol_handle_t * handle,
 		goto cleanup;
 	}
 
+	/* now that all role attribute's roles ebitmap have been settled,
+	 * expand sub role attribute's roles ebitmap into that of parent */
+	if (hashtab_map
+	    (state.base->p_roles.table, expand_role_attributes, &state))
+		goto cleanup;
+
 	retval = 0;
       cleanup:
 	for (i = 0; modules != NULL && i < len; i++) {
-- 
1.7.0.4


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

* Re: [v1 PATCH 1/6] Add role attribute support when compiling modules.
  2011-05-29  4:36 ` [v1 PATCH 1/6] Add role attribute support when compiling modules Harry Ciao
@ 2011-05-29 22:57   ` Joshua Brindle
  2011-05-30  6:59     ` HarryCiao
  0 siblings, 1 reply; 10+ messages in thread
From: Joshua Brindle @ 2011-05-29 22:57 UTC (permalink / raw)
  To: Harry Ciao; +Cc: cpebenito, sds, jmorris, eparis, selinux

Harry Ciao wrote:
> 1. Add a uint32_t "flavor" field and an ebitmap "roles" to the
> role_datum_t structure;
>
> 2. Modify the attribute declaration rule to add support to declare
> role attribute as well as type attribute;

Lets just use a different token to declare role attributes and use 
separate parser functions. I strongly dislike the char *kind in 
define_attrib(). Overloading tokens has caused much pain in the past.

>
> 3. Modify declare_role() to setup role_datum_t.flavor according
> to the isattr argument;
>
> 4. Add a new roleattribute rule and its handler, which will record
> the regular role's (policy value - 1) into the role attribute's
> role_datum_t.roles ebitmap;
>
> 5. Modify the syntax for the role_types rule only to define the
> role-type associations;
>
> 6. Add a new role_attr rule to support the declaration of a single
> role, and the role attribute that the role belongs to;
>
> 7. Check if the new_role used in role transition is a regular role;
>
> 8. Make the role-types rule no longer used to declare a regular role
> but solely aimed for declaring role-types associations;
>
> FIXME:
> How to pass a second argument to require_attribute(), to indicate
> if the attribute is of role or type ?

My suggestion on #2 should resolve this.

I'll look at the other patches soon.

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

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

* RE: [v1 PATCH 1/6] Add role attribute support when compiling modules.
  2011-05-29 22:57   ` Joshua Brindle
@ 2011-05-30  6:59     ` HarryCiao
  0 siblings, 0 replies; 10+ messages in thread
From: HarryCiao @ 2011-05-30  6:59 UTC (permalink / raw)
  To: method, qingtao.cao
  Cc: Christopher J. PeBenito, Stephen Smalley, jmorris, eparis,
	selinux-mailing-list

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


Hi Joshua,

> Date: Sun, 29 May 2011 18:57:38 -0400
> From: method@manicmethod.com
> To: qingtao.cao@windriver.com
> CC: cpebenito@tresys.com; sds@tycho.nsa.gov; jmorris@namei.org; eparis@parisplace.org; selinux@tycho.nsa.gov
> Subject: Re: [v1 PATCH 1/6] Add role attribute support when compiling modules.
> 
> Harry Ciao wrote:
> > 1. Add a uint32_t "flavor" field and an ebitmap "roles" to the
> > role_datum_t structure;
> >
> > 2. Modify the attribute declaration rule to add support to declare
> > role attribute as well as type attribute;
> 
> Lets just use a different token to declare role attributes and use 
> separate parser functions. I strongly dislike the char *kind in 
> define_attrib(). Overloading tokens has caused much pain in the past.
> 
> >
> > 3. Modify declare_role() to setup role_datum_t.flavor according
> > to the isattr argument;
> >
> > 4. Add a new roleattribute rule and its handler, which will record
> > the regular role's (policy value - 1) into the role attribute's
> > role_datum_t.roles ebitmap;
> >
> > 5. Modify the syntax for the role_types rule only to define the
> > role-type associations;
> >
> > 6. Add a new role_attr rule to support the declaration of a single
> > role, and the role attribute that the role belongs to;
> >
> > 7. Check if the new_role used in role transition is a regular role;
> >
> > 8. Make the role-types rule no longer used to declare a regular role
> > but solely aimed for declaring role-types associations;
> >
> > FIXME:
> > How to pass a second argument to require_attribute(), to indicate
> > if the attribute is of role or type ?
> 
> My suggestion on #2 should resolve this.
> 
> I'll look at the other patches soon.

Yep, turns out it is such a neat idea to use a separate token to declare a role attribute, which would make it very obvious and easy to require a role attribute!

I have been testing on the new token, I would send out v2 patches to endorse any of your further comments.

Thanks a lot!

Best regards,
Harry

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

[-- Attachment #2: Type: text/html, Size: 2842 bytes --]

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

end of thread, other threads:[~2011-05-30  6:59 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-29  4:36 v1 Add role attribute support to libsepol Harry Ciao
2011-05-29  4:36 ` [v1 PATCH 1/6] Add role attribute support when compiling modules Harry Ciao
2011-05-29 22:57   ` Joshua Brindle
2011-05-30  6:59     ` HarryCiao
2011-05-29  4:36 ` [v1 PATCH 2/6] Add role attribute support when generating pp files Harry Ciao
2011-05-29  4:36 ` [v1 PATCH 3/6] Add role attribute support when linking modules Harry Ciao
2011-05-29  4:36 ` [v1 PATCH 4/6] Add role attribute support when expanding role_datum_t Harry Ciao
2011-05-29  4:36 ` [v1 PATCH 5/6] Add role attribute support when expanding role_set_t Harry Ciao
2011-05-29  4:51 ` v1 Add role attribute support to libsepol HarryCiao
2011-05-29 10:41   ` HarryCiao

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.