[RFC-v2] libsepol and checkpolicy: make genfs statements valid in modules

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

 



This patch fixes some sorting issues from the previous patch and appears
to work!  This one should be ready for testing, comments, review....

Anyway given a module with:
genfscon proc /paris4444	user_u:role_r:type2_t:s0
genfscon proc /			user_u:role_r:type2_t:s0
genfscon proc /paris333		user_u:role_r:type2_t:s0
genfscon proc /paris1		user_u:role_r:type2_t:s0
genfscon proc /paris22		user_u:role_r:type2_t:s0

genfscon a /22		user_u:role_r:type2_t:s0
genfscon a /1		user_u:role_r:type2_t:s0
genfscon a /333		user_u:role_r:type2_t:s0

genfscon z /1		user_u:role_r:type2_t:s0
genfscon z /333		user_u:role_r:type2_t:s0

And a base policy with:
genfscon proc /par	user_u:role_r:type1_t:s0
genfscon proc /paris	user_u:role_r:type1_t:s0
genfscon proc /pari	user_u:role_r:type1_t:s0


genfscon b /333	user_u:role_r:type1_t:s0
genfscon b /22	user_u:role_r:type1_t:s0
genfscon b /1	user_u:role_r:type1_t:s0


genfscon y /22	user_u:role_r:type1_t:s0
genfscon y /333	user_u:role_r:type1_t:s0
genfscon y /1	user_u:role_r:type1_t:s0

The final linked policy genfs looks like:
Command ('m' for menu):  g
genfs_context: fs=a
	/333                            	0	user_u:role_r:type2_t
	/22                             	0	user_u:role_r:type2_t
	/1                              	0	user_u:role_r:type2_t
genfs_context: fs=b
	/333                            	0	user_u:role_r:type1_t
	/22                             	0	user_u:role_r:type1_t
	/1                              	0	user_u:role_r:type1_t
genfs_context: fs=proc
	/paris4444                      	0	user_u:role_r:type2_t
	/paris333                       	0	user_u:role_r:type2_t
	/paris22                        	0	user_u:role_r:type2_t
	/paris1                         	0	user_u:role_r:type2_t
	/paris                          	0	user_u:role_r:type1_t
	/pari                           	0	user_u:role_r:type1_t
	/par                            	0	user_u:role_r:type1_t
	/                               	0	user_u:role_r:type2_t
genfs_context: fs=y
	/333                            	0	user_u:role_r:type1_t
	/22                             	0	user_u:role_r:type1_t
	/1                              	0	user_u:role_r:type1_t
genfs_context: fs=z
	/333                            	0	user_u:role_r:type2_t
	/1                              	0	user_u:role_r:type2_t

Which looks just great to me.....

-Eric

diff -Naupr libsepol-2.0.26.orig/src/link.c libsepol-2.0.26/src/link.c
--- libsepol-2.0.26.orig/src/link.c	2008-03-27 13:20:03.000000000 -0400
+++ libsepol-2.0.26/src/link.c	2008-05-06 11:01:22.000000000 -0400
@@ -34,6 +34,7 @@
 #include <assert.h>
 
 #include "debug.h"
+#include "context.h"
 
 #undef min
 #define min(a,b) (((a) < (b)) ? (a) : (b))
@@ -864,6 +865,10 @@ static int mls_level_convert(mls_semanti
 	if (!mod->policy->mls)
 		return 0;
 
+	/* Required not declared. */
+	if (!src->sens)
+		return 0;
+
 	assert(mod->map[SYM_LEVELS][src->sens - 1]);
 	dst->sens = mod->map[SYM_LEVELS][src->sens - 1];
 
@@ -2120,6 +2125,183 @@ static int prepare_base(link_state_t * s
 	return 0;
 }
 
+static int context_copy_and_validate(link_state_t *state, context_struct_t *dst, context_struct_t *src)
+{
+	user_datum_t *base_user_datum;
+	role_datum_t *base_role_datum;
+	type_datum_t *base_type_datum;
+	char *key;
+	int ret;
+
+	key = state->cur->policy->p_user_val_to_name[src->user - 1];
+	base_user_datum = hashtab_search(state->base->p_users.table, key);
+	dst->user = base_user_datum->s.value;
+
+	key = state->cur->policy->p_role_val_to_name[src->role - 1];
+	base_role_datum = hashtab_search(state->base->p_roles.table, key);
+	dst->role = base_role_datum->s.value;
+
+	key = state->cur->policy->p_type_val_to_name[src->type - 1];
+	base_type_datum = hashtab_search(state->base->p_types.table, key);
+	dst->type = base_type_datum->s.value;
+
+	ret = mls_context_cpy(dst, src);
+	if (ret)
+		return ret;
+
+	return context_is_valid(state->base, dst);
+}
+
+/* merge 2 genfs sets with the same fstype */
+static int genfs_merge(link_state_t *state, genfs_t *genfs, genfs_t *base_genfs)
+{
+	ocontext_t *con, *next_con, *base_con, *prev;
+	int cmp;
+
+	assert(!strcmp(genfs->fstype, base_genfs->fstype));
+
+
+	for(con = genfs->head; con; con = next_con) {
+		next_con = con->next;
+		base_con = base_genfs->head;
+		if (!base_con) {
+			base_genfs->head = con;
+			continue;
+		}
+		cmp = strcmp(con->u.name, base_con->u.name);
+		if (cmp > 0) {
+			con->next = base_con;
+			base_genfs->head = con;
+			continue;
+		} else if (cmp == 0)
+			goto merge;
+
+		/* walk the list until we either need to insert between base_con
+		 * and base_con->next or bomb cause of double/conflicting */
+		while (base_con->next && (strcmp(con->u.name, base_con->next->u.name) < 0))
+			base_con = base_con->next;
+
+		/* insert between base_con and base_con->next */
+		if (!base_con->next || (strcmp(con->u.name, base_con->next->u.name) > 0)) {
+			con->next = base_con->next;
+			base_con->next = con;
+			continue;
+		}
+
+		/* so now the fstype and the path are the same, so keep digging... */
+		base_con = base_con->next;
+merge:
+		if (!con->v.sclass || !base_con->v.sclass || con->v.sclass == base_con->v.sclass) {
+			ERR(state->handle, "dup genfs entry (%s,%s)", genfs->fstype, con->u.name);
+			/* everything earlier in the list is now associated with
+			 * the base genfs, so we need to leave all of it alone and
+			 * let it get freed naturaly when we tear down the base.
+			 */
+			while (con) {
+				free(con->u.name);
+				prev = con;
+				con = con->next;
+				free(prev);
+			}
+			free(genfs->fstype);
+			free(genfs);
+			return -1;
+		}
+		con->next = base_con->next;
+		base_con->next = con;
+	}
+	/* free these since we are using the genfs and fstype already in the base */
+	free(genfs->fstype);
+	free(genfs);
+	return 0;
+}
+
+/* so this is going to merge genfs info from modules into the base policy */
+static int genfs_context_copy_helper(link_state_t *state)
+{
+	ocontext_t *c, *newc, *l;
+	genfs_t *genfs, *newgenfs, *base_genfs;
+	int cmp;
+
+	for (genfs = state->cur->policy->genfs; genfs; genfs = genfs->next) {
+		/* build a newgenfs, we might free peices and parts
+		 * later if the base already had them */
+		newgenfs = calloc(1, sizeof(genfs_t));
+		if (!newgenfs) {
+			ERR(state->handle, "Out of memory!");
+			return -1;
+		}
+		newgenfs->fstype = strdup(genfs->fstype);
+		if (!newgenfs->fstype) {
+			ERR(state->handle, "Out of memory!");
+			return -1;
+		}
+
+		l = NULL;
+		for (c = genfs->head; c; c = c->next) {
+			newc = calloc(1, sizeof(ocontext_t));
+			if (!newc) {
+				ERR(state->handle, "Out of memory!");
+				return -1;
+			}
+			newc->u.name = strdup(c->u.name);
+			if (!newc->u.name) {
+				ERR(state->handle, "Out of memory!");
+				return -1;
+			}
+			newc->v.sclass = c->v.sclass;
+			context_copy_and_validate(state, &newc->context[0], &c->context[0]);
+
+			if (l)
+				l->next = newc;
+			else
+				newgenfs->head = newc;
+			l = newc;
+		}
+
+		base_genfs = state->base->genfs;
+		/* base had no genfs, insert at front */
+		if (!base_genfs) {
+			state->base->genfs = newgenfs;
+			continue;
+		}
+		/* first base entry is after this entry, insert at front */
+		cmp = strcmp(newgenfs->fstype, base_genfs->fstype);
+		if (cmp < 0) {
+			newgenfs->next = base_genfs;
+			state->base->genfs = newgenfs;
+			continue;
+		} else if (cmp == 0) {
+			/* merge with head of list */
+			int ret = genfs_merge(state, newgenfs, base_genfs);
+			/* genfs_merge freed stuff if it blew up... */
+			if (ret)
+				return ret;
+			continue;
+		}
+		/* move down the list until we either need to be inserted between
+		 * base_genfs and base_genfs->next or we need to merge with
+		 * base_genfs->next */
+		while (base_genfs->next && (strcmp(newgenfs->fstype, base_genfs->next->fstype) > 0))
+			base_genfs = base_genfs->next;
+		/* insert between if appropiete */
+		if (!base_genfs->next || (strcmp(newgenfs->fstype, base_genfs->next->fstype) < 0)) {
+			newgenfs->next = base_genfs->next;
+			base_genfs->next = newgenfs;
+			continue;
+		}
+		/* this is the fun part, merge..... */
+		if (strcmp(newgenfs->fstype, base_genfs->next->fstype) == 0) {
+			int ret = genfs_merge(state, newgenfs, base_genfs->next);
+			/* genfs_merge freed stuff if it blew up... */
+			if (ret)
+				return ret;
+		} else
+			assert(1);
+	}
+	return 0;
+}
+
 /* Link a set of modules into a base module. This process is somewhat
  * similar to an actual compiler: it requires a set of order dependent
  * steps.  The base and every module must have been indexed prior to
@@ -2202,8 +2384,19 @@ int link_modules(sepol_handle_t * handle
 	for (i = 0; i < len; i++) {
 		state.cur = modules[i];
 		state.cur_mod_name = modules[i]->policy->name;
-		ret =
-		    copy_identifiers(&state, modules[i]->policy->symtab, NULL);
+		ret = copy_identifiers(&state, modules[i]->policy->symtab, NULL);
+		if (ret) {
+			retval = ret;
+			goto cleanup;
+		}
+	}
+
+	/* copy genfs_context stuff into base */
+	for (i = 0; i < len; i++) {
+		state.cur = modules[i];
+		state.cur_mod_name = modules[i]->policy->name;
+
+		ret = genfs_context_copy_helper(&state);
 		if (ret) {
 			retval = ret;
 			goto cleanup;
diff -Naupr libsepol-2.0.26.orig/src/policydb.c libsepol-2.0.26/src/policydb.c
--- libsepol-2.0.26.orig/src/policydb.c	2008-03-27 13:20:03.000000000 -0400
+++ libsepol-2.0.26/src/policydb.c	2008-05-05 16:11:26.000000000 -0400
@@ -1564,7 +1564,8 @@ static int mls_range_to_semantic(mls_ran
  * from a policydb binary representation file.
  */
 static int context_read_and_validate(context_struct_t * c,
-				     policydb_t * p, struct policy_file *fp)
+				     policydb_t * p, struct policy_file *fp,
+				     uint32_t validate)
 {
 	uint32_t buf[3];
 	int rc;
@@ -1588,7 +1589,7 @@ static int context_read_and_validate(con
 		}
 	}
 
-	if (!policydb_context_isvalid(p, c)) {
+	if (validate && !policydb_context_isvalid(p, c)) {
 		ERR(fp->handle, "invalid security context");
 		context_destroy(c);
 		return -1;
@@ -2076,7 +2077,7 @@ static int ocontext_read(struct policydb
 					return -1;
 				c->sid[0] = le32_to_cpu(buf[0]);
 				if (context_read_and_validate
-				    (&c->context[0], p, fp))
+				    (&c->context[0], p, fp, 1))
 					return -1;
 				break;
 			case OCON_FS:
@@ -2093,10 +2094,10 @@ static int ocontext_read(struct policydb
 					return -1;
 				c->u.name[len] = 0;
 				if (context_read_and_validate
-				    (&c->context[0], p, fp))
+				    (&c->context[0], p, fp, 1))
 					return -1;
 				if (context_read_and_validate
-				    (&c->context[1], p, fp))
+				    (&c->context[1], p, fp, 1))
 					return -1;
 				break;
 			case OCON_PORT:
@@ -2107,7 +2108,7 @@ static int ocontext_read(struct policydb
 				c->u.port.low_port = le32_to_cpu(buf[1]);
 				c->u.port.high_port = le32_to_cpu(buf[2]);
 				if (context_read_and_validate
-				    (&c->context[0], p, fp))
+				    (&c->context[0], p, fp, 1))
 					return -1;
 				break;
 			case OCON_NODE:
@@ -2117,7 +2118,7 @@ static int ocontext_read(struct policydb
 				c->u.node.addr = le32_to_cpu(buf[0]);
 				c->u.node.mask = le32_to_cpu(buf[1]);
 				if (context_read_and_validate
-				    (&c->context[0], p, fp))
+				    (&c->context[0], p, fp, 1))
 					return -1;
 				break;
 			case OCON_FSUSE:
@@ -2134,7 +2135,7 @@ static int ocontext_read(struct policydb
 					return -1;
 				c->u.name[len] = 0;
 				if (context_read_and_validate
-				    (&c->context[0], p, fp))
+				    (&c->context[0], p, fp, 1))
 					return -1;
 				break;
 			case OCON_NODE6:{
@@ -2151,7 +2152,7 @@ static int ocontext_read(struct policydb
 						c->u.node6.mask[k] =
 						    le32_to_cpu(buf[k + 4]);
 					if (context_read_and_validate
-					    (&c->context[0], p, fp))
+					    (&c->context[0], p, fp, 1))
 						return -1;
 					break;
 				}
@@ -2173,6 +2174,10 @@ static int genfs_read(policydb_t * p, st
 	ocontext_t *l, *c, *newc = NULL;
 	int rc;
 
+	/* don't validate full contexts in modules, will do that at link
+	 * time later */
+	int validate = (p->policy_type != POLICY_MOD);
+
 	rc = next_entry(buf, fp, sizeof(uint32_t));
 	if (rc < 0)
 		goto bad;
@@ -2240,7 +2245,7 @@ static int genfs_read(policydb_t * p, st
 			if (rc < 0)
 				goto bad;
 			newc->v.sclass = le32_to_cpu(buf[0]);
-			if (context_read_and_validate(&newc->context[0], p, fp))
+			if (context_read_and_validate(&newc->context[0], p, fp, validate))
 				goto bad;
 			for (l = NULL, c = newgenfs->head; c;
 			     l = c, c = c->next) {
diff -Naupr checkpolicy-2.0.14.orig/policy_define.c checkpolicy-2.0.14/policy_define.c
--- checkpolicy-2.0.14.orig/policy_define.c	2008-04-14 15:33:41.000000000 -0400
+++ checkpolicy-2.0.14/policy_define.c	2008-05-05 16:19:07.000000000 -0400
@@ -68,7 +68,6 @@ extern int yyerror(char *msg);
 static char errormsg[ERRORMSG_LEN + 1] = {0};
 
 static int id_has_dot(char *id);
-static int parse_security_context(context_struct_t *c);
 
 /* initialize all of the state variables for the scanner/parser */
 void init_parser(int pass_number)
@@ -3008,7 +3007,7 @@ int define_user(void)
 	return 0;
 }
 
-static int parse_security_context(context_struct_t * c)
+static int parse_security_context(context_struct_t * c, uint32_t check_valid)
 {
 	char *id;
 	role_datum_t *role;
@@ -3160,7 +3159,7 @@ static int parse_security_context(contex
 		}
 	}
 
-	if (!policydb_context_isvalid(policydbp, c)) {
+	if (check_valid && !policydb_context_isvalid(policydbp, c)) {
 		yyerror("invalid security context");
 		goto bad;
 	}
@@ -3180,7 +3179,7 @@ int define_initial_sid_context(void)
 	if (pass == 1) {
 		id = (char *)queue_remove(id_queue);
 		free(id);
-		parse_security_context(NULL);
+		parse_security_context(NULL, 1);
 		return 0;
 	}
 
@@ -3208,7 +3207,7 @@ int define_initial_sid_context(void)
 	/* no need to keep the sid name */
 	free(id);
 
-	if (parse_security_context(&c->context[0]))
+	if (parse_security_context(&c->context[0], 1))
 		return -1;
 
 	return 0;
@@ -3219,8 +3218,8 @@ int define_fs_context(unsigned int major
 	ocontext_t *newc, *c, *head;
 
 	if (pass == 1) {
-		parse_security_context(NULL);
-		parse_security_context(NULL);
+		parse_security_context(NULL, 1);
+		parse_security_context(NULL, 1);
 		return 0;
 	}
 
@@ -3239,12 +3238,12 @@ int define_fs_context(unsigned int major
 	}
 	sprintf(newc->u.name, "%02x:%02x", major, minor);
 
-	if (parse_security_context(&newc->context[0])) {
+	if (parse_security_context(&newc->context[0], 1)) {
 		free(newc->u.name);
 		free(newc);
 		return -1;
 	}
-	if (parse_security_context(&newc->context[1])) {
+	if (parse_security_context(&newc->context[1], 1)) {
 		context_destroy(&newc->context[0]);
 		free(newc->u.name);
 		free(newc);
@@ -3279,7 +3278,7 @@ int define_port_context(unsigned int low
 	if (pass == 1) {
 		id = (char *)queue_remove(id_queue);
 		free(id);
-		parse_security_context(NULL);
+		parse_security_context(NULL, 1);
 		return 0;
 	}
 
@@ -3315,7 +3314,7 @@ int define_port_context(unsigned int low
 		return -1;
 	}
 
-	if (parse_security_context(&newc->context[0])) {
+	if (parse_security_context(&newc->context[0], 1)) {
 		free(newc);
 		return -1;
 	}
@@ -3360,8 +3359,8 @@ int define_netif_context(void)
 
 	if (pass == 1) {
 		free(queue_remove(id_queue));
-		parse_security_context(NULL);
-		parse_security_context(NULL);
+		parse_security_context(NULL, 1);
+		parse_security_context(NULL, 1);
 		return 0;
 	}
 
@@ -3377,12 +3376,12 @@ int define_netif_context(void)
 		free(newc);
 		return -1;
 	}
-	if (parse_security_context(&newc->context[0])) {
+	if (parse_security_context(&newc->context[0], 1)) {
 		free(newc->u.name);
 		free(newc);
 		return -1;
 	}
-	if (parse_security_context(&newc->context[1])) {
+	if (parse_security_context(&newc->context[1], 1)) {
 		context_destroy(&newc->context[0]);
 		free(newc->u.name);
 		free(newc);
@@ -3417,7 +3416,7 @@ int define_ipv4_node_context()
 	if (pass == 1) {
 		free(queue_remove(id_queue));
 		free(queue_remove(id_queue));
-		parse_security_context(NULL);
+		parse_security_context(NULL, 1);
 		goto out;
 	}
 
@@ -3464,7 +3463,7 @@ int define_ipv4_node_context()
 	newc->u.node.addr = addr.s_addr;
 	newc->u.node.mask = mask.s_addr;
 
-	if (parse_security_context(&newc->context[0])) {
+	if (parse_security_context(&newc->context[0], 1)) {
 		free(newc);
 		return -1;
 	}
@@ -3498,7 +3497,7 @@ int define_ipv6_node_context(void)
 	if (pass == 1) {
 		free(queue_remove(id_queue));
 		free(queue_remove(id_queue));
-		parse_security_context(NULL);
+		parse_security_context(NULL, 1);
 		goto out;
 	}
 
@@ -3545,7 +3544,7 @@ int define_ipv6_node_context(void)
 	memcpy(&newc->u.node6.addr[0], &addr.s6_addr32[0], 16);
 	memcpy(&newc->u.node6.mask[0], &mask.s6_addr32[0], 16);
 
-	if (parse_security_context(&newc->context[0])) {
+	if (parse_security_context(&newc->context[0], 1)) {
 		free(newc);
 		rc = -1;
 		goto out;
@@ -3577,7 +3576,7 @@ int define_fs_use(int behavior)
 
 	if (pass == 1) {
 		free(queue_remove(id_queue));
-		parse_security_context(NULL);
+		parse_security_context(NULL, 1);
 		return 0;
 	}
 
@@ -3594,7 +3593,7 @@ int define_fs_use(int behavior)
 		return -1;
 	}
 	newc->v.behavior = behavior;
-	if (parse_security_context(&newc->context[0])) {
+	if (parse_security_context(&newc->context[0], 1)) {
 		free(newc->u.name);
 		free(newc);
 		return -1;
@@ -3624,13 +3623,14 @@ int define_genfs_context_helper(char *fs
 	ocontext_t *newc, *c, *head, *p;
 	char *type = NULL;
 	int len, len2;
+	uint32_t check_valid;
 
 	if (pass == 1) {
 		free(fstype);
 		free(queue_remove(id_queue));
 		if (has_type)
 			free(queue_remove(id_queue));
-		parse_security_context(NULL);
+		parse_security_context(NULL, 0);
 		return 0;
 	}
 
@@ -3701,7 +3701,11 @@ int define_genfs_context_helper(char *fs
 			goto fail;
 		}
 	}
-	if (parse_security_context(&newc->context[0]))
+	if (policydbp->policy_type == POLICY_MOD)
+		check_valid = 0;
+	else
+		check_valid = 1;
+	if (parse_security_context(&newc->context[0], check_valid))
 		goto fail;
 
 	head = genfs->head;
diff -Naupr checkpolicy-2.0.14.orig/policy_parse.y checkpolicy-2.0.14/policy_parse.y
--- checkpolicy-2.0.14.orig/policy_parse.y	2008-04-14 15:33:41.000000000 -0400
+++ checkpolicy-2.0.14/policy_parse.y	2008-05-06 09:41:16.000000000 -0400
@@ -612,12 +612,12 @@ fs_use_def              : FSUSEXATTR ide
                         | FSUSETRANS identifier security_context_def ';'
                         {if (define_fs_use(SECURITY_FS_USE_TRANS)) return -1;}
                         ;
-opt_genfs_contexts      : genfs_contexts
-                        |
-                        ;
-genfs_contexts          : genfs_context_def
-                        | genfs_contexts genfs_context_def
-                        ;
+opt_genfs_contexts	: genfs_context_defs
+			| /* empty */
+			;
+genfs_context_defs	: genfs_context_defs genfs_context_def
+			| genfs_context_def
+			;
 genfs_context_def	: GENFSCON identifier path '-' identifier security_context_def
 			{if (define_genfs_context(1)) return -1;}
 			| GENFSCON identifier path '-' '-' {insert_id("-", 0);} security_context_def
@@ -734,6 +734,7 @@ avrule_decl             : rbac_decl
                         | cond_stmt_def
                         | require_block
                         | optional_block
+			| genfs_context_defs
                         | ';'
                         ;
 require_block           : REQUIRE '{' require_list '}'
@@ -775,6 +776,6 @@ optional_decl           : OPTIONAL
 else_decl               : ELSE
                         { if (begin_optional_else(pass) == -1) return -1; }
                         ;
-avrule_user_defs        : user_def avrule_user_defs
-                        | /* empty */
+avrule_user_defs	: user_def avrule_user_defs
+			| /* empty */
                         ;
diff -Naupr checkpolicy-2.0.14.orig/test/dismod.c checkpolicy-2.0.14/test/dismod.c
--- checkpolicy-2.0.14.orig/test/dismod.c	2008-04-14 15:33:41.000000000 -0400
+++ checkpolicy-2.0.14/test/dismod.c	2008-05-06 11:01:31.000000000 -0400
@@ -787,6 +787,32 @@ static void display_policycaps(policydb_
 	}
 }
 
+static void display_context(policydb_t *p, context_struct_t *context, FILE *fp)
+{
+	char *user, *role, *type;
+	user = p->p_user_val_to_name[context->user - 1];
+	role = p->p_role_val_to_name[context->role - 1];
+	type = p->p_type_val_to_name[context->type - 1];
+	fprintf(fp, "%s:%s:%s", user, role, type);
+}
+
+static void display_genfs_context(policydb_t *p, FILE *fp)
+{
+	genfs_t *genfs = p->genfs;
+	ocontext_t *context;
+	while (genfs) {
+		fprintf(fp, "genfs_context: fs=%s\n", genfs->fstype);
+		context = genfs->head;
+		while (context) {
+			fprintf(fp, "\t%-32s\t%d\t", context->u.name, context->v.sclass);
+			display_context(p, &context->context[0], fp);
+			fprintf(fp, "\n");
+			context = context->next;
+		}
+		genfs = genfs->next;
+	}
+}
+
 int menu()
 {
 	printf("\nSelect a command:\n");
@@ -804,6 +830,7 @@ int menu()
 	printf("a)  Display avrule requirements\n");
 	printf("b)  Display avrule declarations\n");
 	printf("c)  Display policy capabilities\n");
+	printf("g)  Display genfs_context entries\n");
 	printf("l)  Link in a module\n");
 	printf("u)  Display the unknown handling setting\n");
 	printf("\n");
@@ -936,6 +963,10 @@ int main(int argc, char **argv)
 			if (out_fp != stdout)
 				printf("\nOutput to file: %s\n", OutfileName);
 			break;
+		case 'g':
+		case 'G':
+			display_genfs_context(&policydb, out_fp);
+			break;
 		case 'l':
 			link_module(&policydb, out_fp);
 			break;
diff -Naupr checkpolicy-2.0.14.orig/test/dispol.c checkpolicy-2.0.14/test/dispol.c
--- checkpolicy-2.0.14.orig/test/dispol.c	2008-04-14 15:33:41.000000000 -0400
+++ checkpolicy-2.0.14/test/dispol.c	2008-04-30 16:24:08.000000000 -0400
@@ -319,6 +319,31 @@ static void display_policycaps(policydb_
 	}
 }
 
+static void display_context(policydb_t *p, context_struct_t *context, FILE *fp)
+{
+	char *user, *role, *type;
+	user = p->p_user_val_to_name[context->user - 1];
+	role = p->p_role_val_to_name[context->role - 1];
+	type = p->p_type_val_to_name[context->type - 1];
+	fprintf(fp, "%s:%s:%s\n", user, role, type);
+}
+static void display_genfs_context(policydb_t *p, FILE *fp)
+{
+	genfs_t *genfs = p->genfs;
+	ocontext_t *context;
+	while (genfs) {
+		fprintf(fp, "genfs_context: fs=%s\n", genfs->fstype);
+		context = genfs->head;
+		while (context) {
+			fprintf(fp, "\t%s%16d\t", context->u.name, context->v.sclass);
+			display_context(p, &context->context[0], fp);
+			fprintf(fp, "\n");
+			context = context->next;
+		}
+		genfs = genfs->next;
+	}
+}
+
 static void display_id(policydb_t *p, FILE *fp, uint32_t symbol_type,
 		       uint32_t symbol_value, char *prefix)
 {
@@ -353,6 +378,7 @@ int menu()
 	printf("7)  change a boolean value\n");
 	printf("\n");
 	printf("c)  display policy capabilities\n");
+	printf("g)  display all genfs_context entries\n");
 	printf("p)  display the list of permissive types\n");
 	printf("u)  display unknown handling setting\n");
 	printf("f)  set output file\n");
@@ -470,6 +496,9 @@ int main(int argc, char **argv)
 		case 'c':
 			display_policycaps(&policydb, out_fp);
 			break;
+		case 'g':
+			display_genfs_context(&policydb, out_fp);
+			break;
 		case 'p':
 			display_permissive(&policydb, out_fp);
 			break;

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

  Powered by Linux