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); + - retval = 0; - cleanup: - for (i = 0; modules != NULL && i < len; i++) { + 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; ++} ++ + 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 - 2.1.2-3 +- Add patch to handle preserving tunables + * Thu Sep 1 2011 Dan Walsh - 2.1.2-2 - export expand_module_avrules