-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 This patch looks good to me. acked. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk5yV7AACgkQrlYvE4MpobNZigCgyybp+N8veYWrKnUL2TIskXey m/UAniubnND+I5RM3IfTkv6NgtS6cRUt =Z5+G -----END PGP SIGNATURE-----
>From e336ed0c05fbf4585efd09842e2e0896e945c9e8 Mon Sep 17 00:00:00 2001 From: Harry Ciao <qingtao.cao@xxxxxxxxxxxxx> Date: Thu, 1 Sep 2011 11:29:44 +0800 Subject: [PATCH 48/67] libsepol: Permanently discard disabled branches of tunables in expansion. For a cond_node_t in one decl->cond_list queue, append its avtrue_list or avfalse_list to the avrules list of its home decl depending on its state value, so that these effective rules would be permanently added to te_avtab hashtab. On the other hand, the rules on the disabled unused list won't be expanded and written to the raw policy at all. Signed-off-by: Harry Ciao <qingtao.cao@xxxxxxxxxxxxx> Signed-off-by: Eric Paris <eparis@xxxxxxxxxx> --- libsepol/src/expand.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 98 insertions(+), 0 deletions(-) diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c index 06f11f4..be41243 100644 --- a/libsepol/src/expand.c +++ b/libsepol/src/expand.c @@ -2665,6 +2665,94 @@ int expand_module_avrules(sepol_handle_t * handle, policydb_t * base, return copy_and_expand_avrule_block(&state); } +static void discard_tunables(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; + + /* 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; + cond_bool_datum_t *booldatum; + + booleans = tunables = 0; + + 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) + tunables++; + else + booleans++; + } + + /* bool_copy_callback() at link phase has ensured + * that no mixture of tunables and booleans in one + * expression. */ + assert(!(booleans && tunables)); + + if (booleans) { + cur_node->flags &= ~COND_NODE_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"); + 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; + + /* 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; + } + } + } +} + /* 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 +2766,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. 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(base); + expand_state_init(&state); state.verbose = verbose; -- 1.7.6.2