[v0 PATCH 2/5] Make role_transition parser to handle class field

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Harry Ciao <harrytaurus2002@xxxxxxxxxxx>

If no class is specified in the role_transition rule, then it would
be set to the "process" class by default.

Signed-off-by: Harry Ciao <qingtao.cao@xxxxxxxxxxxxx>
---
 checkpolicy/policy_define.c |   89 ++++++++++++++++++++++++++++++++-----------
 checkpolicy/policy_define.h |    2 +-
 checkpolicy/policy_parse.y  |    4 +-
 3 files changed, 71 insertions(+), 24 deletions(-)

diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c
index 82ab44c..6c28d8a 100644
--- a/checkpolicy/policy_define.c
+++ b/checkpolicy/policy_define.c
@@ -2050,17 +2050,18 @@ static int set_roles(role_set_t * set, char *id)
 	return 0;
 }
 
-int define_role_trans(void)
+int define_role_trans(int class_specified)
 {
 	char *id;
 	role_datum_t *role;
 	role_set_t roles;
 	type_set_t types;
-	ebitmap_t e_types, e_roles;
-	ebitmap_node_t *tnode, *rnode;
+	class_datum_t *cladatum;
+	ebitmap_t e_types, e_roles, classes;
+	ebitmap_node_t *tnode, *rnode, *cnode;
 	struct role_trans *tr = NULL;
 	struct role_trans_rule *rule = NULL;
-	unsigned int i, j;
+	unsigned int i, j, k;
 	int add = 1;
 
 	if (pass == 1) {
@@ -2068,6 +2069,9 @@ int define_role_trans(void)
 			free(id);
 		while ((id = queue_remove(id_queue)))
 			free(id);
+		if (class_specified)
+			while ((id = queue_remove(id_queue)))
+				free(id);
 		id = queue_remove(id_queue);
 		free(id);
 		return 0;
@@ -2077,6 +2081,7 @@ int define_role_trans(void)
 	ebitmap_init(&e_roles);
 	type_set_init(&types);
 	ebitmap_init(&e_types);
+	ebitmap_init(&classes);
 
 	while ((id = queue_remove(id_queue))) {
 		if (set_roles(&roles, id))
@@ -2088,6 +2093,35 @@ int define_role_trans(void)
 			return -1;
 	}
 
+	if (class_specified) {
+		while ((id = queue_remove(id_queue))) {
+			if (!is_id_in_scope(SYM_CLASSES, id)) {
+				yyerror2("class %s is not within scope", id);
+				free(id);
+				return -1;
+			}
+			cladatum = hashtab_search(policydbp->p_classes.table,
+						  id);
+			if (!cladatum) {
+				yyerror2("unknow class %s", id);
+				return -1;
+			}
+
+			ebitmap_set_bit(&classes, cladatum->s.value - 1, TRUE);
+			free(id);
+		}
+	} else {
+		cladatum = hashtab_search(policydbp->p_classes.table,
+					  "process");
+		if (!cladatum) {
+			yyerror2("could not find process class for "
+				 "legacy role_transition statement");
+			return -1;
+		}
+
+		ebitmap_set_bit(&classes, cladatum->s.value - 1, TRUE);
+	}
+
 	id = (char *)queue_remove(id_queue);
 	if (!id) {
 		yyerror("no new role in transition definition?");
@@ -2117,27 +2151,37 @@ int define_role_trans(void)
 		ebitmap_for_each_bit(&e_types, tnode, j) {
 			if (!ebitmap_node_get_bit(tnode, j))
 				continue;
-
-			for (tr = policydbp->role_tr; tr; tr = tr->next) {
-				if (tr->role == (i + 1) && tr->type == (j + 1)) {
-					yyerror2("duplicate role transition for (%s,%s)",
-					      role_val_to_name(i + 1),
-					      policydbp->p_type_val_to_name[j]);
-					goto bad;
+			ebitmap_for_each_bit(&classes, cnode, k) {
+				if (!ebitmap_node_get_bit(cnode, k))
+					continue;
+				for (tr = policydbp->role_tr; tr;
+				     tr = tr->next) {
+					if (tr->role == (i + 1) &&
+					    tr->type == (j + 1) &&
+					    tr->cclass == (k + 1)) {
+						yyerror2("duplicate role "
+							 "transition for "
+							 "(%s,%s,%s)",
+							 role_val_to_name(i+1),
+							 policydbp->p_type_val_to_name[j],
+							 policydbp->p_class_val_to_name[k]);
+						goto bad;
+					}
 				}
-			}
 
-			tr = malloc(sizeof(struct role_trans));
-			if (!tr) {
-				yyerror("out of memory");
-				return -1;
+				tr = malloc(sizeof(struct role_trans));
+				if (!tr) {
+					yyerror("out of memory");
+					return -1;
+				}
+				memset(tr, 0, sizeof(struct role_trans));
+				tr->role = i + 1;
+				tr->type = j + 1;
+				tr->cclass = k + 1;
+				tr->new_role = role->s.value;
+				tr->next = policydbp->role_tr;
+				policydbp->role_tr = tr;
 			}
-			memset(tr, 0, sizeof(struct role_trans));
-			tr->role = i + 1;
-			tr->type = j + 1;
-			tr->new_role = role->s.value;
-			tr->next = policydbp->role_tr;
-			policydbp->role_tr = tr;
 		}
 	}
 	/* Now add the real rule */
@@ -2149,6 +2193,7 @@ int define_role_trans(void)
 	memset(rule, 0, sizeof(struct role_trans_rule));
 	rule->roles = roles;
 	rule->types = types;
+	rule->classes = classes;
 	rule->new_role = role->s.value;
 
 	append_role_trans(rule);
diff --git a/checkpolicy/policy_define.h b/checkpolicy/policy_define.h
index 5ac6667..2f7a78f 100644
--- a/checkpolicy/policy_define.h
+++ b/checkpolicy/policy_define.h
@@ -45,7 +45,7 @@ int define_ioport_context(unsigned long low, unsigned long high);
 int define_pcidevice_context(unsigned long device);
 int define_range_trans(int class_specified);
 int define_role_allow(void);
-int define_role_trans(void);
+int define_role_trans(int class_specified);
 int define_role_types(void);
 int define_sens(void);
 int define_te_avtab(int which);
diff --git a/checkpolicy/policy_parse.y b/checkpolicy/policy_parse.y
index 8d1bc37..8c29e2b 100644
--- a/checkpolicy/policy_parse.y
+++ b/checkpolicy/policy_parse.y
@@ -417,7 +417,9 @@ role_type_def		: ROLE identifier TYPES names ';'
 role_dominance		: DOMINANCE '{' roles '}'
 			;
 role_trans_def		: ROLE_TRANSITION names names identifier ';'
-			{if (define_role_trans()) return -1; }
+			{if (define_role_trans(0)) return -1; }
+			| ROLE_TRANSITION names names ':' names identifier ';'
+			{if (define_role_trans(1)) return -1;}
 			;
 role_allow_def		: ALLOW names names ';'
 			{if (define_role_allow()) return -1; }
-- 
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@xxxxxxxxxxxxx with
the words "unsubscribe selinux" without quotes as the message.


[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux