All of lore.kernel.org
 help / color / mirror / Atom feed
From: KaiGai Kohei <kaigai@kaigai.gr.jp>
To: KaiGai Kohei <kaigai@kaigai.gr.jp>
Cc: Stephen Smalley <sds@tycho.nsa.gov>,
	Kaigai Kohei <kaigai@ak.jp.nec.com>,
	SELinux Mail List <selinux@tycho.nsa.gov>
Subject: Re: [RFC & PATCH] inherited type definition.
Date: Mon, 21 Mar 2005 19:07:59 +0900	[thread overview]
Message-ID: <423E9CFF.3080808@kaigai.gr.jp> (raw)
In-Reply-To: <42399AE4.5040508@kaigai.gr.jp>

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

Hi,

This attached patch implements (1) EXTENDS syntax with TYPE statement and
(2) '@' prefix to distinguish whether an assigned type/attribute includes
own child types or not.

(1) TYPE ... EXTENDS syntax

TYPE <typename> [ALIAS <aliases>] EXTENDS <type/attr>, <type/attr>, ...

The declared type can have the parents enumerated behind EXTENDS.
If we grant any permissions with '@' prefix, this permission is also
granted to own child types.

(2) '@' prefix

This is new feature from the former version.
If we specify the types (which have some child types) with '@' prefix to grant
permissions, the specified types is treated as the specified types directly
and those chils type.
If we specify the types without '@' prefix, such interpretation is not done.
By default, specifying the types are recognized same as current checkpolicy doing.

For Example:

attribute attr;
type X extends attr;
type Y extends X;
type A;
type B extends A;
type C extends A, X;

"allow @A A:file read;" is equal "allow {A B C} A:file read;".
"allow @A @A-@X:file read;" is equal "allow {A B C} {A B}:file read;".
"allow attr ~@X:file read;" is equal "allow {X Y C} {A B}:file read;".

We can use the '@' prefixi in following statements.
- ALLOW/AUDITALLOW/AUDITDENY/DONTAUDIT statements
- TYPE_TRANSITION/TYPE_MEMBER/TYPE_CHANGE statements
- ROLE/ROLE_TRANSITION statements.
- CONSTRAIN statements
- VALIDATETRANS statements (I was not sure)
- RANGE_TRANSITION statements (MLS statement, I was not sure)

In addition, the recognization of 'self' is changed from former version's patch.
In former version, "allow @A self:file read;" means "allow A {A B C}:file read;"
and "allow B B:file read;", "allow C C:file read;".
(I appended '@' for convenience.)

But in current version, "allow @A self:file read" means "allow {A B C} {A B C}:file read;".
Since I thought this interpretation is more aimple.

I checked this patch with 'sediff' and printf() in source.
If there are several good checking tools for such a purpose, I want you to teach.

Thanks,
-- 
DO NOTHING IS THE WORST POLICY.
KaiGai Kohei <kaigai@kaigai.gr.jp>

[-- Attachment #2: checkpolicy-1.22-type_extends.2nd.patch --]
[-- Type: text/plain, Size: 22022 bytes --]

--- checkpolicy-1.22/checkpolicy.h	2005-01-26 14:16:20.000000000 -0500
+++ checkpolicy-1.22.extends.2nd/checkpolicy.h	2005-03-21 12:58:08.000000000 -0500
@@ -7,6 +7,7 @@ typedef struct te_assert { 
 	ebitmap_t stypes;
 	ebitmap_t ttypes;
 	ebitmap_t tclasses;
+	ebitmap_t inherit;
         int self;
 	access_vector_t *avp;
 	unsigned long line;
@@ -18,4 +19,16 @@ te_assert_t *te_assertions;
 extern unsigned int policyvers;
 extern unsigned int mlspol;
 
+/* type was not indexed in policydb,
+   but it's necessary for extends support. */
+extern type_datum_t **type_val_to_struct;
+extern int num_type_val_to_struct;
+extern void get_child_types(ebitmap_t *set, type_datum_t *t, int recursive);
+
+static inline type_datum_t *get_type(int typeval) {
+	if (!type_val_to_struct || typeval<1 || typeval>num_type_val_to_struct)
+		return NULL;
+	return type_val_to_struct[typeval-1];
+}
+
 #endif
--- checkpolicy-1.22/checkpolicy.c	2005-01-26 14:16:20.000000000 -0500
+++ checkpolicy-1.22.extends.2nd/checkpolicy.c	2005-03-21 16:40:36.000000000 -0500
@@ -344,8 +344,10 @@ void check_assertion_helper(unsigned int
 
 void check_assertions(void) 
 {
+	ebitmap_t temp;
+	type_datum_t *typedatum;
 	te_assert_t *a, *tmp;
-	unsigned int i, j;
+	unsigned int i, j, k;
 
 	a = te_assertions;
 	while (a) {
@@ -353,7 +355,23 @@ void check_assertions(void) 
 			if (!ebitmap_get_bit(&a->stypes, i))
 				continue;
 			if (a->self) {
-				check_assertion_helper(i, i, &a->tclasses, a->avp, a->line);
+				typedatum = type_val_to_struct[i];
+				if (!typedatum) {
+					fprintf(stderr, "BUG: check_assetion for undefined type.\n");
+					exit(1);
+				}
+				ebitmap_init(&temp);
+				get_child_types(&temp, typedatum, ebitmap_get_bit(&a->inherit, i));
+				for (j = ebitmap_startbit(&temp); j < ebitmap_length(&temp); j++) {
+					if (!ebitmap_get_bit(&temp, j))
+						continue;
+					for (k = ebitmap_startbit(&temp); k < ebitmap_length(&temp); k++) {
+						if (!ebitmap_get_bit(&temp, k))
+							continue;
+						 check_assertion_helper(j, k, &a->tclasses, a->avp, a->line);
+					}
+				}
+				ebitmap_destroy(&temp);
 			}
 			for (j = ebitmap_startbit(&a->ttypes); j < ebitmap_length(&a->ttypes); j++) {
 				if (!ebitmap_get_bit(&a->ttypes, j)) 
@@ -366,6 +384,7 @@ void check_assertions(void) 
 		ebitmap_destroy(&tmp->stypes);
 		ebitmap_destroy(&tmp->ttypes);
 		ebitmap_destroy(&tmp->tclasses);
+		ebitmap_destroy(&tmp->inherit);
 		free(tmp->avp);
 		free(tmp);
 	}
@@ -442,6 +461,49 @@ int change_bool(char *name, int state)
 	return 0;
 }
 
+type_datum_t **type_val_to_struct = NULL;
+int num_type_val_to_struct = -1;
+
+static int type_val_to_struct_helper(hashtab_key_t k, hashtab_datum_t d, void *args)
+{
+	type_datum_t *t = (type_datum_t *)d;
+	if (!t->isattr && t->primary)
+		type_val_to_struct[t->value-1] = t;
+	return 0; /* always success */
+}
+
+void get_child_types(ebitmap_t *set, type_datum_t *td, int recur)
+{
+	type_datum_t *child;
+	int i;
+
+	if (!td->isattr && !td->primary)
+		td = get_type(td->value);
+
+	if (!td->isattr) {
+		ebitmap_set_bit(set, td->value - 1, 1);
+		if (!recur)
+			return;
+		for (i = ebitmap_startbit(&td->types); i < ebitmap_length(&td->types); i++) {
+			if (!ebitmap_get_bit(&td->types, i))
+				continue;
+			child = type_val_to_struct[i];
+			get_child_types(set, child, recur);
+		}
+	} else {
+		for (i = ebitmap_startbit(&td->types); i < ebitmap_length(&td->types); i++) {
+			if (!ebitmap_get_bit(&td->types, i))
+				continue;
+			if (!recur) {
+				ebitmap_set_bit(set, i, 1);
+			} else {
+				child = type_val_to_struct[i];
+				get_child_types(set, child, recur);
+			}
+		}
+	}
+}
+
 int main(int argc, char **argv)
 {
 	security_class_t tclass;
@@ -456,7 +518,7 @@ int main(int argc, char **argv)
 	unsigned int binary = 0, debug = 0;
 	struct val_to_name v;
 	int ret, ch, fd;
-	unsigned int nel;
+	unsigned int nel, len;
 	struct stat sb;
 	void *map;
 	FILE *outfp = NULL;
@@ -593,6 +655,18 @@ int main(int argc, char **argv)
 			fprintf(stderr, "%s:  error(s) encountered while parsing configuration\n", argv[0]);
 			exit(1);
 		}
+
+		/* construction of type_val_to_struct */
+		num_type_val_to_struct = policydbp->p_types.nprim;
+		len = sizeof(type_datum_t *) * num_type_val_to_struct;
+		type_val_to_struct = (type_datum_t **)malloc(len);
+		if (!type_val_to_struct) {
+			fprintf(stderr, "type_val_to_struct: out of memory\n");
+			exit(1);
+		}
+		memset(type_val_to_struct, 0, len);
+		hashtab_map(policydbp->p_types.table, type_val_to_struct_helper, NULL);
+
 		rewind(yyin);
 		policydb_lineno = 1;
 		source_file[0] = '\0';
--- checkpolicy-1.22/policy_scan.l	2005-02-17 09:59:23.000000000 -0500
+++ checkpolicy-1.22.extends.2nd/policy_scan.l	2005-03-21 12:23:17.000000000 -0500
@@ -78,6 +78,8 @@ ELSE |
 else				{ return(ELSE); }
 ALIAS |
 alias				{ return(ALIAS); }
+EXTENDS |
+extends				{ return(EXTENDS); }
 ATTRIBUTE |
 attribute			{ return(ATTRIBUTE); }
 TYPE_TRANSITION |
@@ -211,7 +213,8 @@ H2				{ return(H2); }
 "." |
 "]" |
 "~" |
-"*"				{ return(yytext[0]); } 
+"*" |
+"@"				{ return(yytext[0]); } 
 .                               { yywarn("unrecognized character");}
 %%
 int yyerror(char *msg)
--- checkpolicy-1.22/policy_parse.y	2005-02-17 09:59:23.000000000 -0500
+++ checkpolicy-1.22.extends.2nd/policy_parse.y	2005-03-21 16:46:52.000000000 -0500
@@ -19,6 +19,11 @@
  *	the Free Software Foundation, version 2.
  */
 
+/* Updated: KaiGai Kohei, <kaigai@ak.jp.nec.com>
+ *      Added inherited type extensions and '@' prefix. (2005/03/21)
+ */
+
+
 /* FLASK */
 
 %{
@@ -73,7 +78,7 @@ static int define_level(int range);
 static int define_attrib(void);
 static int define_typealias(void);
 static int define_typeattribute(void);
-static int define_type(int alias);
+static int define_type(int alias, int extends);
 static int define_compute_type(int which);
 static int define_te_avtab(int which);
 static int define_role_types(void);
@@ -133,6 +138,7 @@ static int define_ipv6_node_context(void
 %token TYPE
 %token TYPES
 %token ALIAS
+%token EXTENDS
 %token ATTRIBUTE
 %token BOOL
 %token IF
@@ -297,9 +303,13 @@ attribute_def           : ATTRIBUTE iden
                         { if (define_attrib()) return -1;}
                         ;
 type_def		: TYPE identifier alias_def opt_attr_list ';'
-                        {if (define_type(1)) return -1;}
+                        {if (define_type(1, 0)) return -1;}
 	                | TYPE identifier opt_attr_list ';'
-                        {if (define_type(0)) return -1;}
+                        {if (define_type(0, 0)) return -1;}
+			| TYPE identifier alias_def opt_extends_list ';'
+			{if (define_type(1, 1)) return -1;}
+			| TYPE identifier opt_extends_list ';'
+			{if (define_type(0, 1)) return -1;}
     			;
 typealias_def           : TYPEALIAS identifier alias_def ';'
 			{if (define_typealias()) return -1;}
@@ -310,6 +320,8 @@ typeattribute_def	: TYPEATTRIBUTE identi
 opt_attr_list           : ',' id_comma_list
 			| 
 			;
+opt_extends_list	: EXTENDS id_comma_list
+			;
 bool_def                : BOOL identifier bool_val ';'
                         {if (define_bool()) return -1;}
                         ;
@@ -511,13 +523,13 @@ cexpr_prim		: U1 op U2
 			| R3 op { if (insert_separator(1)) return -1; } names_push
 			{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_ROLE | CEXPR_XTARGET), $2);
 			  if ($$ == 0) return -1; }
-			| T1 op { if (insert_separator(1)) return -1; } names_push
+			| T1 op { if (insert_separator(1)) return -1; } type_names_push
 			{ $$ = define_cexpr(CEXPR_NAMES, CEXPR_TYPE, $2);
 			  if ($$ == 0) return -1; }
-			| T2 op { if (insert_separator(1)) return -1; } names_push
+			| T2 op { if (insert_separator(1)) return -1; } type_names_push
 			{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_TARGET), $2);
 			  if ($$ == 0) return -1; }
-			| T3 op { if (insert_separator(1)) return -1; } names_push
+			| T3 op { if (insert_separator(1)) return -1; } type_names_push
 			{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_XTARGET), $2);
 			  if ($$ == 0) return -1; }
 			| SAMEUSER
@@ -532,10 +544,10 @@ cexpr_prim		: U1 op U2
 			| ROLE role_mls_op
 			{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_ROLE, $2);
 			  if ($$ == 0) return -1; }
-			| SOURCE TYPE { if (insert_separator(1)) return -1; } names_push
+			| SOURCE TYPE { if (insert_separator(1)) return -1; } type_names_push
 			{ $$ = define_cexpr(CEXPR_NAMES, CEXPR_TYPE, CEXPR_EQ);
 			  if ($$ == 0) return -1; }
-			| TARGET TYPE { if (insert_separator(1)) return -1; } names_push
+			| TARGET TYPE { if (insert_separator(1)) return -1; } type_names_push
 			{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_TARGET), CEXPR_EQ);
 			  if ($$ == 0) return -1; }
 			| L1 role_mls_op L2
@@ -695,20 +707,27 @@ tilde			: '~'
 			;
 asterisk		: '*'
 			;
-names           	: identifier
+atmark			: '@'
+			;
+type_identifier		: IDENTIFIER
+			{ if (insert_id(yytext, 0)) return -1; }
+			| atmark IDENTIFIER
+			{ if (insert_id("@", 0) || insert_id(yytext, 0)) return -1; }
+			;
+names           	: type_identifier
 			{ if (insert_separator(0)) return -1; }
 			| nested_id_set
 			{ if (insert_separator(0)) return -1; }
 			| asterisk
                         { if (insert_id("*", 0)) return -1; 
 			  if (insert_separator(0)) return -1; }
-			| tilde identifier
+			| tilde type_identifier
                         { if (insert_id("~", 0)) return -1;
 			  if (insert_separator(0)) return -1; }
 			| tilde nested_id_set
-	 		{ if (insert_id("~", 0)) return -1; 
+			{ if (insert_id("~", 0)) return -1;
 			  if (insert_separator(0)) return -1; }
-                        | identifier '-' { if (insert_id("-", 0)) return -1; } identifier 
+			| type_identifier '-' { if (insert_id("-", 0)) return -1; } type_identifier 
 			{ if (insert_separator(0)) return -1; }
 			;
 tilde_push              : tilde
@@ -717,6 +736,19 @@ tilde_push              : tilde
 asterisk_push           : asterisk
                         { if (insert_id("*", 1)) return -1; }
 			;
+type_names_push		: type_identifier_push
+			| '{' type_identifier_list_push '}'
+			| tilde_push type_identifier_push
+			| tilde_push '{' type_identifier_list_push '}'
+			;
+type_identifier_list_push	: type_identifier_push
+				| type_identifier_list_push type_identifier_push
+				;
+type_identifier_push	: IDENTIFIER
+			{ if (insert_id(yytext,1)) return -1; }
+			| atmark IDENTIFIER
+			{ if (insert_id(yytext,1)||insert_id("@",1)) return -1;}
+			;
 names_push		: identifier_push
 			| '{' identifier_list_push '}'
 			| asterisk_push
@@ -736,7 +768,9 @@ nested_id_set           : '{' nested_id_
                         ;
 nested_id_list          : nested_id_element | nested_id_list nested_id_element
                         ;
-nested_id_element       : identifier | '-' { if (insert_id("-", 0)) return -1; } identifier | nested_id_set
+nested_id_element       : type_identifier
+			| '-' { if (insert_id("-", 0)) return -1; } type_identifier
+			| nested_id_set
                         ;
 identifier		: IDENTIFIER
 			{ if (insert_id(yytext,0)) return -1; }
@@ -1596,10 +1630,10 @@ static int define_typeattribute(void)
 	return 0;
 }
 
-static int define_type(int alias)
+static int define_type(int alias, int extends)
 {
 	char *id;
-	type_datum_t *datum, *aliasdatum, *attr;
+	type_datum_t *datum, *aliasdatum, *inherit;
 	int ret, newattr = 0;
 
 
@@ -1677,9 +1711,10 @@ static int define_type(int alias)
 	}
 
 	while ((id = queue_remove(id_queue))) {
-		attr = hashtab_search(policydbp->p_types.table, id);
-		if (!attr) {
-			sprintf(errormsg, "attribute %s is not declared", id);
+		inherit = hashtab_search(policydbp->p_types.table, id);
+		if (!inherit) {
+			sprintf(errormsg, "%sattribute %s is not declared",
+			        (extends)?"type/":"", id);
 #if 1
 			/* treat it as a fatal error */
 			yyerror(errormsg);
@@ -1708,7 +1743,7 @@ static int define_type(int alias)
 			newattr = 0;
 		}
 
-		if (!attr->isattr) {
+		if (!extends && !inherit->isattr) {
 			sprintf(errormsg, "%s is a type, not an attribute", id);
 			yyerror(errormsg);
 			return -1;
@@ -1717,7 +1752,7 @@ static int define_type(int alias)
 		if (!newattr)
 			free(id);
 
-		ebitmap_set_bit(&attr->types, datum->value - 1, TRUE);
+		ebitmap_set_bit(&inherit->types, datum->value - 1, TRUE);
 	}
 
 	return 0;
@@ -1759,11 +1794,13 @@ static char *type_val_to_name(unsigned i
 
 static int set_types(ebitmap_t *set,
 		     ebitmap_t *negset,
+		     ebitmap_t *inherit,
 		     char *id,
 		     int *add)
 {
 	type_datum_t *t;
 	unsigned int i;
+	ebitmap_t temp;
 
 	if (strcmp(id, "*") == 0) {
 		/* set all types not in negset */
@@ -1788,10 +1825,16 @@ static int set_types(ebitmap_t *set,
 	}
 
 	if (strcmp(id, "-") == 0) {
-		*add = 0;
+		*add &= 0xfffe; /* clear bit 0*/
+		free(id);
+		return 0;
+	}
+
+	if (strcmp(id, "@") == 0) {
+		*add |= 0x0002; /* set bit 1 */
 		free(id);
 		return 0;
-	}	
+	}
 
 	t = hashtab_search(policydbp->p_types.table, id);
 	if (!t) {
@@ -1800,42 +1843,28 @@ static int set_types(ebitmap_t *set,
 		free(id);
 		return -1;
 	}
+	if (inherit && ((*add)&0x0002)!=0 )
+		ebitmap_set_bit(inherit, t->value - 1, TRUE);
 
-	if (t->isattr) {
-		/* set or clear all types with this attribute,
-		   but do not set anything explicitly cleared previously */
-		for (i = ebitmap_startbit(&t->types); i < ebitmap_length(&t->types); i++) {
-			if (!ebitmap_get_bit(&t->types, i)) 
-				continue;		
-			if (!(*add)) {
-				ebitmap_set_bit(set, i, FALSE);
-				ebitmap_set_bit(negset, i, TRUE);
-			} else if (!ebitmap_get_bit(negset, i)) {
-				ebitmap_set_bit(set, i, TRUE);
-#if VERBOSE
-			} else {
-				char *name = type_val_to_name(i+1);
-				sprintf(errormsg, "ignoring %s due to prior -%s", name, name);
-				yywarn(errormsg);
-#endif
-			}
-		}
-	} else {
-		/* set or clear one type, but do not set anything
-		   explicitly cleared previously */	
-		if (!(*add)) {
-			ebitmap_set_bit(set, t->value - 1, FALSE);
-			ebitmap_set_bit(negset, t->value - 1, TRUE);
-		} else if (!ebitmap_get_bit(negset, t->value - 1)) {
-			ebitmap_set_bit(set, t->value - 1, TRUE);
+	ebitmap_init(&temp);
+	get_child_types(&temp, t, (*add)&0x0002);
+	for (i = ebitmap_startbit(&temp); i < ebitmap_length(&temp); i++) {
+		if (!ebitmap_get_bit(&temp, i))
+			continue;
+		if (!((*add)&0x0001)) {
+			ebitmap_set_bit(set, i, FALSE);
+			ebitmap_set_bit(negset, i, TRUE);
+		} else if (!ebitmap_get_bit(negset, i)) {
+			ebitmap_set_bit(set, i, TRUE);
 #if VERBOSE
 		} else {
-			sprintf(errormsg, "ignoring %s due to prior -%s", id, id);
+			char *name = type_val_to_name(i+1);
+			sprintf(errormsg, "ignoring %s due to prior -%s", name, name);
 			yywarn(errormsg);
 #endif
 		}
 	}
-
+	ebitmap_destroy(&temp);
 	free(id);
 	*add = 1;
 	return 0;
@@ -1872,14 +1901,14 @@ static int define_compute_type(int which
 
 	ebitmap_init(&negset);
 	while ((id = queue_remove(id_queue))) {
-		if (set_types(&stypes, &negset, id, &add))
+		if (set_types(&stypes, &negset, NULL, id, &add))
 			return -1;
 	}
 	ebitmap_destroy(&negset);
 
 	ebitmap_init(&negset);
 	while ((id = queue_remove(id_queue))) {
-		if (set_types(&ttypes, &negset, id, &add))
+		if (set_types(&ttypes, &negset, NULL, id, &add))
 			return -1;
 	}
 	ebitmap_destroy(&negset);
@@ -2012,14 +2041,14 @@ static cond_av_list_t *define_cond_compu
 
 	ebitmap_init(&negset);
 	while ((id = queue_remove(id_queue))) {
-		if (set_types(&stypes, &negset, id, &add))
+		if (set_types(&stypes, &negset, NULL, id, &add))
 			return  COND_ERR;
 	}
 	ebitmap_destroy(&negset);
 
 	ebitmap_init(&negset);
 	while ((id = queue_remove(id_queue))) {
-		if (set_types(&ttypes, &negset, id, &add))
+		if (set_types(&ttypes, &negset, NULL, id, &add))
 			return COND_ERR;
 	}
 	ebitmap_destroy(&negset);
@@ -2419,9 +2448,10 @@ static cond_av_list_t *define_cond_te_av
 	cond_av_list_t *sub_list, *final_list, *tail;
 	class_datum_t *cladatum;
 	perm_datum_t *perdatum;
-	ebitmap_t stypes, ttypes, tclasses, negset;
+	type_datum_t *typedatum;
+	ebitmap_t stypes, ttypes, tclasses, temp, inherit, negset;
 	access_vector_t *avp;
-	int i, j, hiclass, self = 0, add = 1;
+	int i, j, k, hiclass, self = 0, add = 1;
 	int suppress = 0;
 
 	if (pass == 1) {
@@ -2439,10 +2469,11 @@ static cond_av_list_t *define_cond_te_av
 	ebitmap_init(&stypes);
 	ebitmap_init(&ttypes);
 	ebitmap_init(&tclasses);
+	ebitmap_init(&inherit);
 
 	ebitmap_init(&negset);
 	while ((id = queue_remove(id_queue))) {
-		if (set_types(&stypes, &negset, id, &add))
+		if (set_types(&stypes, &negset, &inherit, id, &add))
 			return COND_ERR;
 	}
 	ebitmap_destroy(&negset);
@@ -2453,7 +2484,7 @@ static cond_av_list_t *define_cond_te_av
 			self = 1;
 			continue;
 		}
-		if (set_types(&ttypes, &negset, id, &add))
+		if (set_types(&ttypes, &negset, NULL, id, &add))
 			return COND_ERR;
 	}
 	ebitmap_destroy(&negset);
@@ -2542,19 +2573,36 @@ static cond_av_list_t *define_cond_te_av
 		for (i = ebitmap_startbit(&stypes); i < ebitmap_length(&stypes); i++) {
 			if (!ebitmap_get_bit(&stypes, i)) 
 				continue;
-			if (self) {
-				if ((sub_list = cond_te_avtab_helper(which, i, i, &tclasses, avp )) == COND_ERR)
-					return COND_ERR;
-				if (final_list) {
-					tail->next = sub_list;
-					while (tail->next != NULL)
-						tail = tail->next;
-				} else {
-					final_list = sub_list;
-					tail = final_list;
-					while (tail->next != NULL)
-						tail = tail->next;
+			typedatum = get_type(i+1);
+			if (!typedatum)
+				return COND_ERR;
+			ebitmap_init(&temp);
+			/* If the source type is given with '@' prefix,
+			   'self' also includes own child types. */
+			get_child_types(&temp, typedatum, ebitmap_get_bit(&inherit,i));
+			for (j = ebitmap_startbit(&temp); j < ebitmap_length(&temp); j++) {
+				if(!ebitmap_get_bit(&temp, j))
+					continue;
+				for (k = ebitmap_startbit(&temp); k < ebitmap_length(&temp); k++) {
+					if(!ebitmap_get_bit(&temp, k))
+						continue;
+					sub_list = cond_te_avtab_helper(which, j, k, &tclasses, avp);
+					if (sub_list==COND_ERR) {
+						ebitmap_destroy(&temp);
+						return COND_ERR;
+					}
+					if (final_list) {
+						tail->next = sub_list;
+						while (tail->next != NULL)
+							tail = tail->next;
+					} else {
+						final_list = sub_list;
+						tail = final_list;
+						while (tail->next != NULL)
+							tail = tail->next;
+					}
 				}
+				ebitmap_destroy(&temp);
 			}
 		}
 	}
@@ -2595,9 +2643,10 @@ static int define_te_avtab(int which)
 	char *id;
 	class_datum_t *cladatum;
 	perm_datum_t *perdatum;
-	ebitmap_t stypes, ttypes, tclasses, negset;
+	type_datum_t *typedatum;
+	ebitmap_t stypes, ttypes, tclasses, temp, inherit, negset;
 	access_vector_t *avp;
-	unsigned int i, j, hiclass;
+	unsigned int i, j, k, hiclass;
 	int self = 0, add = 1;
 	te_assert_t *newassert;
 	int suppress = 0;
@@ -2617,10 +2666,11 @@ static int define_te_avtab(int which)
 	ebitmap_init(&stypes);
 	ebitmap_init(&ttypes);
 	ebitmap_init(&tclasses);
+	ebitmap_init(&inherit);
 
 	ebitmap_init(&negset);
 	while ((id = queue_remove(id_queue))) {
-		if (set_types(&stypes, &negset, id, &add))
+		if (set_types(&stypes, &negset, &inherit, id, &add))
 			return -1;
 	}
 	ebitmap_destroy(&negset);
@@ -2631,7 +2681,7 @@ static int define_te_avtab(int which)
 			self = 1;
 			continue;
 		}
-		if (set_types(&ttypes, &negset, id, &add))
+		if (set_types(&ttypes, &negset, NULL, id, &add))
 			return -1;
 	}
 	ebitmap_destroy(&negset);
@@ -2723,6 +2773,7 @@ static int define_te_avtab(int which)
 		newassert->stypes = stypes;
 		newassert->ttypes = ttypes;
 		newassert->tclasses = tclasses;
+		newassert->inherit = inherit;
 		newassert->self = self;
 		newassert->avp = avp;
 		newassert->line = policydb_lineno;
@@ -2735,8 +2786,26 @@ static int define_te_avtab(int which)
 		if (!ebitmap_get_bit(&stypes, i)) 
 			continue;
 		if (self) {
-			if (te_avtab_helper(which, i, i, &tclasses, avp))
+			typedatum = get_type(i+1);
+			if (!typedatum)
 				return -1;
+			ebitmap_init(&temp);
+			/* If the source type is given with '@' prefix,
+			   'self' means own child types. */
+			get_child_types(&temp, typedatum, ebitmap_get_bit(&inherit, i));
+			for (j = ebitmap_startbit(&temp); j < ebitmap_length(&temp); j++) {
+				if (!ebitmap_get_bit(&temp, j))
+					continue;
+				for (k = ebitmap_startbit(&temp); k < ebitmap_length(&temp); k++) {
+					if (!ebitmap_get_bit(&temp, k))
+						continue;
+					if (te_avtab_helper(which, j, k, &tclasses, avp)) {
+						ebitmap_destroy(&temp);
+						return -1;
+					}
+				}
+			}
+			ebitmap_destroy(&temp);
 		}
 		for (j = ebitmap_startbit(&ttypes); j < ebitmap_length(&ttypes); j++) {
 			if (!ebitmap_get_bit(&ttypes, j)) 
@@ -2827,7 +2896,7 @@ static int define_role_types(void)
 
 	ebitmap_init(&negset);
 	while ((id = queue_remove(id_queue))) {
-		if (set_types(&role->types, &negset, id, &add))
+		if (set_types(&role->types, &negset, NULL, id, &add))
 			return -1;
 	}
 	ebitmap_destroy(&negset);
@@ -3042,7 +3111,7 @@ static int define_role_trans(void)
 
 	ebitmap_init(&negset);
 	while ((id = queue_remove(id_queue))) {
-		if (set_types(&types, &negset, id, &add))
+		if (set_types(&types, &negset, NULL, id, &add))
 			return -1;
 	}
 	ebitmap_destroy(&negset);
@@ -3467,7 +3536,7 @@ static uintptr_t
 				}
 				val = role->value;
 			} else if (expr->attr & CEXPR_TYPE) {
-				if (set_types(&expr->names, &negset, id, &add)) {
+				if (set_types(&expr->names, &negset, NULL, id, &add)) {
 					free(expr);
 					return 0;
 				}
@@ -4903,14 +4972,14 @@ static int define_range_trans(void)
 
 	ebitmap_init(&negset);
 	while ((id = queue_remove(id_queue))) {
-		if (set_types(&doms, &negset, id, &add))
+		if (set_types(&doms, &negset, NULL, id, &add))
 			return -1;
 	}
 	ebitmap_destroy(&negset);
 
 	ebitmap_init(&negset);
 	while ((id = queue_remove(id_queue))) {
-		if (set_types(&types, &negset, id, &add))
+		if (set_types(&types, &negset, NULL, id, &add))
 			return -1;
 	}
 	ebitmap_destroy(&negset);

  reply	other threads:[~2005-03-21 10:07 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-03-13 16:36 [RFC & PATCH] inherited type definition KaiGai Kohei
2005-03-14 13:17 ` KaiGai Kohei
2005-03-14 13:50 ` Stephen Smalley
2005-03-14 15:13   ` Luke Kenneth Casson Leighton
2005-03-14 15:22     ` Stephen Smalley
2005-03-14 16:01       ` Luke Kenneth Casson Leighton
2005-03-14 19:27         ` Valdis.Kletnieks
2005-03-14 20:10         ` Stephen Smalley
2005-03-14 17:26   ` KaiGai Kohei
2005-03-14 18:10     ` Luke Kenneth Casson Leighton
2005-03-14 18:25     ` Stephen Smalley
2005-03-15 11:50       ` KaiGai Kohei
2005-03-15 14:42         ` Stephen Smalley
2005-03-16  4:42           ` Kaigai Kohei
2005-03-16 10:00             ` Luke Kenneth Casson Leighton
2005-03-16 14:05             ` Stephen Smalley
2005-03-17  9:32               ` Kaigai Kohei
2005-03-17 13:55                 ` Stephen Smalley
2005-03-17 14:57                   ` KaiGai Kohei
2005-03-21 10:07                     ` KaiGai Kohei [this message]
2005-03-21 15:59                       ` Stephen Smalley
2005-03-23  8:17                         ` Kaigai Kohei
2005-03-23 13:56                           ` Stephen Smalley
2005-04-16  7:31                             ` KaiGai Kohei
2005-04-18 12:25                               ` Stephen Smalley
2005-04-18 16:57                                 ` KaiGai Kohei
2005-03-24 11:06                           ` Luke Kenneth Casson Leighton
2005-03-24 12:34                             ` Kaigai Kohei
2005-04-06 12:49         ` Russell Coker
2005-04-06 14:50           ` KaiGai Kohei
2005-04-06 15:30             ` Russell Coker
2005-04-06 18:23               ` Jim McCullough
2005-04-07  2:16               ` Kaigai Kohei
2005-04-06 17:55             ` Luke Kenneth Casson Leighton
2005-03-14 16:38 ` Karl MacMillan
2005-03-15 11:47   ` KaiGai Kohei
2005-03-15 14:00     ` Karl MacMillan
2005-03-16  4:35       ` Kaigai Kohei
2005-03-16 10:13         ` Luke Kenneth Casson Leighton
2005-03-16 21:46           ` Karl MacMillan
2005-03-16 21:31         ` Karl MacMillan
2005-03-17 13:05           ` Kaigai Kohei
2005-03-17 19:15             ` Karl MacMillan
2005-03-17 20:07               ` Stephen Smalley
2005-03-17 21:41                 ` Karl MacMillan
2005-03-18 13:13                   ` Stephen Smalley
2005-03-18 13:56                     ` Stephen Smalley
2005-03-18 22:28                     ` Karl MacMillan
2005-03-18 23:03                       ` Luke Kenneth Casson Leighton
2005-03-20 23:20                         ` Karl MacMillan
2005-03-21  0:17                           ` Luke Kenneth Casson Leighton
2005-03-21 13:39                             ` Karl MacMillan
2005-03-22  0:14                               ` Luke Kenneth Casson Leighton
2005-03-22 13:53                                 ` Karl MacMillan
2005-03-24 11:04                                   ` Luke Kenneth Casson Leighton
2005-03-24 12:31                                     ` Kaigai Kohei
2005-03-24 22:19                                       ` Luke Kenneth Casson Leighton
2005-03-24 22:27                                     ` Luke Kenneth Casson Leighton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=423E9CFF.3080808@kaigai.gr.jp \
    --to=kaigai@kaigai.gr.jp \
    --cc=kaigai@ak.jp.nec.com \
    --cc=sds@tycho.nsa.gov \
    --cc=selinux@tycho.nsa.gov \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.