[libsepol] export expand_module_avrules

Daniel J Walsh dwalsh at fedoraproject.org
Thu Sep 1 21:08:17 UTC 2011


commit 3c75a3b3ff38c6f906de791fc842818d5008a5e6
Author: Dan Walsh <dwalsh at redhat.com>
Date:   Thu Sep 1 17:07:56 2011 -0400

    export expand_module_avrules

 libsepol-rhat.patch |  375 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 libsepol.spec       |    5 +-
 2 files changed, 374 insertions(+), 6 deletions(-)
---
diff --git a/libsepol-rhat.patch b/libsepol-rhat.patch
index 5066c22..5f397e3 100644
--- a/libsepol-rhat.patch
+++ b/libsepol-rhat.patch
@@ -1,8 +1,373 @@
+diff --git a/libsepol/include/sepol/policydb/conditional.h b/libsepol/include/sepol/policydb/conditional.h
+index a8ed694..1fd1638 100644
+--- a/libsepol/include/sepol/policydb/conditional.h
++++ b/libsepol/include/sepol/policydb/conditional.h
+@@ -77,15 +77,16 @@ typedef struct cond_node {
+ 	/* these true/false lists point into te_avtab when that is used */
+ 	cond_av_list_t *true_list;
+ 	cond_av_list_t *false_list;
+-	/* and these are using during parsing and for modules */
++	/* and these are used during parsing and for modules */
+ 	avrule_t *avtrue_list;
+ 	avrule_t *avfalse_list;
+ 	/* these fields are not written to binary policy */
+ 	unsigned int nbools;
+ 	uint32_t bool_ids[COND_MAX_BOOLS];
+ 	uint32_t expr_pre_comp;
+-	/*                                               */
+ 	struct cond_node *next;
++#define	COND_NODE_FLAGS_TUNABLE	0x01	/* a tunable conditional */
++	uint32_t flags;
+ } cond_node_t;
+ 
+ extern int cond_evaluate_expr(policydb_t * p, cond_expr_t * expr);
+diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h
+index 5320bc8..1848a7b 100644
+--- a/libsepol/include/sepol/policydb/policydb.h
++++ b/libsepol/include/sepol/policydb/policydb.h
+@@ -210,6 +210,8 @@ typedef struct range_trans {
+ typedef struct cond_bool_datum {
+ 	symtab_datum_t s;
+ 	int state;
++#define COND_BOOL_FLAGS_TUNABLE	0x01	/* is this a tunable? */
++	uint32_t flags;
+ } cond_bool_datum_t;
+ 
+ struct cond_node;
+@@ -683,9 +685,10 @@ extern int policydb_set_target_platform(policydb_t *p, int platform);
+ #define MOD_POLICYDB_VERSION_FILENAME_TRANS	11
+ #define MOD_POLICYDB_VERSION_ROLETRANS		12
+ #define MOD_POLICYDB_VERSION_ROLEATTRIB		13
++#define MOD_POLICYDB_VERSION_TUNABLE_SEP	14
+ 
+ #define MOD_POLICYDB_VERSION_MIN MOD_POLICYDB_VERSION_BASE
+-#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_ROLEATTRIB
++#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_TUNABLE_SEP
+ 
+ #define POLICYDB_CONFIG_MLS    1
+ 
+diff --git a/libsepol/src/conditional.c b/libsepol/src/conditional.c
+index 1482387..ea47cdd 100644
+--- a/libsepol/src/conditional.c
++++ b/libsepol/src/conditional.c
+@@ -160,6 +160,7 @@ cond_node_t *cond_node_create(policydb_t * p, cond_node_t * node)
+ 		for (i = 0; i < min(node->nbools, COND_MAX_BOOLS); i++)
+ 			new_node->bool_ids[i] = node->bool_ids[i];
+ 		new_node->expr_pre_comp = node->expr_pre_comp;
++		new_node->flags = node->flags;
+ 	}
+ 
+ 	return new_node;
+@@ -563,8 +564,8 @@ static int bool_isvalid(cond_bool_datum_t * b)
+ 	return 1;
+ }
+ 
+-int cond_read_bool(policydb_t * p
+-		   __attribute__ ((unused)), hashtab_t h,
++int cond_read_bool(policydb_t * p,
++		   hashtab_t h,
+ 		   struct policy_file *fp)
+ {
+ 	char *key = 0;
+@@ -596,6 +597,15 @@ int cond_read_bool(policydb_t * p
+ 	if (rc < 0)
+ 		goto err;
+ 	key[len] = 0;
++
++	if (p->policy_type != POLICY_KERN &&
++	    p->policyvers >= MOD_POLICYDB_VERSION_TUNABLE_SEP) {
++		rc = next_entry(buf, fp, sizeof(uint32_t));
++		if (rc < 0)
++			goto err;
++		booldatum->flags = le32_to_cpu(buf[0]);
++	}
++
+ 	if (hashtab_insert(h, key, booldatum))
+ 		goto err;
+ 
+@@ -810,6 +820,14 @@ static int cond_read_node(policydb_t * p, cond_node_t * node, void *fp)
+ 			goto err;
+ 	}
+ 
++	if (p->policy_type != POLICY_KERN &&
++	    p->policyvers >= MOD_POLICYDB_VERSION_TUNABLE_SEP) {
++		rc = next_entry(buf, fp, sizeof(uint32_t));
++		if (rc < 0)
++			goto err;
++		node->flags = le32_to_cpu(buf[0]);
++	}
++
+ 	return 0;
+       err:
+ 	cond_node_destroy(node);
+diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
+index 06f11f4..4458de6 100644
+--- a/libsepol/src/expand.c
++++ b/libsepol/src/expand.c
+@@ -1014,6 +1014,11 @@ static int bool_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
+ 		return 0;
+ 	}
+ 
++	if (bool->flags & COND_BOOL_FLAGS_TUNABLE) {
++		/* Skip tunables */
++		return 0;
++	}
++
+ 	if (state->verbose)
+ 		INFO(state->handle, "copying boolean %s", id);
+ 
+@@ -1046,6 +1051,7 @@ static int bool_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
+ 	state->boolmap[bool->s.value - 1] = new_bool->s.value;
+ 
+ 	new_bool->state = bool->state;
++	new_bool->flags = bool->flags;
+ 
+ 	return 0;
+ }
+@@ -1940,6 +1946,13 @@ static int cond_node_copy(expand_state_t * state, cond_node_t * cn)
+ 	if (cond_node_copy(state, cn->next)) {
+ 		return -1;
+ 	}
++
++	/* If current cond_node_t is of tunable, its effective branch
++	 * has been appended to its home decl->avrules list during link
++	 * and now we should just skip it. */
++	if (cn->flags & COND_NODE_FLAGS_TUNABLE)
++		return 0;
++
+ 	if (cond_normalize_expr(state->base, cn)) {
+ 		ERR(state->handle, "Error while normalizing conditional");
+ 		return -1;
+diff --git a/libsepol/src/libsepol.map b/libsepol/src/libsepol.map
+index 719e5b7..4044977 100644
+--- a/libsepol/src/libsepol.map
++++ b/libsepol/src/libsepol.map
+@@ -1,5 +1,6 @@
+ {
+   global: 
++	expand_module_avrules;
+ 	sepol_module_package_*; sepol_link_modules; sepol_expand_module; sepol_link_packages;
+ 	sepol_bool_*; sepol_genbools*; 
+ 	sepol_context_*; sepol_mls_*; sepol_check_context;
+diff --git a/libsepol/src/link.c b/libsepol/src/link.c
+index 421c47b..4b0fd16 100644
+--- a/libsepol/src/link.c
++++ b/libsepol/src/link.c
+@@ -587,7 +587,17 @@ static int bool_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
+ 		}
+ 		state->base->p_bools.nprim++;
+ 		base_bool = new_bool;
+-
++		base_bool->flags = booldatum->flags;
++	} else if ((booldatum->flags & COND_BOOL_FLAGS_TUNABLE) !=
++		   (base_bool->flags & COND_BOOL_FLAGS_TUNABLE)) {
++			/* A mismatch between boolean/tunable declaration
++			 * and usage(for example, a boolean used in the
++			 * tunable_policy macro), then the tunables would
++			 * be filtered out and only the effective branch
++			 * of the cond_node would be preserved. */
++			INFO(state->handle,
++			     "%s: Mismatch between boolean/tunable definition "
++			     "and usage for %s", state->cur_mod_name, id);
+ 	}
+ 
+ 	/* Get the scope info for this boolean to see if this is the declaration, 
+@@ -595,9 +605,12 @@ static int bool_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
+ 	scope = hashtab_search(state->cur->policy->p_bools_scope.table, id);
+ 	if (!scope)
+ 		return SEPOL_ERR;
+-	if (scope->scope == SCOPE_DECL)  
++	if (scope->scope == SCOPE_DECL) {
+ 		base_bool->state = booldatum->state;
+-
++		/* Only the declaration rather than requirement
++		 * decides if it is a boolean or tunable. */
++		base_bool->state = booldatum->state;
++	}
+ 	state->cur->map[SYM_BOOLS][booldatum->s.value - 1] = base_bool->s.value;
+ 	return 0;
+ 
+@@ -2451,6 +2464,92 @@ static int populate_roleattributes(link_state_t *state, policydb_t *pol)
+ 	return 0;
+ }
+ 
++static void separate_tunables(link_state_t *state, policydb_t *pol)
++{
++	avrule_block_t *block;
++	avrule_decl_t *decl;
++	cond_node_t *cur_node;
++	cond_expr_t *cur_expr;
++	int cur_state;
++	avrule_t *tail, *to_be_appended;
++
++	if (state->verbose)
++		INFO(state->handle, "Separating tunables from booleans.");
++
++	/* Iterate through all cond_node of all enabled decls, if a cond_node
++	 * is about tunable, caculate its state value and concatenate one of
++	 * its avrule list to the current decl->avrules list.
++	 *
++	 * Note, such tunable cond_node would be skipped over in expansion,
++	 * so we won't have to worry about removing it from decl->cond_list
++	 * here :-)
++	 *
++	 * If tunables and booleans co-exist in the expression of a cond_node,
++	 * then tunables would be "transformed" as booleans.
++	 */
++	for (block = pol->global; block != NULL; block = block->next) {
++		decl = block->enabled;
++		if (decl == NULL || decl->enabled == 0)
++			continue;
++
++		tail = decl->avrules;
++		while (tail && tail->next)
++			tail = tail->next;
++
++		for (cur_node = decl->cond_list; cur_node != NULL;
++		     cur_node = cur_node->next) {
++			int booleans, tunables, i;
++			cond_bool_datum_t *booldatum;
++			cond_bool_datum_t *tmp[COND_EXPR_MAXDEPTH];
++
++			booleans = tunables = 0;
++			memset(tmp, 0, sizeof(cond_bool_datum_t *) * COND_EXPR_MAXDEPTH);
++
++			for (cur_expr = cur_node->expr; cur_expr != NULL;
++			     cur_expr = cur_expr->next) {
++				if (cur_expr->expr_type != COND_BOOL)
++					continue;
++				booldatum = pol->bool_val_to_struct[cur_expr->bool - 1];
++				if (booldatum->flags & COND_BOOL_FLAGS_TUNABLE)
++					tmp[tunables++] = booldatum;
++				else
++					booleans++;
++			}
++
++			if (tunables && booleans) {
++				/* Tunable mixed with boolean */
++				for (i = 0; i < tunables; i++)
++					tmp[i]->flags &= ~COND_BOOL_FLAGS_TUNABLE;
++			} else if (tunables && !booleans) {
++				/* Pure tunable conditional */
++				cur_node->flags |= COND_NODE_FLAGS_TUNABLE;
++				cur_state = cond_evaluate_expr(pol, cur_node->expr);
++				if (cur_state == -1) {
++					printf("Expression result was "
++						"undefined, skipping all"
++						"rules\n");
++					continue;
++				}
++
++				to_be_appended = (cur_state == 1) ?
++					cur_node->avtrue_list : cur_node->avfalse_list;
++
++				if (tail)
++					tail->next = to_be_appended;
++				else
++					tail = decl->avrules = to_be_appended;
++
++				/* Update the tail of decl->avrules for
++				 * further concatenation */
++				while (tail && tail->next)
++					tail = tail->next;
++
++				cur_node->avtrue_list = cur_node->avfalse_list = NULL;
++			}
++		}
++	}
++}
++
+ /* 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
+@@ -2587,6 +2686,11 @@ int link_modules(sepol_handle_t * handle,
+ 			&state))
+ 		goto cleanup;
+ 
++	/* Append tunable's avtrue_list or avfalse_list to the avrules list
++	 * of its home decl depending on its state value, so that the effect
++	 * rules of a tunable would be added to te_avtab permanently. */
++	separate_tunables(&state, state.base);
++
+ 	retval = 0;
+       cleanup:
+ 	for (i = 0; modules != NULL && i < len; i++) {
+diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
+index 017aeca..136b450 100644
+--- a/libsepol/src/policydb.c
++++ b/libsepol/src/policydb.c
+@@ -221,6 +221,13 @@ static struct policydb_compat_info policydb_compat[] = {
+ 	 .target_platform = SEPOL_TARGET_SELINUX,
+ 	},
+ 	{
++	 .type = POLICY_BASE,
++	 .version = MOD_POLICYDB_VERSION_TUNABLE_SEP,
++	 .sym_num = SYM_NUM,
++	 .ocon_num = OCON_NODE6 + 1,
++	 .target_platform = SEPOL_TARGET_SELINUX,
++	},
++	{
+ 	 .type = POLICY_MOD,
+ 	 .version = MOD_POLICYDB_VERSION_BASE,
+ 	 .sym_num = SYM_NUM,
+@@ -290,6 +297,13 @@ static struct policydb_compat_info policydb_compat[] = {
+ 	 .ocon_num = 0,
+ 	 .target_platform = SEPOL_TARGET_SELINUX,
+ 	},
++	{
++	 .type = POLICY_MOD,
++	 .version = MOD_POLICYDB_VERSION_TUNABLE_SEP,
++	 .sym_num = SYM_NUM,
++	 .ocon_num = 0,
++	 .target_platform = SEPOL_TARGET_SELINUX,
++	},
+ };
+ 
+ #if 0
 diff --git a/libsepol/src/write.c b/libsepol/src/write.c
-index 290e036..7257b0b 100644
+index 290e036..e34ab52 100644
 --- a/libsepol/src/write.c
 +++ b/libsepol/src/write.c
-@@ -972,6 +972,19 @@ static int role_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr)
+@@ -607,6 +607,7 @@ static int cond_write_bool(hashtab_key_t key, hashtab_datum_t datum, void *ptr)
+ 	unsigned int items, items2;
+ 	struct policy_data *pd = ptr;
+ 	struct policy_file *fp = pd->fp;
++	struct policydb *p = pd->p;
+ 
+ 	booldatum = (cond_bool_datum_t *) datum;
+ 
+@@ -621,6 +622,15 @@ static int cond_write_bool(hashtab_key_t key, hashtab_datum_t datum, void *ptr)
+ 	items = put_entry(key, 1, len, fp);
+ 	if (items != len)
+ 		return POLICYDB_ERROR;
++
++	if (p->policy_type != POLICY_KERN &&
++	    p->policyvers >= MOD_POLICYDB_VERSION_TUNABLE_SEP) {
++		buf[0] = cpu_to_le32(booldatum->flags);
++		items = put_entry(buf, sizeof(uint32_t), 1, fp);
++		if (items != 1)
++			return POLICYDB_ERROR;
++	}
++
+ 	return POLICYDB_SUCCESS;
+ }
+ 
+@@ -727,6 +737,14 @@ static int cond_write_node(policydb_t * p,
+ 			return POLICYDB_ERROR;
+ 	}
+ 
++	if (p->policy_type != POLICY_KERN &&
++	    p->policyvers >= MOD_POLICYDB_VERSION_TUNABLE_SEP) {
++		buf[0] = cpu_to_le32(node->flags);
++		items = put_entry(buf, sizeof(uint32_t), 1, fp);
++		if (items != 1)
++			return POLICYDB_ERROR;
++	}
++
+ 	return POLICYDB_SUCCESS;
+ }
+ 
+@@ -972,6 +990,19 @@ static int role_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr)
  
  	role = (role_datum_t *) datum;
  
@@ -22,7 +387,7 @@ index 290e036..7257b0b 100644
  	len = strlen(key);
  	items = 0;
  	buf[items++] = cpu_to_le32(len);
-@@ -1795,6 +1808,19 @@ static int type_attr_uncount(hashtab_key_t key __attribute__ ((unused)),
+@@ -1795,6 +1826,19 @@ static int type_attr_uncount(hashtab_key_t key __attribute__ ((unused)),
  	return 0;
  }
  
@@ -42,7 +407,7 @@ index 290e036..7257b0b 100644
  /*
   * Write the configuration data in a policy database
   * structure to a policy database binary representation
-@@ -1926,7 +1952,7 @@ int policydb_write(policydb_t * p, struct policy_file *fp)
+@@ -1926,7 +1970,7 @@ int policydb_write(policydb_t * p, struct policy_file *fp)
  	num_syms = info->sym_num;
  	for (i = 0; i < num_syms; i++) {
  		buf[0] = cpu_to_le32(p->symtab[i].nprim);
@@ -51,7 +416,7 @@ index 290e036..7257b0b 100644
  
  		/*
  		 * A special case when writing type/attribute symbol table.
-@@ -1939,6 +1965,20 @@ int policydb_write(policydb_t * p, struct policy_file *fp)
+@@ -1939,6 +1983,20 @@ int policydb_write(policydb_t * p, struct policy_file *fp)
  		    p->policy_type == POLICY_KERN) {
  			hashtab_map(p->symtab[i].table, type_attr_uncount, &buf[1]);
  		}
diff --git a/libsepol.spec b/libsepol.spec
index af99025..c138128 100644
--- a/libsepol.spec
+++ b/libsepol.spec
@@ -1,7 +1,7 @@
 Summary: SELinux binary policy manipulation library 
 Name: libsepol
 Version: 2.1.2
-Release: 1%{?dist}
+Release: 2%{?dist}
 License: LGPLv2+
 Group: System Environment/Libraries
 Source: http://www.nsa.gov/selinux/archives/libsepol-%{version}.tgz
@@ -98,6 +98,9 @@ exit 0
 /%{_lib}/libsepol.so.1
 
 %changelog
+* Thu Sep 1 2011 Dan Walsh <dwalsh at redhat.com> - 2.1.2-2
+- export expand_module_avrules 
+
 * Thu Aug 18 2011 Dan Walsh <dwalsh at redhat.com> - 2.1.2-0
 - Update to upstream 
 	* Only call role_fix_callback for base.p_roles during expansion.


More information about the scm-commits mailing list