diff --exclude-from=exclude -N -u -r nsalibsepol/include/sepol/policydb/conditional.h libsepol-2.0.1/include/sepol/policydb/conditional.h --- nsalibsepol/include/sepol/policydb/conditional.h 2006-11-16 17:14:15.000000000 -0500 +++ libsepol-2.0.1/include/sepol/policydb/conditional.h 2007-03-28 14:13:02.000000000 -0400 @@ -100,6 +100,8 @@ cond_node_t * needle, cond_node_t * haystack, int *was_created); +extern cond_node_t *cond_node_create(policydb_t * p, cond_node_t * node); + extern cond_node_t *cond_node_search(policydb_t * p, cond_node_t * list, cond_node_t * cn); diff --exclude-from=exclude -N -u -r nsalibsepol/src/conditional.c libsepol-2.0.1/src/conditional.c --- nsalibsepol/src/conditional.c 2006-11-16 17:14:24.000000000 -0500 +++ libsepol-2.0.1/src/conditional.c 2007-03-28 14:13:02.000000000 -0400 @@ -26,9 +26,6 @@ #include "private.h" -#undef min -#define min(a,b) (((a) < (b)) ? (a) : (b)) - /* move all type rules to top of t/f lists to help kernel on evaluation */ static void cond_optimize(cond_av_list_t ** l) { @@ -136,6 +133,38 @@ return 1; } +/* Create a new conditional node, optionally copying + * the conditional expression from an existing node. + * If node is NULL then a new node will be created + * with no conditional expression. + */ +cond_node_t *cond_node_create(policydb_t * p, cond_node_t * node) +{ + cond_node_t *new_node; + unsigned int i; + + new_node = (cond_node_t *)malloc(sizeof(cond_node_t)); + if (!new_node) { + return NULL; + } + memset(new_node, 0, sizeof(cond_node_t)); + + if (node) { + new_node->expr = cond_copy_expr(node->expr); + if (!new_node->expr) { + free(new_node); + return NULL; + } + new_node->cur_state = cond_evaluate_expr(p, new_node->expr); + new_node->nbools = node->nbools; + 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; + } + + return new_node; +} + /* Find a conditional (the needle) within a list of existing ones (the * haystack) that has a matching expression. If found, return a * pointer to the existing node, setting 'was_created' to 0. @@ -145,9 +174,6 @@ cond_node_t * needle, cond_node_t * haystack, int *was_created) { - cond_node_t *new_node; - unsigned int i; - while (haystack) { if (cond_expr_equal(needle, haystack)) { *was_created = 0; @@ -156,26 +182,8 @@ haystack = haystack->next; } *was_created = 1; - new_node = (cond_node_t *) malloc(sizeof(cond_node_t)); - if (!new_node) { - return NULL; - } - memset(new_node, 0, sizeof(cond_node_t)); - new_node->expr = cond_copy_expr(needle->expr); - if (!new_node->expr) { - free(new_node); - return NULL; - } - new_node->cur_state = cond_evaluate_expr(p, new_node->expr); - new_node->nbools = needle->nbools; - for (i = 0; i < min(needle->nbools, COND_MAX_BOOLS); i++) - new_node->bool_ids[i] = needle->bool_ids[i]; - new_node->expr_pre_comp = needle->expr_pre_comp; - new_node->true_list = NULL; - new_node->false_list = NULL; - new_node->avtrue_list = NULL; - new_node->avfalse_list = NULL; - return new_node; + + return cond_node_create(p, needle); } /* return either a pre-existing matching node or create a new node */ diff --exclude-from=exclude -N -u -r nsalibsepol/src/expand.c libsepol-2.0.1/src/expand.c --- nsalibsepol/src/expand.c 2007-02-07 12:11:48.000000000 -0500 +++ libsepol-2.0.1/src/expand.c 2007-03-28 14:13:02.000000000 -0400 @@ -35,10 +35,12 @@ #include #include "debug.h" +#include "private.h" typedef struct expand_state { int verbose; uint32_t *typemap; + uint32_t *boolmap; policydb_t *base; policydb_t *out; sepol_handle_t *handle; @@ -791,8 +793,8 @@ return -1; } - new_bool->s.value = bool->s.value; state->out->p_bools.nprim++; + new_bool->s.value = state->out->p_bools.nprim; ret = hashtab_insert(state->out->p_bools.table, (hashtab_key_t) new_id, @@ -804,6 +806,8 @@ return -1; } + state->boolmap[bool->s.value - 1] = new_bool->s.value; + new_bool->state = bool->state; return 0; @@ -1555,12 +1559,35 @@ return 0; } +static int cond_node_map_bools(expand_state_t * state, cond_node_t * cn) +{ + cond_expr_t *cur; + unsigned int i; + + cur = cn->expr; + while (cur) { + if (cur->bool) + cur->bool = state->boolmap[cur->bool - 1]; + cur = cur->next; + } + + for (i = 0; i < min(cn->nbools, COND_MAX_BOOLS); i++) + cn->bool_ids[i] = state->boolmap[cn->bool_ids[i] - 1]; + + if (cond_normalize_expr(state->out, cn)) { + ERR(state->handle, "Error while normalizing conditional"); + return -1; + } + + return 0; +} + /* copy the nodes in *reverse* order -- the result is that the last * given conditional appears first in the policy, so as to match the * behavior of the upstream compiler */ static int cond_node_copy(expand_state_t * state, cond_node_t * cn) { - cond_node_t *new_cond; + cond_node_t *new_cond, *tmp; if (cn == NULL) { return 0; @@ -1573,11 +1600,26 @@ return -1; } - new_cond = cond_node_search(state->out, state->out->cond_list, cn); + /* create a new temporary conditional node with the booleans + * mapped */ + tmp = cond_node_create(state->base, cn); + if (!tmp) { + ERR(state->handle, "Out of memory"); + return -1; + } + + if (cond_node_map_bools(state, tmp)) { + ERR(state->handle, "Error mapping booleans"); + return -1; + } + + new_cond = cond_node_search(state->out, state->out->cond_list, tmp); if (!new_cond) { + cond_node_destroy(tmp); ERR(state->handle, "Out of memory!"); return -1; } + cond_node_destroy(tmp); if (cond_avrule_list_copy (state->out, cn->avtrue_list, &state->out->te_cond_avtab, @@ -2210,6 +2252,12 @@ goto cleanup; } + state.boolmap = (uint32_t *)calloc(state.base->p_bools.nprim, sizeof(uint32_t)); + if (!state.boolmap) { + ERR(handle, "Out of memory!"); + goto cleanup; + } + /* order is important - types must be first */ /* copy types */ @@ -2364,6 +2412,7 @@ cleanup: free(state.typemap); + free(state.boolmap); return retval; } diff --exclude-from=exclude -N -u -r nsalibsepol/src/private.h libsepol-2.0.1/src/private.h --- nsalibsepol/src/private.h 2007-02-07 12:11:48.000000000 -0500 +++ libsepol-2.0.1/src/private.h 2007-03-28 14:13:02.000000000 -0400 @@ -24,6 +24,9 @@ #define le64_to_cpu(x) bswap_64(x) #endif +#undef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) + /* Policy compatibility information. */ struct policydb_compat_info { unsigned int type;