[libsepol] Add patch to handle preserving tunables

Daniel J Walsh dwalsh at fedoraproject.org
Thu Sep 15 02:40:40 UTC 2011


commit ed26f06a290544694de78ecff6fe6706719a3c01
Author: Dan Walsh <dwalsh at redhat.com>
Date:   Wed Sep 14 22:40:27 2011 -0400

    Add patch to handle preserving tunables

 libsepol-rhat.patch |  254 ++++++++++++++++++++++++++++++++++-----------------
 libsepol.spec       |    5 +-
 2 files changed, 174 insertions(+), 85 deletions(-)
---
diff --git a/libsepol-rhat.patch b/libsepol-rhat.patch
index 5f397e3..6ae1159 100644
--- a/libsepol-rhat.patch
+++ b/libsepol-rhat.patch
@@ -1,8 +1,24 @@
+diff --git a/libsepol/include/sepol/handle.h b/libsepol/include/sepol/handle.h
+index 19be326..115bda1 100644
+--- a/libsepol/include/sepol/handle.h
++++ b/libsepol/include/sepol/handle.h
+@@ -24,4 +24,11 @@ void sepol_set_expand_consume_base(sepol_handle_t * sh, int consume_base);
+ /* Destroy a sepol handle. */
+ void sepol_handle_destroy(sepol_handle_t *);
+ 
++/* Get whether or not needless unused branch of tunables would be preserved */
++int sepol_get_preserve_tunables(sepol_handle_t * sh);
++
++/* Set whether or not to preserve the needless unused branch of tunables,
++ * 0 is default and discard such branch, 1 preserves them */
++void sepol_set_preserve_tunables(sepol_handle_t * sh, int preserve_tunables);
++
+ #endif
 diff --git a/libsepol/include/sepol/policydb/conditional.h b/libsepol/include/sepol/policydb/conditional.h
-index a8ed694..1fd1638 100644
+index a8ed694..48ec106 100644
 --- a/libsepol/include/sepol/policydb/conditional.h
 +++ b/libsepol/include/sepol/policydb/conditional.h
-@@ -77,15 +77,16 @@ typedef struct cond_node {
+@@ -77,15 +77,17 @@ 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;
@@ -16,7 +32,8 @@ index a8ed694..1fd1638 100644
  	uint32_t expr_pre_comp;
 -	/*                                               */
  	struct cond_node *next;
-+#define	COND_NODE_FLAGS_TUNABLE	0x01	/* a tunable conditional */
++	/* a tunable conditional, calculated and used at expansion */
++#define	COND_NODE_FLAGS_TUNABLE	0x01
 +	uint32_t flags;
  } cond_node_t;
  
@@ -101,7 +118,7 @@ index 1482387..ea47cdd 100644
        err:
  	cond_node_destroy(node);
 diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
-index 06f11f4..4458de6 100644
+index 06f11f4..2861776 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,
@@ -138,81 +155,33 @@ index 06f11f4..4458de6 100644
  	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;
+@@ -2665,6 +2678,106 @@ int expand_module_avrules(sepol_handle_t * handle, policydb_t * base,
+ 	return copy_and_expand_avrule_block(&state);
  }
  
-+static void separate_tunables(link_state_t *state, policydb_t *pol)
++static void discard_tunables(sepol_handle_t *sh, policydb_t *pol)
 +{
 +	avrule_block_t *block;
 +	avrule_decl_t *decl;
 +	cond_node_t *cur_node;
 +	cond_expr_t *cur_expr;
-+	int cur_state;
++	int cur_state, preserve_tunables = 0;
 +	avrule_t *tail, *to_be_appended;
 +
-+	if (state->verbose)
-+		INFO(state->handle, "Separating tunables from booleans.");
++	if (sh && sh->preserve_tunables)
++		preserve_tunables = 1;
 +
 +	/* 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.
++	 * is about tunable, calculate its state value and concatenate one of
++	 * its avrule list to the current decl->avrules list. On the other
++	 * hand, the disabled unused branch of a tunable would be discarded.
 +	 *
 +	 * 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.
++	 * If tunables are requested to be preserved then they would be
++	 * "transformed" as booleans by having their TUNABLE flag cleared.
 +	 */
 +	for (block = pol->global; block != NULL; block = block->next) {
 +		decl = block->enabled;
@@ -243,18 +212,26 @@ index 421c47b..4b0fd16 100644
 +					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 */
++			/* bool_copy_callback() at link phase has ensured
++			 * that no mixture of tunables and booleans in one
++			 * expression. However, this would be broken by the
++			 * request to preserve tunables */
++			if (!preserve_tunables)
++				assert(!(booleans && tunables));
++
++			if (booleans || preserve_tunables) {
++				cur_node->flags &= ~COND_NODE_FLAGS_TUNABLE;
++				if (tunables) {
++					for (i = 0; i < tunables; i++)
++						tmp[i]->flags &= ~COND_BOOL_FLAGS_TUNABLE;
++				}
++			} else {
 +				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");
++					       "undefined, skipping all"
++					       "rules\n");
 +					continue;
 +				}
 +
@@ -266,32 +243,141 @@ index 421c47b..4b0fd16 100644
 +				else
 +					tail = decl->avrules = to_be_appended;
 +
++				/* Now that the effective branch has been
++				 * appended, neutralize its original pointer */
++				if (cur_state == 1)
++					cur_node->avtrue_list = NULL;
++				else
++					cur_node->avfalse_list = NULL;
++
 +				/* 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;
+ /* Linking should always be done before calling expand, even if
+  * there is only a base since all optionals are dealt with at link time
+  * the base passed in should be indexed and avrule blocks should be 
+@@ -2678,6 +2791,16 @@ int expand_module(sepol_handle_t * handle,
+ 	expand_state_t state;
+ 	avrule_block_t *curblock;
  
 +	/* 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);
++	 * rules of a tunable would be added to te_avtab permanently. Whereas
++	 * the disabled unused branch would be discarded.
++	 *
++	 * Originally this function is called at the very end of link phase,
++	 * however, we need to keep the linked policy intact for analysis
++	 * purpose. */
++	discard_tunables(handle, base);
++
+ 	expand_state_init(&state);
+ 
+ 	state.verbose = verbose;
+diff --git a/libsepol/src/handle.c b/libsepol/src/handle.c
+index 191ac57..2e9a4ad 100644
+--- a/libsepol/src/handle.c
++++ b/libsepol/src/handle.c
+@@ -18,9 +18,24 @@ sepol_handle_t *sepol_handle_create(void)
+ 	sh->disable_dontaudit = 0;
+ 	sh->expand_consume_base = 0;
+ 
++	/* by default needless unused branch of tunables would be discarded  */
++	sh->preserve_tunables = 0;
++
+ 	return sh;
+ }
+ 
++int sepol_get_preserve_tunables(sepol_handle_t *sh)
++{
++	assert(sh != NULL);
++	return sh->preserve_tunables;
++}
++
++void sepol_set_preserve_tunables(sepol_handle_t * sh, int preserve_tunables)
++{
++	assert(sh !=NULL);
++	sh->preserve_tunables = preserve_tunables;
++}
 +
- 	retval = 0;
-       cleanup:
- 	for (i = 0; modules != NULL && i < len; i++) {
+ int sepol_get_disable_dontaudit(sepol_handle_t *sh)
+ {
+ 	assert(sh !=NULL);
+diff --git a/libsepol/src/handle.h b/libsepol/src/handle.h
+index 254fbd8..7728d04 100644
+--- a/libsepol/src/handle.h
++++ b/libsepol/src/handle.h
+@@ -17,7 +17,7 @@ struct sepol_handle {
+ 
+ 	int disable_dontaudit;
+ 	int expand_consume_base;
+-
++	int preserve_tunables;
+ };
+ 
+ #endif
+diff --git a/libsepol/src/libsepol.map b/libsepol/src/libsepol.map
+index 719e5b7..c6bb788 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;
+@@ -15,5 +16,6 @@
+ 	sepol_get_disable_dontaudit;
+ 	sepol_set_disable_dontaudit;
+ 	sepol_set_expand_consume_base;
++	sepol_get_preserve_tunables; sepol_set_preserve_tunables;
+   local: *;
+ };
+diff --git a/libsepol/src/link.c b/libsepol/src/link.c
+index 421c47b..ee9675b 100644
+--- a/libsepol/src/link.c
++++ b/libsepol/src/link.c
+@@ -587,7 +587,18 @@ 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() or vice versa).
++			 *
++			 * This is not allowed and bail out with errors */
++			ERR(state->handle,
++			    "%s: Mismatch between boolean/tunable definition "
++			    "and usage for %s", state->cur_mod_name, id);
++			return -1;
+ 	}
+ 
+ 	/* Get the scope info for this boolean to see if this is the declaration, 
+@@ -595,9 +606,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->flags = booldatum->flags;
++	}
+ 	state->cur->map[SYM_BOOLS][booldatum->s.value - 1] = base_bool->s.value;
+ 	return 0;
+ 
 diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
 index 017aeca..136b450 100644
 --- a/libsepol/src/policydb.c
diff --git a/libsepol.spec b/libsepol.spec
index c138128..1e64543 100644
--- a/libsepol.spec
+++ b/libsepol.spec
@@ -1,7 +1,7 @@
 Summary: SELinux binary policy manipulation library 
 Name: libsepol
 Version: 2.1.2
-Release: 2%{?dist}
+Release: 3%{?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 14 2011 Dan Walsh <dwalsh at redhat.com> - 2.1.2-3
+- Add patch to handle preserving tunables
+
 * Thu Sep 1 2011 Dan Walsh <dwalsh at redhat.com> - 2.1.2-2
 - export expand_module_avrules 
 


More information about the scm-commits mailing list