All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kaigai Kohei <kaigai@ak.jp.nec.com>
To: Stephen Smalley <sds@tycho.nsa.gov>
Cc: KaiGai Kohei <kaigai@kaigai.gr.jp>,
	SELinux Mail List <selinux@tycho.nsa.gov>
Subject: Re: [RFC & PATCH] inherited type definition.
Date: Wed, 23 Mar 2005 17:17:57 +0900	[thread overview]
Message-ID: <42412635.4030108@ak.jp.nec.com> (raw)
In-Reply-To: <1111420782.13101.16.camel@moss-spartans.epoch.ncsc.mil>

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

Hi,

The attached (3rd) patch implements TYPEEXTENDS statement in addition
to the latest patch. Because TYPE ... EXTENDS statements can not handle
forwarding loopup, TYPEEXTENDS statement is necessary to represent
inheritance-relationship not to depend on the definition placement.

TYPEEXTENDS <type-name> EXTENDS <type/attr>, <type/attr>, ... ;

(*) <type-name> and <type/attr> must have been defined.
This is almost the same as TYPEATTRIBUTE.


> Thanks for this revised patch.  I think at this point we need some
> concrete examples of how this new language extension can be applied to
> solve real problems in a manner that is superior to the use of macros
> (or alternatively, if the language supported them, templates of some
> kind).  That will help us determine whether this language extension is
> justified.

I tried to modify the Fedora-C3's strict policy for quick testing,
and represent a unified file type of HTTPd/Samba/FTPd.

I intend to access /var/www/ftp via HTTP and FTP, /var/www/samba via HTTP and Samba.
The following configuration was necessary for this purpose.

BTW, since any macros (such as apache) were so complex for me, the following
configuration may be insufficiency in a precise sense.
But it's easily understandable as a configuration sample for real application,
I think.

Thanks,

o samba.te was modified as follows:

--- policy.orig/domains/program/samba.te        2005-03-23 03:52:39.000000000 -0500
+++ policy.kaigai/domains/program/samba.te      2005-03-23 04:04:45.000000000 -0500
@@ -75,6 +75,8 @@

 # Access Samba shares.
-allow smbd_t samba_share_t:dir create_dir_perms;
-allow smbd_t samba_share_t:file create_file_perms;
+attribute samba_share_path;
+allow smbd_t samba_share_path:dir {getattr search};
+allow smbd_t @samba_share_t:dir create_dir_perms;
+allow smbd_t @samba_share_t:file create_file_perms;

 ifdef(`logrotate.te', `


o apache_macros.te was modified as follows:

--- policy.orig/macros/program/apache_macros.te 2005-03-23 03:52:39.000000000 -0500
+++ policy.kaigai/macros/program/apache_macros.te       2005-03-23 03:39:57.000000000 -0500
@@ -172,9 +172,9 @@
 # Allow the web server to run scripts and serve pages
 ##############################################################
-r_dir_file(httpd_t, httpd_$1_content_t)
+r_dir_file(httpd_t, @httpd_$1_content_t)

-allow httpd_t httpd_$1_htaccess_t: file r_file_perms;
+allow httpd_t @httpd_$1_htaccess_t: file r_file_perms;

-r_dir_file(httpd_t, httpd_$1_script_rw_t)
+r_dir_file(httpd_t, @httpd_$1_script_rw_t)

 ############################################

o ftpd.te was modified as follows:

--- policy.orig/domains/program/ftpd.te 2005-03-23 03:52:38.000000000 -0500
+++ policy.kaigai/domains/program/ftpd.te       2005-03-23 04:03:11.000000000 -0500
@@ -105,2 +105,9 @@
 ')dnl end if nfs_home_dirs
 dontaudit ftpd_t selinux_config_t:dir { search };
+
+attribute ftp_content_path;
+type ftp_content_t alias ftpd_anon_t extends ftp_content_path;
+allow ftpd_t @ftp_content_path:dir {getattr search};
+r_dir_file(ftpd_t, @ftp_content_t);
+file_type_auto_trans(ftpd_t, @ftp_content_t, ftp_content_t)
+

o And, private additional configuration is as follows:
--- /dev/null   2005-03-22 18:46:01.562514976 -0500
+++ policy.kaigai/inaddition.te 2005-03-23 04:06:49.576548144 -0500
@@ -0,0 +1,7 @@
+# necessity for access path
+typeattribute var_t ftp_content_path, samba_share_path;
+typeattribute httpd_sys_content_t ftp_content_path, samba_share_path;
+# definition of unified file type
+type httpd_ftp_t extends httpd_sys_content_t, ftp_content_t;
+type httpd_samba_t extends httpd_sys_content_t, samba_share_t;

o File labeling
/var                        system_u:object_r:var_t
/var/www                    system_u:object_r:httpd_sys_content_t
/var/www/ftp                system_u:object_r:httpd_ftp_t
/var/www/ftp/index.html     system_u:object_r:httpd_ftp_t
/var/www/samba              system_u:object_r:httpd_samba_t
/var/www/samba/index.html   system_u:object_r:httpd_samba_t


-- 
Linux Promotion Center, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>

[-- Attachment #2: checkpolicy-1.22-type_extends.3rd.patch --]
[-- Type: text/plain, Size: 24872 bytes --]

--- checkpolicy-1.22/checkpolicy.h	2005-01-27 04:16:20.000000000 +0900
+++ checkpolicy-1.22.extends.3rd/checkpolicy.h	2005-03-23 08:31:03.000000000 +0900
@@ -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-27 04:16:20.000000000 +0900
+++ checkpolicy-1.22.extends.3rd/checkpolicy.c	2005-03-23 08:31:03.000000000 +0900
@@ -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 23:59:23.000000000 +0900
+++ checkpolicy-1.22.extends.3rd/policy_scan.l	2005-03-23 08:31:47.000000000 +0900
@@ -68,6 +68,8 @@ TYPEALIAS |
 typealias			{ return(TYPEALIAS); }
 TYPEATTRIBUTE |
 typeattribute			{ return(TYPEATTRIBUTE); }
+TYPEEXTENDS |
+typeextends			{ return(TYPEEXTENDS); }
 TYPE |
 type				{ return(TYPE); }
 BOOL |
@@ -78,6 +80,8 @@ ELSE |
 else				{ return(ELSE); }
 ALIAS |
 alias				{ return(ALIAS); }
+EXTENDS |
+extends				{ return(EXTENDS); }
 ATTRIBUTE |
 attribute			{ return(ATTRIBUTE); }
 TYPE_TRANSITION |
@@ -211,7 +215,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 23:59:23.000000000 +0900
+++ checkpolicy-1.22.extends.3rd/policy_parse.y	2005-03-23 09:11:42.000000000 +0900
@@ -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 */
 
 %{
@@ -72,8 +77,8 @@ static int define_category(void);
 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_typeattribute(int extends);
+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);
@@ -130,9 +135,11 @@ static int define_ipv6_node_context(void
 %token ROLES
 %token TYPEALIAS
 %token TYPEATTRIBUTE
+%token TYPEEXTENDS
 %token TYPE
 %token TYPES
 %token ALIAS
+%token EXTENDS
 %token ATTRIBUTE
 %token BOOL
 %token IF
@@ -287,6 +294,7 @@ te_decl			: attribute_def
                         | type_def
                         | typealias_def
                         | typeattribute_def
+			| typeextends_def
                         | bool_def
                         | transition_def
                         | range_trans_def
@@ -297,19 +305,28 @@ 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;}
 			;
 typeattribute_def	: TYPEATTRIBUTE identifier id_comma_list ';'
-			{if (define_typeattribute()) return -1;}
+			{if (define_typeattribute(0)) return -1;}
+			;
+typeextends_def		: TYPEEXTENDS identifier EXTENDS id_comma_list ';'
+			{if (define_typeattribute(1)) return -1;}
 			;
 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 +528,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 +549,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 +712,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 +741,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 +773,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; }
@@ -1543,10 +1582,35 @@ static int define_typealias(void)
 	return 0;
 }
 
-static int define_typeattribute(void)
+static int check_loop_inheritance(type_datum_t *td, int parent_typeval)
+{
+	type_datum_t *child;
+	int i;
+
+	/* attribute never have inheritance loop */
+	if (td->isattr)
+		return 0;
+
+	for (i = ebitmap_startbit(&td->types); i < ebitmap_length(&td->types); i++) {
+		if (!ebitmap_get_bit(&td->types, i))
+			continue;
+		if ( parent_typeval - 1 == i )
+			return -1; /* Loop inheritance detected */
+		child = get_type(i+1);
+		if (!child) {
+			yyerror("BUG: unregistered type");
+			return -1;
+		}
+		if (check_loop_inheritance(child, parent_typeval))
+			return -1;
+	}
+	return 0;
+}
+
+static int define_typeattribute(int extends)
 {
 	char *id;
-	type_datum_t *t, *attr;
+	type_datum_t *t, *inherit;
 
 	if (pass == 2) {
 		while ((id = queue_remove(id_queue)))
@@ -1569,16 +1633,17 @@ static int define_typeattribute(void)
 	}
 
 	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);
 			/* treat it as a fatal error */
 			yyerror(errormsg);
 			free(id);
 			return -1;
 		}
 
-		if (!attr->isattr) {
+		if (!extends && !inherit->isattr) {
 			sprintf(errormsg, "%s is a type, not an attribute", id);
 			yyerror(errormsg);
 			free(id);
@@ -1587,7 +1652,12 @@ static int define_typeattribute(void)
 
 		free(id);
 
-		if (ebitmap_set_bit(&attr->types, (t->value - 1), TRUE)) {
+		if (check_loop_inheritance(t, inherit->value)) {
+			yyerror("inheritance loop is detected");
+			return -1;
+		}
+
+		if (ebitmap_set_bit(&inherit->types, (t->value - 1), TRUE)) {
 			yyerror("out of memory");
 			return -1;
 		}
@@ -1596,10 +1666,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 +1747,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 +1779,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 +1788,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 +1830,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 +1861,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 +1879,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 +1937,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 +2077,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 +2484,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 +2505,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 +2520,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 +2609,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 +2679,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 +2702,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 +2717,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 +2809,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 +2822,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 +2932,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 +3147,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 +3572,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 +5008,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-23  8:17 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
2005-03-21 15:59                       ` Stephen Smalley
2005-03-23  8:17                         ` Kaigai Kohei [this message]
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=42412635.4030108@ak.jp.nec.com \
    --to=kaigai@ak.jp.nec.com \
    --cc=kaigai@kaigai.gr.jp \
    --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.