Add patch to handle preserving tunables
This commit is contained in:
parent
3c75a3b3ff
commit
ed26f06a29
@ -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
|
||||
|
@ -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@redhat.com> - 2.1.2-3
|
||||
- Add patch to handle preserving tunables
|
||||
|
||||
* Thu Sep 1 2011 Dan Walsh <dwalsh@redhat.com> - 2.1.2-2
|
||||
- export expand_module_avrules
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user