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



Comments:
---------
Add role attribute to SELinux, which aims at replacing the deprecated
role dominance rule.

Previous discussions could be found here:
http://www.spinics.net/lists/selinux/msg00974.html

A role attribute could be declared by the rule of
"attribute <role_attribute_name> role;" and further used in the
user-roles, role-types, role-allows and role_transition rules. In order
to avoid ambiguity, the role-types would no longer to declare a role,
another new rule of role-attr is added to declare a regular role and
optionally a list of role attribute that the regular role belongs to
(like the type rule). Also the role-attribute association could be
declared by a new rule of roleattribute.

BTW, since the flavor and roles ebitmap of a role_datum_t structure
are not needed to be written to policy.X, the SELinux kernel driver
would not need any change. The maximum version number in both libsepol
and kernel remain the same.

FIXME_1:
I may need some help to specify the "kind" of a required attribute
(of a type attribute or role attribute), please see the notes left in
the patches. BTW, since multiple declarations of role/user are allowed,
so far I just explicitly declare the required role attribute :-P


Testings I've done:
-------------------
1. Use role attribute in several different modules to test if a role
   attribute used in user-roles, role-types, role-allows and role-transition
   rules could be properly compiled/linked/expanded.
   
   Also in order to support that role-types rule no longer is used to
   declare a regular role, we have to use the role-attr rule to declare
   the related role explicitly (so far only nx_server_r and unconfined_r).
   
   Please refer to the attached refpolicy patch for above tests, then make
   policy.
   

2. Make a hexdump of policy.26 by xxd tool, then check out the policy value
   for those identifiers related with this test:
   
   0035b40:                       07 0000 004a 0300  r_tmpfs_t....J..
   0035b50: 0001 0000 0000 0000 0076 6c6f 636b 5f74  .........vlock_t
   
   vlock_t: len = 7, policy value = 0x34a, prop = 01, bounds = 0
   
   00353b0:                          0800 0000 fa02  ..shadow_t......
   00353c0: 0000 0100 0000 00000000  7379 7361 646d  ..........sysadm
   00353d0: 5f74 1200 0000 cb01 0000 0000 0000 0000  _t
   
   sysadm_t: len = 8, policy value = 0x2fa, prop = 01, bounds = 0
   
   003d3f0: 635f 7409 0000 0034 0600 0001 0000 0000  c_t....4........
   003d400: 0000 006e 6577 726f 6c65 5f74 0900 0000  ...newrole_t....
   
   newrole_t: len = 9, policy value = 0x634, prop = 0x01, bounds = 0
   
   0045dc0:                                    0800  ......cgroup_t..
   0045dd0: 0000 7309 0000 0100 0000 0000 0000 6368  ..s...........ch
   0045de0: 6b70 7764 5f74 0800 0000 7409 0000 0100  kpwd_t
   
   chkpwd_t: len = 0x08, policy value = 0x973, prop = 0x01, bounds = 0
   
   002c6a0:                                      07  ................
   002c6b0: 0000 0005 0000 0000 0000 0073 7461 6666  ...........staff
   002c6c0: 5f72 4000 0000 4000 0000 0100 0000 0000  _r@...@.........
   
   staff_r: len = 0x07, policy value = 0x05, bounds = 0
   
   002cc60:                               0800 0000  .......@........
   002cc70: 0a00 0000 0000 0000 7379 7361 646d 5f72  ........sysadm_r
   
   sysadm_r: len = 0x08, policy value = 0x0a, bounds = 0
   
   002cec0:                               0800 0000  @...............
   002ced0: 0b00 0000 0000 0000 7379 7374 656d 5f72  ........system_r
   
   system_r: len = 0x08, policy value = 0x0b, bounds = 0
   
   
3. Check out the hexdump for the sysadm_r_2 and sysadm_r_3 role, verify
   if their types.types ebitmap records all types specified in the
   "role role_attribute_1 types xxx;" rule:
   
   002d470:                  0a 0000 0010 0000 0000  ................
   002d480: 0000 0073 7973 6164 6d5f 725f 3240 0000  ...sysadm_r_2@..
   002d490: 0040 0000 0001 0000 0000 0000 0000 8000  .@..............
   002d4a0: 0000 0000 0040 0000 0080 0900 0004 0000  .....@..........
   002d4b0: 00c0 0200 0000 0000 0000 0000 0240 0300  .............@..
   002d4c0: 0000 0200 0000 0000 0000 0600 0000 0000  ................
   002d4d0: 0000 0008 0040 0900 0000 0000 0000 0004  .....@..........
   002d4e0: 000a 0000 0011 0000 0000 0000 0073 7973  .............sys
   002d4f0: 6164 6d5f 725f 3340 0000 0040 0000 0001  adm_r_3@...@....
   002d500: 0000 0000 0000 0000 0001 0000 0000 0040  ...............@
   002d510: 0000 0080 0900 0004 0000 00c0 0200 0000  ................
   002d520: 0000 0000 0000 0240 0300 0000 0200 0000  .......@........
   002d530: 0000 0000 0600 0000 0000 0000 0008 0040  ...............@
   002d540: 0900 0000 0000 0000 0004 0065 0d00 00fa  ...........e....
   
   sysadm_r_2:
   	len = 0x0a, policy value = 0x10, bounds = 0
   	dominates:
   		ms = 0x40, highbit = 0x40, node = 0x01, 
		startbit = 0, map: 00 8000 0000 0000 00 (policy value = 0x10)
   	types.types:
   		ms = 0x40, highbit = 0x980, node = 0x04, 
		startbit = 0x2c0, map: 00 0000 0000 0000 02 (policy value = 0x2fa, sysadm_t)
		startbit = 0x340, map: 00 0200 0000 0000 00 (policy value = 0x34a, vlock_t)
   		startbit = 0x600, map: 00 0000 0000 0008 00 (policy value = 0x634, newrole_t)
   		startbit = 0x940, map: 00 0000 0000 0004 00 (policy value = 0x973, chkpwd_t)
   
   sysadm_r_3:
   	len = 0x0a, policy value = 0x11, bounds = 0
   	(The dominates and types.types ebitmaps are the same as that
	 of sysadm_r_2)	
   
   
4. Check out the hexdump of the root user, verify if its roles.roles ebitmap
   records the policy values of sysadm_r_2 and sysadm_r_3 that specified in
   the "user root roles role_attribute_1 ...;" rule:
   
   004fc20:                            04 0000 0003  ................
   004fc30: 0000 0000 0000 0072 6f6f 7440 0000 0040  .......root@...@
   004fc40: 0000 0001 0000 0000 0000 0012 8701 0000  ................
   004fc50: 0000 0002 0000 0001 0000 0010 0000 0040  ...............@
   004fc60: 0000 0000 0000 0000 0000 0040 0000 0000  ...........@....
   004fc70: 0400 0010 0000 0000 0000 00ff ffff ffff  ................
   004fc80: ffff ff40 0000 00ff ffff ffff ffff ff80  ...@............
   
   root:
   	len = 0x04, policy value = 0x03, bounds = 0x0
   	roles.roles:
   		ms = 0x40, highbit = 0x40, node = 0x01,
   		startbit = 0, map: 12 8701 0000 0000 00
   
   roles.roles ebitmap for the root user recorded following policy values:
   	2, 5, 9, 10, 11, 16, 17
   where 5 == staff_r, 10 == sysadmd_r, 11 == system_r, 16 == sysadm_r_2,
	 17 == sysadm_r_3
   
   
5. Boot up the system with the latest Eric SELinux tree:
   
   [root/sysadm_r/s0@~]# sestatus 
   SELinux status:                 enabled
   SELinuxfs mount:                /selinux
   Current mode:                   enforcing
   Mode from config file:          enforcing
   Policy version:                 26
   Policy from config file:        refpolicy-mls
   [root/sysadm_r/s0@~]# 
   [root/sysadm_r/s0@~]# echo "sysadm_r_2:sysadm_t" >> /etc/selinux/refpolicy-mls/contexts/default_type 
   [root/sysadm_r/s0@~]# echo "sysadm_r_3:sysadm_t" >> /etc/selinux/refpolicy-mls/contexts/default_type 
   [root/sysadm_r/s0@~]#
   

6. Use newrole command to switch between sysadm_r and sysadm_r_2/3, to
   prove that the role_attribute_1 used in relevant
   role-allow/user-roles/role-types rules have been properly linked/expanded:
   
   [root/sysadm_r/s0@~]# newrole -r sysadm_r_2 -p
   Password: 
   [root/sysadm_r_2/s0@~]#
   [root/sysadm_r_2/s0@~]# id -Z
   root:sysadm_r_2:sysadm_t:s0-s15:c0.c1023
   [root/sysadm_r_2/s0@~]# 
   [root/sysadm_r_2/s0@~]# newrole -r sysadm_r -p
   Password: 
   [root/sysadm_r/s0@~]# 
   [root/sysadm_r/s0@~]# newrole -r sysadm_r_3 -p
   Password: 
   [root/sysadm_r_3/s0@~]# 
   [root/sysadm_r_3/s0@~]# newrole -r sysadm_r -p
   Password: 
   [root/sysadm_r/s0@~]# id -Z
   root:sysadm_r:sysadm_t:s0-s15:c0.c1023
   [root/sysadm_r/s0@~]# 
   

7. Use the compute_create command to prove that the role_attribute_1 used
   in relevant role_transition rule has been properly linked/expanded:
   
   [root/sysadm_r_2/s0@~]# ls -Z /usr/sbin/vlock-main 
   -rws--x--x  root root system_u:object_r:vlock_exec_t:s0 /usr/sbin/vlock-main
   [root/sysadm_r_2/s0@~]# 
   [root/sysadm_r_2/s0@~]# compute_create `id -Z` system_u:object_r:vlock_exec_t:s0 process
   root:system_r:vlock_t:s0-s15:c0.c1023
   [root/sysadm_r_2/s0@~]# 
   
   [root/sysadm_r_3/s0@~]# compute_create `id -Z` system_u:object_r:vlock_exec_t:s0 process
   root:system_r:vlock_t:s0-s15:c0.c1023
   [root/sysadm_r_3/s0@~]# 
   

8. FIXME_2:
   The result of compute_create in the above steps has showed that the
   domain transition from sysadm_t to vlock_t, and the role transition from
   sysadm_r_2/3 to system_r could have taken place correctly. BTW, since
   security_compute_sid() has called policydb_context_isvalid(), so the
   "root:system_r:vlock_t:s0-s15:c0.c1023" context is valid.
   
   However, the root:sysadm_r_2:sysadm_t would fail to run the vlock
   program with the below AVC denied message, what else refpolicy rule
   should I have added ?
   
   [root/sysadm_r_2/s0@~]# date
   Thu May 26 06:27:29 GMT 2011
   [root/sysadm_r_2/s0@~]# vlock
   /usr/bin/vlock: line 224: /usr/sbin/vlock-main: Permission denied
   [root/sysadm_r_2/s0@~]# exit
   
   [root/sysadm_r/s0@~]# audhigh "ausearch -ts 06:27:29 -sv no"
   Password: 
   ----
   time->Thu May 26 06:27:32 2011
   type=SYSCALL msg=audit(1306391252.699:38): arch=40000003 syscall=11 success=no exit=-13 a0=80db080 a1=80da830 a2=80d07b0 a3=80da830 items=0 ppid=723 pid=849 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=ttyS0 ses=4294967295 comm="vlock" exe="/bin/bash" subj=root:sysadm_r_2:sysadm_t:s0-s15:c0.c1023 key=(null)
   type=AVC msg=audit(1306391252.699:38): avc:  denied  { transition } for  pid=849 comm="vlock" path="/usr/sbin/vlock-main" dev=sda ino=50097 scontext=root:sysadm_r_2:sysadm_t:s0-s15:c0.c1023 tcontext=root:system_r:vlock_t:s0-s15:c0.c1023 tclass=process
   [root/sysadm_r/s0@~]# 

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

* [v0 PATCH 1/5] Add role attribute support when compiling modules.
  2011-05-27  1:24 v0 Add role attribute support to libsepol Harry Ciao
@ 2011-05-27  1:24 ` Harry Ciao
  2011-05-27  1:24 ` [v0 PATCH 2/5] Add role attribute support when generating pp files Harry Ciao
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Harry Ciao @ 2011-05-27  1:24 UTC (permalink / raw)
  To: 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] 11+ messages in thread

* [v0 PATCH 2/5] Add role attribute support when generating pp files.
  2011-05-27  1:24 v0 Add role attribute support to libsepol Harry Ciao
  2011-05-27  1:24 ` [v0 PATCH 1/5] Add role attribute support when compiling modules Harry Ciao
@ 2011-05-27  1:24 ` Harry Ciao
  2011-05-27  1:24 ` [v0 PATCH 3/5] Add role attribute support when linking modules Harry Ciao
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Harry Ciao @ 2011-05-27  1:24 UTC (permalink / raw)
  To: 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] 11+ messages in thread

* [v0 PATCH 3/5] Add role attribute support when linking modules.
  2011-05-27  1:24 v0 Add role attribute support to libsepol Harry Ciao
  2011-05-27  1:24 ` [v0 PATCH 1/5] Add role attribute support when compiling modules Harry Ciao
  2011-05-27  1:24 ` [v0 PATCH 2/5] Add role attribute support when generating pp files Harry Ciao
@ 2011-05-27  1:24 ` Harry Ciao
  2011-05-27  1:24 ` [v0 PATCH 4/5] Add role attribute support when expanding role_datum_t Harry Ciao
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Harry Ciao @ 2011-05-27  1:24 UTC (permalink / raw)
  To: 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] 11+ messages in thread

* [v0 PATCH 4/5] Add role attribute support when expanding role_datum_t.
  2011-05-27  1:24 v0 Add role attribute support to libsepol Harry Ciao
                   ` (2 preceding siblings ...)
  2011-05-27  1:24 ` [v0 PATCH 3/5] Add role attribute support when linking modules Harry Ciao
@ 2011-05-27  1:24 ` Harry Ciao
  2011-05-27  1:24 ` [v0 PATCH 5/5] Add role attribute support when expanding role_set_t Harry Ciao
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Harry Ciao @ 2011-05-27  1:24 UTC (permalink / raw)
  To: 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] 11+ messages in thread

* [v0 PATCH 5/5] Add role attribute support when expanding role_set_t.
  2011-05-27  1:24 v0 Add role attribute support to libsepol Harry Ciao
                   ` (3 preceding siblings ...)
  2011-05-27  1:24 ` [v0 PATCH 4/5] Add role attribute support when expanding role_datum_t Harry Ciao
@ 2011-05-27  1:24 ` Harry Ciao
  2011-05-27  2:00 ` v0 Add role attribute support to libsepol HarryCiao
  2011-05-27 13:52 ` Joshua Brindle
  6 siblings, 0 replies; 11+ messages in thread
From: Harry Ciao @ 2011-05-27  1:24 UTC (permalink / raw)
  To: 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] 11+ messages in thread

* RE: v0 Add role attribute support to libsepol
  2011-05-27  1:24 v0 Add role attribute support to libsepol Harry Ciao
                   ` (4 preceding siblings ...)
  2011-05-27  1:24 ` [v0 PATCH 5/5] Add role attribute support when expanding role_set_t Harry Ciao
@ 2011-05-27  2:00 ` HarryCiao
  2011-05-27 13:52 ` Joshua Brindle
  6 siblings, 0 replies; 11+ messages in thread
From: HarryCiao @ 2011-05-27  2:00 UTC (permalink / raw)
  To: Stephen Smalley, method, jmorris, eparis; +Cc: selinux-mailing-list


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


Hi,

The attached is the refpolicy patch used for role attribute testing.

Thanks,
Harry

> From: qingtao.cao@windriver.com
> To: sds@tycho.nsa.gov; method@manicmethod.com; jmorris@namei.org; eparis@parisplace.org
> CC: selinux@tycho.nsa.gov
> Subject: v0 Add role attribute support to libsepol
> Date: Fri, 27 May 2011 09:24:19 +0800
> 
> 
> 
> Comments:
> ---------
> Add role attribute to SELinux, which aims at replacing the deprecated
> role dominance rule.
> 
> Previous discussions could be found here:
> http://www.spinics.net/lists/selinux/msg00974.html
> 
> A role attribute could be declared by the rule of
> "attribute <role_attribute_name> role;" and further used in the
> user-roles, role-types, role-allows and role_transition rules. In order
> to avoid ambiguity, the role-types would no longer to declare a role,
> another new rule of role-attr is added to declare a regular role and
> optionally a list of role attribute that the regular role belongs to
> (like the type rule). Also the role-attribute association could be
> declared by a new rule of roleattribute.
> 
> BTW, since the flavor and roles ebitmap of a role_datum_t structure
> are not needed to be written to policy.X, the SELinux kernel driver
> would not need any change. The maximum version number in both libsepol
> and kernel remain the same.
> 
> FIXME_1:
> I may need some help to specify the "kind" of a required attribute
> (of a type attribute or role attribute), please see the notes left in
> the patches. BTW, since multiple declarations of role/user are allowed,
> so far I just explicitly declare the required role attribute :-P
> 
> 
> Testings I've done:
> -------------------
> 1. Use role attribute in several different modules to test if a role
>    attribute used in user-roles, role-types, role-allows and role-transition
>    rules could be properly compiled/linked/expanded.
>    
>    Also in order to support that role-types rule no longer is used to
>    declare a regular role, we have to use the role-attr rule to declare
>    the related role explicitly (so far only nx_server_r and unconfined_r).
>    
>    Please refer to the attached refpolicy patch for above tests, then make
>    policy.
>    
> 
> 2. Make a hexdump of policy.26 by xxd tool, then check out the policy value
>    for those identifiers related with this test:
>    
>    0035b40:                       07 0000 004a 0300  r_tmpfs_t....J..
>    0035b50: 0001 0000 0000 0000 0076 6c6f 636b 5f74  .........vlock_t
>    
>    vlock_t: len = 7, policy value = 0x34a, prop = 01, bounds = 0
>    
>    00353b0:                          0800 0000 fa02  ..shadow_t......
>    00353c0: 0000 0100 0000 00000000  7379 7361 646d  ..........sysadm
>    00353d0: 5f74 1200 0000 cb01 0000 0000 0000 0000  _t
>    
>    sysadm_t: len = 8, policy value = 0x2fa, prop = 01, bounds = 0
>    
>    003d3f0: 635f 7409 0000 0034 0600 0001 0000 0000  c_t....4........
>    003d400: 0000 006e 6577 726f 6c65 5f74 0900 0000  ...newrole_t....
>    
>    newrole_t: len = 9, policy value = 0x634, prop = 0x01, bounds = 0
>    
>    0045dc0:                                    0800  ......cgroup_t..
>    0045dd0: 0000 7309 0000 0100 0000 0000 0000 6368  ..s...........ch
>    0045de0: 6b70 7764 5f74 0800 0000 7409 0000 0100  kpwd_t
>    
>    chkpwd_t: len = 0x08, policy value = 0x973, prop = 0x01, bounds = 0
>    
>    002c6a0:                                      07  ................
>    002c6b0: 0000 0005 0000 0000 0000 0073 7461 6666  ...........staff
>    002c6c0: 5f72 4000 0000 4000 0000 0100 0000 0000  _r@...@.........
>    
>    staff_r: len = 0x07, policy value = 0x05, bounds = 0
>    
>    002cc60:                               0800 0000  .......@........
>    002cc70: 0a00 0000 0000 0000 7379 7361 646d 5f72  ........sysadm_r
>    
>    sysadm_r: len = 0x08, policy value = 0x0a, bounds = 0
>    
>    002cec0:                               0800 0000  @...............
>    002ced0: 0b00 0000 0000 0000 7379 7374 656d 5f72  ........system_r
>    
>    system_r: len = 0x08, policy value = 0x0b, bounds = 0
>    
>    
> 3. Check out the hexdump for the sysadm_r_2 and sysadm_r_3 role, verify
>    if their types.types ebitmap records all types specified in the
>    "role role_attribute_1 types xxx;" rule:
>    
>    002d470:                  0a 0000 0010 0000 0000  ................
>    002d480: 0000 0073 7973 6164 6d5f 725f 3240 0000  ...sysadm_r_2@..
>    002d490: 0040 0000 0001 0000 0000 0000 0000 8000  .@..............
>    002d4a0: 0000 0000 0040 0000 0080 0900 0004 0000  .....@..........
>    002d4b0: 00c0 0200 0000 0000 0000 0000 0240 0300  .............@..
>    002d4c0: 0000 0200 0000 0000 0000 0600 0000 0000  ................
>    002d4d0: 0000 0008 0040 0900 0000 0000 0000 0004  .....@..........
>    002d4e0: 000a 0000 0011 0000 0000 0000 0073 7973  .............sys
>    002d4f0: 6164 6d5f 725f 3340 0000 0040 0000 0001  adm_r_3@...@....
>    002d500: 0000 0000 0000 0000 0001 0000 0000 0040  ...............@
>    002d510: 0000 0080 0900 0004 0000 00c0 0200 0000  ................
>    002d520: 0000 0000 0000 0240 0300 0000 0200 0000  .......@........
>    002d530: 0000 0000 0600 0000 0000 0000 0008 0040  ...............@
>    002d540: 0900 0000 0000 0000 0004 0065 0d00 00fa  ...........e....
>    
>    sysadm_r_2:
>    	len = 0x0a, policy value = 0x10, bounds = 0
>    	dominates:
>    		ms = 0x40, highbit = 0x40, node = 0x01, 
> 		startbit = 0, map: 00 8000 0000 0000 00 (policy value = 0x10)
>    	types.types:
>    		ms = 0x40, highbit = 0x980, node = 0x04, 
> 		startbit = 0x2c0, map: 00 0000 0000 0000 02 (policy value = 0x2fa, sysadm_t)
> 		startbit = 0x340, map: 00 0200 0000 0000 00 (policy value = 0x34a, vlock_t)
>    		startbit = 0x600, map: 00 0000 0000 0008 00 (policy value = 0x634, newrole_t)
>    		startbit = 0x940, map: 00 0000 0000 0004 00 (policy value = 0x973, chkpwd_t)
>    
>    sysadm_r_3:
>    	len = 0x0a, policy value = 0x11, bounds = 0
>    	(The dominates and types.types ebitmaps are the same as that
> 	 of sysadm_r_2)	
>    
>    
> 4. Check out the hexdump of the root user, verify if its roles.roles ebitmap
>    records the policy values of sysadm_r_2 and sysadm_r_3 that specified in
>    the "user root roles role_attribute_1 ...;" rule:
>    
>    004fc20:                            04 0000 0003  ................
>    004fc30: 0000 0000 0000 0072 6f6f 7440 0000 0040  .......root@...@
>    004fc40: 0000 0001 0000 0000 0000 0012 8701 0000  ................
>    004fc50: 0000 0002 0000 0001 0000 0010 0000 0040  ...............@
>    004fc60: 0000 0000 0000 0000 0000 0040 0000 0000  ...........@....
>    004fc70: 0400 0010 0000 0000 0000 00ff ffff ffff  ................
>    004fc80: ffff ff40 0000 00ff ffff ffff ffff ff80  ...@............
>    
>    root:
>    	len = 0x04, policy value = 0x03, bounds = 0x0
>    	roles.roles:
>    		ms = 0x40, highbit = 0x40, node = 0x01,
>    		startbit = 0, map: 12 8701 0000 0000 00
>    
>    roles.roles ebitmap for the root user recorded following policy values:
>    	2, 5, 9, 10, 11, 16, 17
>    where 5 == staff_r, 10 == sysadmd_r, 11 == system_r, 16 == sysadm_r_2,
> 	 17 == sysadm_r_3
>    
>    
> 5. Boot up the system with the latest Eric SELinux tree:
>    
>    [root/sysadm_r/s0@~]# sestatus 
>    SELinux status:                 enabled
>    SELinuxfs mount:                /selinux
>    Current mode:                   enforcing
>    Mode from config file:          enforcing
>    Policy version:                 26
>    Policy from config file:        refpolicy-mls
>    [root/sysadm_r/s0@~]# 
>    [root/sysadm_r/s0@~]# echo "sysadm_r_2:sysadm_t" >> /etc/selinux/refpolicy-mls/contexts/default_type 
>    [root/sysadm_r/s0@~]# echo "sysadm_r_3:sysadm_t" >> /etc/selinux/refpolicy-mls/contexts/default_type 
>    [root/sysadm_r/s0@~]#
>    
> 
> 6. Use newrole command to switch between sysadm_r and sysadm_r_2/3, to
>    prove that the role_attribute_1 used in relevant
>    role-allow/user-roles/role-types rules have been properly linked/expanded:
>    
>    [root/sysadm_r/s0@~]# newrole -r sysadm_r_2 -p
>    Password: 
>    [root/sysadm_r_2/s0@~]#
>    [root/sysadm_r_2/s0@~]# id -Z
>    root:sysadm_r_2:sysadm_t:s0-s15:c0.c1023
>    [root/sysadm_r_2/s0@~]# 
>    [root/sysadm_r_2/s0@~]# newrole -r sysadm_r -p
>    Password: 
>    [root/sysadm_r/s0@~]# 
>    [root/sysadm_r/s0@~]# newrole -r sysadm_r_3 -p
>    Password: 
>    [root/sysadm_r_3/s0@~]# 
>    [root/sysadm_r_3/s0@~]# newrole -r sysadm_r -p
>    Password: 
>    [root/sysadm_r/s0@~]# id -Z
>    root:sysadm_r:sysadm_t:s0-s15:c0.c1023
>    [root/sysadm_r/s0@~]# 
>    
> 
> 7. Use the compute_create command to prove that the role_attribute_1 used
>    in relevant role_transition rule has been properly linked/expanded:
>    
>    [root/sysadm_r_2/s0@~]# ls -Z /usr/sbin/vlock-main 
>    -rws--x--x  root root system_u:object_r:vlock_exec_t:s0 /usr/sbin/vlock-main
>    [root/sysadm_r_2/s0@~]# 
>    [root/sysadm_r_2/s0@~]# compute_create `id -Z` system_u:object_r:vlock_exec_t:s0 process
>    root:system_r:vlock_t:s0-s15:c0.c1023
>    [root/sysadm_r_2/s0@~]# 
>    
>    [root/sysadm_r_3/s0@~]# compute_create `id -Z` system_u:object_r:vlock_exec_t:s0 process
>    root:system_r:vlock_t:s0-s15:c0.c1023
>    [root/sysadm_r_3/s0@~]# 
>    
> 
> 8. FIXME_2:
>    The result of compute_create in the above steps has showed that the
>    domain transition from sysadm_t to vlock_t, and the role transition from
>    sysadm_r_2/3 to system_r could have taken place correctly. BTW, since
>    security_compute_sid() has called policydb_context_isvalid(), so the
>    "root:system_r:vlock_t:s0-s15:c0.c1023" context is valid.
>    
>    However, the root:sysadm_r_2:sysadm_t would fail to run the vlock
>    program with the below AVC denied message, what else refpolicy rule
>    should I have added ?
>    
>    [root/sysadm_r_2/s0@~]# date
>    Thu May 26 06:27:29 GMT 2011
>    [root/sysadm_r_2/s0@~]# vlock
>    /usr/bin/vlock: line 224: /usr/sbin/vlock-main: Permission denied
>    [root/sysadm_r_2/s0@~]# exit
>    
>    [root/sysadm_r/s0@~]# audhigh "ausearch -ts 06:27:29 -sv no"
>    Password: 
>    ----
>    time->Thu May 26 06:27:32 2011
>    type=SYSCALL msg=audit(1306391252.699:38): arch=40000003 syscall=11 success=no exit=-13 a0=80db080 a1=80da830 a2=80d07b0 a3=80da830 items=0 ppid=723 pid=849 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=ttyS0 ses=4294967295 comm="vlock" exe="/bin/bash" subj=root:sysadm_r_2:sysadm_t:s0-s15:c0.c1023 key=(null)
>    type=AVC msg=audit(1306391252.699:38): avc:  denied  { transition } for  pid=849 comm="vlock" path="/usr/sbin/vlock-main" dev=sda ino=50097 scontext=root:sysadm_r_2:sysadm_t:s0-s15:c0.c1023 tcontext=root:system_r:vlock_t:s0-s15:c0.c1023 tclass=process
>    [root/sysadm_r/s0@~]# 
> 
> --
> 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: 12780 bytes --]

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Role-attribute-debug.patch --]
[-- Type: text/x-patch, Size: 5000 bytes --]

From 4e2bd0a7ce57010b09ab54fd4af50af57d26a791 Mon Sep 17 00:00:00 2001
From: Harry Ciao <qingtao.cao@windriver.com>
Date: Wed, 25 May 2011 17:34:47 +0800
Subject: [PATCH 1/1] Role attribute debug.

Use role attribute in several different modules to test if a role
attribute used in user-roles, role-types, role-allows and role-transition
rules could be properly compiled/linked/expanded.

Also in order to support that role-types rule no longer is used to
declare a regular role, we have to use the role-attr rule to declare
the related role explicitly (so far only nx_server_r and unconfined_r).

Signed-off-by: Harry Ciao <qingtao.cao@windriver.com>
---
 policy/modules/apps/vlock.te         |   14 ++++++++++++++
 policy/modules/roles/sysadm.te       |   25 +++++++++++++++++++++++++
 policy/modules/services/likewise.te  |    2 +-
 policy/modules/services/nx.te        |    1 +
 policy/modules/system/selinuxutil.te |   19 +++++++++++++++++++
 policy/modules/system/unconfined.te  |    1 +
 6 files changed, 61 insertions(+), 1 deletions(-)

diff --git a/policy/modules/apps/vlock.te b/policy/modules/apps/vlock.te
index 03fc701..4d3295f 100644
--- a/policy/modules/apps/vlock.te
+++ b/policy/modules/apps/vlock.te
@@ -51,3 +51,17 @@ miscfiles_read_localization(vlock_t)
 
 userdom_dontaudit_search_user_home_dirs(vlock_t)
 userdom_use_user_terminals(vlock_t)
+
+optional_policy(`
+	gen_require(`
+		role system_r;
+	')
+
+	# so far I do not know how to require a role attribute yet
+	attribute role_attribute_1 ROLE;
+
+	# assume the system_r role once transitioned to vlock_t domain
+	role_transition role_attribute_1 vlock_exec_t system_r;
+	role system_r types vlock_t;
+	user root roles system_r level s0 range s0 - s15:c0.c1023;
+')
diff --git a/policy/modules/roles/sysadm.te b/policy/modules/roles/sysadm.te
index 2f2bc77..67a8415 100644
--- a/policy/modules/roles/sysadm.te
+++ b/policy/modules/roles/sysadm.te
@@ -454,3 +454,28 @@ optional_policy(`
 	')
 #')
 
+
+# 1. define a role attribute by the modified attribute rule
+# Note, so far the duplicated declarations of role/user are allowed
+# (symtab_insert)
+attribute role_attribute_1 role;
+attribute role_attribute_1 ROLE;
+
+# 2. define a regular role by the new role_attr rule,
+# specifying the role attribute that a regular role belongs to
+role sysadm_r_2, role_attribute_1;
+
+# 3. define a regular role by the existing role_type rule
+role sysadm_r_3;
+
+# 4. add a regular role into a role attribute
+roleattribute sysadm_r_3 role_attribute_1;
+
+optional_policy(`
+	gen_require(`
+		user root;
+		type vlock_t;
+	')
+	
+	user root roles role_attribute_1 level s0 range s0 - s15:c0.c1023;
+')
diff --git a/policy/modules/services/likewise.te b/policy/modules/services/likewise.te
index 3acbf1d..84f4baf 100644
--- a/policy/modules/services/likewise.te
+++ b/policy/modules/services/likewise.te
@@ -137,7 +137,7 @@ selinux_validate_context(lsassd_t)
 seutil_read_config(lsassd_t)
 seutil_read_default_contexts(lsassd_t)
 seutil_read_file_contexts(lsassd_t)
-seutil_run_semanage(lsassd_t, lsassd_t)
+#seutil_run_semanage(lsassd_t, lsassd_t)
 
 sysnet_use_ldap(lsassd_t)
 sysnet_read_config(lsassd_t)
diff --git a/policy/modules/services/nx.te b/policy/modules/services/nx.te
index ebb9582..a3559f2 100644
--- a/policy/modules/services/nx.te
+++ b/policy/modules/services/nx.te
@@ -12,6 +12,7 @@ domain_entry_file(nx_server_t, nx_server_exec_t)
 domain_user_exemption_target(nx_server_t)
 # we need an extra role because nxserver is called from sshd
 # cjp: do we really need this?
+role nx_server_r;
 role nx_server_r types nx_server_t;
 allow system_r nx_server_r;
 
diff --git a/policy/modules/system/selinuxutil.te b/policy/modules/system/selinuxutil.te
index 284c7f8..65e0698 100644
--- a/policy/modules/system/selinuxutil.te
+++ b/policy/modules/system/selinuxutil.te
@@ -603,3 +603,22 @@ ifdef(`hide_broken_symptoms',`
 optional_policy(`
 	hotplug_use_fds(setfiles_t)
 ')
+
+optional_policy(`
+	gen_require(`
+		role sysadm_r;
+		type sysadm_t, chkpwd_t;
+	')
+
+	# so far I do not know how to require a role attribute yet
+	attribute role_attribute_1 ROLE;
+	
+	# allow the transition from sysadm_r to all regular roles that
+	# belong to the role_attribute_1 and vice versa by the newrole cmd
+	allow sysadm_r role_attribute_1;
+	allow role_attribute_1 sysadm_r;
+
+	role role_attribute_1 types newrole_t;
+	role role_attribute_1 types chkpwd_t;
+	role role_attribute_1 types sysadm_t;
+')
diff --git a/policy/modules/system/unconfined.te b/policy/modules/system/unconfined.te
index eae5001..9c5f931 100644
--- a/policy/modules/system/unconfined.te
+++ b/policy/modules/system/unconfined.te
@@ -19,6 +19,7 @@ init_system_domain(unconfined_t, unconfined_exec_t)
 type unconfined_execmem_t;
 type unconfined_execmem_exec_t;
 init_system_domain(unconfined_execmem_t, unconfined_execmem_exec_t)
+role unconfined_r;
 role unconfined_r types unconfined_execmem_t;
 
 ########################################
-- 
1.7.0.4


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

* Re: v0 Add role attribute support to libsepol
  2011-05-27  1:24 v0 Add role attribute support to libsepol Harry Ciao
                   ` (5 preceding siblings ...)
  2011-05-27  2:00 ` v0 Add role attribute support to libsepol HarryCiao
@ 2011-05-27 13:52 ` Joshua Brindle
  2011-05-27 14:23   ` Joshua Brindle
  6 siblings, 1 reply; 11+ messages in thread
From: Joshua Brindle @ 2011-05-27 13:52 UTC (permalink / raw)
  To: Harry Ciao; +Cc: sds, jmorris, eparis, selinux

Harry Ciao wrote:
>
> Comments:
> ---------
> Add role attribute to SELinux, which aims at replacing the deprecated
> role dominance rule.

Thanks. This is going to take a bit of time to absorb and most of my cycles are 
in use at the moment. I'll definitely get around to looking at it though.

>
> Previous discussions could be found here:
> http://www.spinics.net/lists/selinux/msg00974.html
>
> A role attribute could be declared by the rule of
> "attribute<role_attribute_name>  role;" and further used in the
> user-roles, role-types, role-allows and role_transition rules. In order
> to avoid ambiguity, the role-types would no longer to declare a role,
> another new rule of role-attr is added to declare a regular role and
> optionally a list of role attribute that the regular role belongs to
> (like the type rule). Also the role-attribute association could be
> declared by a new rule of roleattribute.
>
> BTW, since the flavor and roles ebitmap of a role_datum_t structure
> are not needed to be written to policy.X, the SELinux kernel driver
> would not need any change. The maximum version number in both libsepol
> and kernel remain the same.
>
> FIXME_1:
> I may need some help to specify the "kind" of a required attribute
> (of a type attribute or role attribute), please see the notes left in
> the patches. BTW, since multiple declarations of role/user are allowed,
> so far I just explicitly declare the required role attribute :-P
>
>
> Testings I've done:
> -------------------
> 1. Use role attribute in several different modules to test if a role
>     attribute used in user-roles, role-types, role-allows and role-transition
>     rules could be properly compiled/linked/expanded.
>
>     Also in order to support that role-types rule no longer is used to
>     declare a regular role, we have to use the role-attr rule to declare
>     the related role explicitly (so far only nx_server_r and unconfined_r).
>
>     Please refer to the attached refpolicy patch for above tests, then make
>     policy.
>
>
> 2. Make a hexdump of policy.26 by xxd tool, then check out the policy value
>     for those identifiers related with this test:
>
>     0035b40:                       07 0000 004a 0300  r_tmpfs_t....J..
>     0035b50: 0001 0000 0000 0000 0076 6c6f 636b 5f74  .........vlock_t
>
>     vlock_t: len = 7, policy value = 0x34a, prop = 01, bounds = 0
>
>     00353b0:                          0800 0000 fa02  ..shadow_t......
>     00353c0: 0000 0100 0000 00000000  7379 7361 646d  ..........sysadm
>     00353d0: 5f74 1200 0000 cb01 0000 0000 0000 0000  _t
>
>     sysadm_t: len = 8, policy value = 0x2fa, prop = 01, bounds = 0
>
>     003d3f0: 635f 7409 0000 0034 0600 0001 0000 0000  c_t....4........
>     003d400: 0000 006e 6577 726f 6c65 5f74 0900 0000  ...newrole_t....
>
>     newrole_t: len = 9, policy value = 0x634, prop = 0x01, bounds = 0
>
>     0045dc0:                                    0800  ......cgroup_t..
>     0045dd0: 0000 7309 0000 0100 0000 0000 0000 6368  ..s...........ch
>     0045de0: 6b70 7764 5f74 0800 0000 7409 0000 0100  kpwd_t
>
>     chkpwd_t: len = 0x08, policy value = 0x973, prop = 0x01, bounds = 0
>
>     002c6a0:                                      07  ................
>     002c6b0: 0000 0005 0000 0000 0000 0073 7461 6666  ...........staff
>     002c6c0: 5f72 4000 0000 4000 0000 0100 0000 0000  _r@...@.........
>
>     staff_r: len = 0x07, policy value = 0x05, bounds = 0
>
>     002cc60:                               0800 0000  .......@........
>     002cc70: 0a00 0000 0000 0000 7379 7361 646d 5f72  ........sysadm_r
>
>     sysadm_r: len = 0x08, policy value = 0x0a, bounds = 0
>
>     002cec0:                               0800 0000  @...............
>     002ced0: 0b00 0000 0000 0000 7379 7374 656d 5f72  ........system_r
>
>     system_r: len = 0x08, policy value = 0x0b, bounds = 0
>
>
> 3. Check out the hexdump for the sysadm_r_2 and sysadm_r_3 role, verify
>     if their types.types ebitmap records all types specified in the
>     "role role_attribute_1 types xxx;" rule:
>
>     002d470:                  0a 0000 0010 0000 0000  ................
>     002d480: 0000 0073 7973 6164 6d5f 725f 3240 0000  ...sysadm_r_2@..
>     002d490: 0040 0000 0001 0000 0000 0000 0000 8000  .@..............
>     002d4a0: 0000 0000 0040 0000 0080 0900 0004 0000  .....@..........
>     002d4b0: 00c0 0200 0000 0000 0000 0000 0240 0300  .............@..
>     002d4c0: 0000 0200 0000 0000 0000 0600 0000 0000  ................
>     002d4d0: 0000 0008 0040 0900 0000 0000 0000 0004  .....@..........
>     002d4e0: 000a 0000 0011 0000 0000 0000 0073 7973  .............sys
>     002d4f0: 6164 6d5f 725f 3340 0000 0040 0000 0001  adm_r_3@...@....
>     002d500: 0000 0000 0000 0000 0001 0000 0000 0040  ...............@
>     002d510: 0000 0080 0900 0004 0000 00c0 0200 0000  ................
>     002d520: 0000 0000 0000 0240 0300 0000 0200 0000  .......@........
>     002d530: 0000 0000 0600 0000 0000 0000 0008 0040  ...............@
>     002d540: 0900 0000 0000 0000 0004 0065 0d00 00fa  ...........e....
>
>     sysadm_r_2:
>     	len = 0x0a, policy value = 0x10, bounds = 0
>     	dominates:
>     		ms = 0x40, highbit = 0x40, node = 0x01,
> 		startbit = 0, map: 00 8000 0000 0000 00 (policy value = 0x10)
>     	types.types:
>     		ms = 0x40, highbit = 0x980, node = 0x04,
> 		startbit = 0x2c0, map: 00 0000 0000 0000 02 (policy value = 0x2fa, sysadm_t)
> 		startbit = 0x340, map: 00 0200 0000 0000 00 (policy value = 0x34a, vlock_t)
>     		startbit = 0x600, map: 00 0000 0000 0008 00 (policy value = 0x634, newrole_t)
>     		startbit = 0x940, map: 00 0000 0000 0004 00 (policy value = 0x973, chkpwd_t)
>
>     sysadm_r_3:
>     	len = 0x0a, policy value = 0x11, bounds = 0
>     	(The dominates and types.types ebitmaps are the same as that
> 	 of sysadm_r_2)	
>
>
> 4. Check out the hexdump of the root user, verify if its roles.roles ebitmap
>     records the policy values of sysadm_r_2 and sysadm_r_3 that specified in
>     the "user root roles role_attribute_1 ...;" rule:
>
>     004fc20:                            04 0000 0003  ................
>     004fc30: 0000 0000 0000 0072 6f6f 7440 0000 0040  .......root@...@
>     004fc40: 0000 0001 0000 0000 0000 0012 8701 0000  ................
>     004fc50: 0000 0002 0000 0001 0000 0010 0000 0040  ...............@
>     004fc60: 0000 0000 0000 0000 0000 0040 0000 0000  ...........@....
>     004fc70: 0400 0010 0000 0000 0000 00ff ffff ffff  ................
>     004fc80: ffff ff40 0000 00ff ffff ffff ffff ff80  ...@............
>
>     root:
>     	len = 0x04, policy value = 0x03, bounds = 0x0
>     	roles.roles:
>     		ms = 0x40, highbit = 0x40, node = 0x01,
>     		startbit = 0, map: 12 8701 0000 0000 00
>
>     roles.roles ebitmap for the root user recorded following policy values:
>     	2, 5, 9, 10, 11, 16, 17
>     where 5 == staff_r, 10 == sysadmd_r, 11 == system_r, 16 == sysadm_r_2,
> 	 17 == sysadm_r_3
>
>
> 5. Boot up the system with the latest Eric SELinux tree:
>
>     [root/sysadm_r/s0@~]# sestatus
>     SELinux status:                 enabled
>     SELinuxfs mount:                /selinux
>     Current mode:                   enforcing
>     Mode from config file:          enforcing
>     Policy version:                 26
>     Policy from config file:        refpolicy-mls
>     [root/sysadm_r/s0@~]#
>     [root/sysadm_r/s0@~]# echo "sysadm_r_2:sysadm_t">>  /etc/selinux/refpolicy-mls/contexts/default_type
>     [root/sysadm_r/s0@~]# echo "sysadm_r_3:sysadm_t">>  /etc/selinux/refpolicy-mls/contexts/default_type
>     [root/sysadm_r/s0@~]#
>
>
> 6. Use newrole command to switch between sysadm_r and sysadm_r_2/3, to
>     prove that the role_attribute_1 used in relevant
>     role-allow/user-roles/role-types rules have been properly linked/expanded:
>
>     [root/sysadm_r/s0@~]# newrole -r sysadm_r_2 -p
>     Password:
>     [root/sysadm_r_2/s0@~]#
>     [root/sysadm_r_2/s0@~]# id -Z
>     root:sysadm_r_2:sysadm_t:s0-s15:c0.c1023
>     [root/sysadm_r_2/s0@~]#
>     [root/sysadm_r_2/s0@~]# newrole -r sysadm_r -p
>     Password:
>     [root/sysadm_r/s0@~]#
>     [root/sysadm_r/s0@~]# newrole -r sysadm_r_3 -p
>     Password:
>     [root/sysadm_r_3/s0@~]#
>     [root/sysadm_r_3/s0@~]# newrole -r sysadm_r -p
>     Password:
>     [root/sysadm_r/s0@~]# id -Z
>     root:sysadm_r:sysadm_t:s0-s15:c0.c1023
>     [root/sysadm_r/s0@~]#
>
>
> 7. Use the compute_create command to prove that the role_attribute_1 used
>     in relevant role_transition rule has been properly linked/expanded:
>
>     [root/sysadm_r_2/s0@~]# ls -Z /usr/sbin/vlock-main
>     -rws--x--x  root root system_u:object_r:vlock_exec_t:s0 /usr/sbin/vlock-main
>     [root/sysadm_r_2/s0@~]#
>     [root/sysadm_r_2/s0@~]# compute_create `id -Z` system_u:object_r:vlock_exec_t:s0 process
>     root:system_r:vlock_t:s0-s15:c0.c1023
>     [root/sysadm_r_2/s0@~]#
>
>     [root/sysadm_r_3/s0@~]# compute_create `id -Z` system_u:object_r:vlock_exec_t:s0 process
>     root:system_r:vlock_t:s0-s15:c0.c1023
>     [root/sysadm_r_3/s0@~]#
>
>
> 8. FIXME_2:
>     The result of compute_create in the above steps has showed that the
>     domain transition from sysadm_t to vlock_t, and the role transition from
>     sysadm_r_2/3 to system_r could have taken place correctly. BTW, since
>     security_compute_sid() has called policydb_context_isvalid(), so the
>     "root:system_r:vlock_t:s0-s15:c0.c1023" context is valid.
>
>     However, the root:sysadm_r_2:sysadm_t would fail to run the vlock
>     program with the below AVC denied message, what else refpolicy rule
>     should I have added ?
>
>     [root/sysadm_r_2/s0@~]# date
>     Thu May 26 06:27:29 GMT 2011
>     [root/sysadm_r_2/s0@~]# vlock
>     /usr/bin/vlock: line 224: /usr/sbin/vlock-main: Permission denied
>     [root/sysadm_r_2/s0@~]# exit
>
>     [root/sysadm_r/s0@~]# audhigh "ausearch -ts 06:27:29 -sv no"
>     Password:
>     ----
>     time->Thu May 26 06:27:32 2011
>     type=SYSCALL msg=audit(1306391252.699:38): arch=40000003 syscall=11 success=no exit=-13 a0=80db080 a1=80da830 a2=80d07b0 a3=80da830 items=0 ppid=723 pid=849 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=ttyS0 ses=4294967295 comm="vlock" exe="/bin/bash" subj=root:sysadm_r_2:sysadm_t:s0-s15:c0.c1023 key=(null)
>     type=AVC msg=audit(1306391252.699:38): avc:  denied  { transition } for  pid=849 comm="vlock" path="/usr/sbin/vlock-main" dev=sda ino=50097 scontext=root:sysadm_r_2:sysadm_t:s0-s15:c0.c1023 tcontext=root:system_r:vlock_t:s0-s15:c0.c1023 tclass=process
>     [root/sysadm_r/s0@~]#
>

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

* Re: v0 Add role attribute support to libsepol
  2011-05-27 13:52 ` Joshua Brindle
@ 2011-05-27 14:23   ` Joshua Brindle
  2011-05-27 14:57     ` Christopher J. PeBenito
  0 siblings, 1 reply; 11+ messages in thread
From: Joshua Brindle @ 2011-05-27 14:23 UTC (permalink / raw)
  To: Harry Ciao
  Cc: sds, jmorris, eparis, selinux, Daniel J Walsh,
	'Christopher J. PeBenito'

Joshua Brindle wrote:
> Harry Ciao wrote:
>>
>> Comments:
>> ---------
>> Add role attribute to SELinux, which aims at replacing the deprecated
>> role dominance rule.
>
> Thanks. This is going to take a bit of time to absorb and most of my cycles are
> in use at the moment. I'll definitely get around to looking at it though.
>

I'd also like to solicit feedback from Dan and Chris as to how this will be used 
in policy, and as to whether this implementation is suitable.

Dan, Chris, opinions?

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

* Re: v0 Add role attribute support to libsepol
  2011-05-27 14:23   ` Joshua Brindle
@ 2011-05-27 14:57     ` Christopher J. PeBenito
  2011-05-29  4:46       ` HarryCiao
  0 siblings, 1 reply; 11+ messages in thread
From: Christopher J. PeBenito @ 2011-05-27 14:57 UTC (permalink / raw)
  To: Joshua Brindle; +Cc: Harry Ciao, sds, jmorris, eparis, selinux, Daniel J Walsh

On 05/27/11 10:23, Joshua Brindle wrote:
> Joshua Brindle wrote:
>> Harry Ciao wrote:
>>>
>>> Comments:
>>> ---------
>>> Add role attribute to SELinux, which aims at replacing the deprecated
>>> role dominance rule.
>>
>> Thanks. This is going to take a bit of time to absorb and most of my
>> cycles are
>> in use at the moment. I'll definitely get around to looking at it though.
>>
> 
> I'd also like to solicit feedback from Dan and Chris as to how this will
> be used in policy, and as to whether this implementation is suitable.
> 
> Dan, Chris, opinions?

Do we really want to overload the attribute statement for declaring role
attributes?

If I understand the description correctly, it seems reasonable, but will
still run into problems for refpolicy.  We want to immediately use this
feature for handling chains of run interfaces.  For example, say we have
an admin (admin_r:admin_t) and he can run the foo program (foo_t
domain).  The foo program then runs the bar program (bar_t) domain.  The
(abbreviated) policy right now would look like this:

foo.te:
bar_domtrans(foo_t)

foo.if:
interface foo_run(
	type_transition $1 foo_exec_t:process foo_t;
	role $2 types foo_t;
	bar_run($1,$2)
)

The reason we do this is so that the bar_t is added on to the admin_r
role, without adding a direct transition from admin_t to bar_t.  But the
above gets messy when the policy writer forgets to put the accompanying
bar_run() call in the foo_run() interface implementation.  With role
attributes it would be simplified to:

foo.te:
role foo_roles types foo_t;
bar_run(foo_t, foo_roles)

foo.if:
interface foo_run(
	type_transition $1 foo_exec_t:process foo_t;
	roleattribute $2 foo_roles;
)

But the problem that I suspect we'll see is what happens the bar_run()
interface also has a role attribute?  Extending the above example:

bar.if:
interface bar_run(
	type_transition $1 bar_exec_t:process bar_t;
	roleattribute $2 bar_roles;
)

When the policy is expanded, you end up getting a roleattribute
statement that has all role attributes in it:

roleattribute foo_roles bar_roles;

This should result in bar_roles being a superset of foo_roles.  It
doesn't sound like this is being done.  There is at least one example of
this case in refpolicy, see rpm_run() and seutil_run_semanage(); caller
runs rpm->rpm_script->semanage->load_policy.

-- 
Chris PeBenito
Tresys Technology, LLC
www.tresys.com | oss.tresys.com

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

* RE: v0 Add role attribute support to libsepol
  2011-05-27 14:57     ` Christopher J. PeBenito
@ 2011-05-29  4:46       ` HarryCiao
  0 siblings, 0 replies; 11+ messages in thread
From: HarryCiao @ 2011-05-29  4:46 UTC (permalink / raw)
  To: Christopher J. PeBenito, method
  Cc: qingtao.cao, Stephen Smalley, jmorris, eparis,
	selinux-mailing-list, Daniel Walsh

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


Hi Chris,

> Date: Fri, 27 May 2011 10:57:32 -0400
> From: cpebenito@tresys.com
> To: method@manicmethod.com
> CC: qingtao.cao@windriver.com; sds@tycho.nsa.gov; jmorris@namei.org; eparis@parisplace.org; selinux@tycho.nsa.gov; dwalsh@redhat.com
> Subject: Re: v0 Add role attribute support to libsepol
> 
> On 05/27/11 10:23, Joshua Brindle wrote:
> > Joshua Brindle wrote:
> >> Harry Ciao wrote:
> >>>
> >>> Comments:
> >>> ---------
> >>> Add role attribute to SELinux, which aims at replacing the deprecated
> >>> role dominance rule.
> >>
> >> Thanks. This is going to take a bit of time to absorb and most of my
> >> cycles are
> >> in use at the moment. I'll definitely get around to looking at it though.
> >>
> > 
> > I'd also like to solicit feedback from Dan and Chris as to how this will
> > be used in policy, and as to whether this implementation is suitable.
> > 
> > Dan, Chris, opinions?
> 
> Do we really want to overload the attribute statement for declaring role
> attributes?

Well, I guess we have to, since the attribute statement would be the only entrypoint to set a role_datum_t.flavor as ROLE_ATTRIB, and the role-types statement would no longer be able to declare roles, since they current syntax does not support to specify if the role is a regular role or a role attribute.

BTW, a regular role would be declared by the newly added role-attr statement exactly as the type statement, and the role-types statement would be solely used for setting up role - role attribute association and association between role attributes.

> 
> If I understand the description correctly, it seems reasonable, but will
> still run into problems for refpolicy.  We want to immediately use this
> feature for handling chains of run interfaces.  For example, say we have
> an admin (admin_r:admin_t) and he can run the foo program (foo_t
> domain).  The foo program then runs the bar program (bar_t) domain.  The
> (abbreviated) policy right now would look like this:
> 
> foo.te:
> bar_domtrans(foo_t)
> 
> foo.if:
> interface foo_run(
> 	type_transition $1 foo_exec_t:process foo_t;
> 	role $2 types foo_t;
> 	bar_run($1,$2)
> )
> 
> The reason we do this is so that the bar_t is added on to the admin_r
> role, without adding a direct transition from admin_t to bar_t.  But the
> above gets messy when the policy writer forgets to put the accompanying
> bar_run() call in the foo_run() interface implementation.  With role
> attributes it would be simplified to:
> 
> foo.te:
> role foo_roles types foo_t;
> bar_run(foo_t, foo_roles)
> 
> foo.if:
> interface foo_run(
> 	type_transition $1 foo_exec_t:process foo_t;
> 	roleattribute $2 foo_roles;
> )
> 
> But the problem that I suspect we'll see is what happens the bar_run()
> interface also has a role attribute?  Extending the above example:
> 
> bar.if:
> interface bar_run(
> 	type_transition $1 bar_exec_t:process bar_t;
> 	roleattribute $2 bar_roles;
> )
> 
> When the policy is expanded, you end up getting a roleattribute
> statement that has all role attributes in it:
> 
> roleattribute foo_roles bar_roles;
> 
> This should result in bar_roles being a superset of foo_roles.  It
> doesn't sound like this is being done.  There is at least one example of
> this case in refpolicy, see rpm_run() and seutil_run_semanage(); caller
> runs rpm->rpm_script->semanage->load_policy.
> 

Yep, I've got your point. Many thanks for clarifying your needs so that I would have a better idea of how role attributes are expected to be used.

While, I have sent out v1 patches, the last one 6/6 patch aims at setting up associations between two role attributes, while the first 5 remains the same as v0.

BTW, I also have modified rpm.* and selinuxutil.* to setup a test scenario same as what you have described above, please further refer to the attachment of the 0/6 email of v1 patches.

Thanks again! Looking forward to your feedbacks.

Best regards,
Harry



> -- 
> Chris PeBenito
> Tresys Technology, LLC
> www.tresys.com | oss.tresys.com
> 
> --
> 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: 5147 bytes --]

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

end of thread, other threads:[~2011-05-29  4:46 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-27  1:24 v0 Add role attribute support to libsepol Harry Ciao
2011-05-27  1:24 ` [v0 PATCH 1/5] Add role attribute support when compiling modules Harry Ciao
2011-05-27  1:24 ` [v0 PATCH 2/5] Add role attribute support when generating pp files Harry Ciao
2011-05-27  1:24 ` [v0 PATCH 3/5] Add role attribute support when linking modules Harry Ciao
2011-05-27  1:24 ` [v0 PATCH 4/5] Add role attribute support when expanding role_datum_t Harry Ciao
2011-05-27  1:24 ` [v0 PATCH 5/5] Add role attribute support when expanding role_set_t Harry Ciao
2011-05-27  2:00 ` v0 Add role attribute support to libsepol HarryCiao
2011-05-27 13:52 ` Joshua Brindle
2011-05-27 14:23   ` Joshua Brindle
2011-05-27 14:57     ` Christopher J. PeBenito
2011-05-29  4:46       ` 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.