diff --git a/libsepol-rhat.patch b/libsepol-rhat.patch index 5066c22..5f397e3 100644 --- a/libsepol-rhat.patch +++ b/libsepol-rhat.patch @@ -1,8 +1,373 @@ +diff --git a/libsepol/include/sepol/policydb/conditional.h b/libsepol/include/sepol/policydb/conditional.h +index a8ed694..1fd1638 100644 +--- a/libsepol/include/sepol/policydb/conditional.h ++++ b/libsepol/include/sepol/policydb/conditional.h +@@ -77,15 +77,16 @@ 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; +- /* and these are using during parsing and for modules */ ++ /* and these are used during parsing and for modules */ + avrule_t *avtrue_list; + avrule_t *avfalse_list; + /* these fields are not written to binary policy */ + unsigned int nbools; + uint32_t bool_ids[COND_MAX_BOOLS]; + uint32_t expr_pre_comp; +- /* */ + struct cond_node *next; ++#define COND_NODE_FLAGS_TUNABLE 0x01 /* a tunable conditional */ ++ uint32_t flags; + } cond_node_t; + + extern int cond_evaluate_expr(policydb_t * p, cond_expr_t * expr); +diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h +index 5320bc8..1848a7b 100644 +--- a/libsepol/include/sepol/policydb/policydb.h ++++ b/libsepol/include/sepol/policydb/policydb.h +@@ -210,6 +210,8 @@ typedef struct range_trans { + typedef struct cond_bool_datum { + symtab_datum_t s; + int state; ++#define COND_BOOL_FLAGS_TUNABLE 0x01 /* is this a tunable? */ ++ uint32_t flags; + } cond_bool_datum_t; + + struct cond_node; +@@ -683,9 +685,10 @@ extern int policydb_set_target_platform(policydb_t *p, int platform); + #define MOD_POLICYDB_VERSION_FILENAME_TRANS 11 + #define MOD_POLICYDB_VERSION_ROLETRANS 12 + #define MOD_POLICYDB_VERSION_ROLEATTRIB 13 ++#define MOD_POLICYDB_VERSION_TUNABLE_SEP 14 + + #define MOD_POLICYDB_VERSION_MIN MOD_POLICYDB_VERSION_BASE +-#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_ROLEATTRIB ++#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_TUNABLE_SEP + + #define POLICYDB_CONFIG_MLS 1 + +diff --git a/libsepol/src/conditional.c b/libsepol/src/conditional.c +index 1482387..ea47cdd 100644 +--- a/libsepol/src/conditional.c ++++ b/libsepol/src/conditional.c +@@ -160,6 +160,7 @@ cond_node_t *cond_node_create(policydb_t * p, cond_node_t * node) + 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; ++ new_node->flags = node->flags; + } + + return new_node; +@@ -563,8 +564,8 @@ static int bool_isvalid(cond_bool_datum_t * b) + return 1; + } + +-int cond_read_bool(policydb_t * p +- __attribute__ ((unused)), hashtab_t h, ++int cond_read_bool(policydb_t * p, ++ hashtab_t h, + struct policy_file *fp) + { + char *key = 0; +@@ -596,6 +597,15 @@ int cond_read_bool(policydb_t * p + if (rc < 0) + goto err; + key[len] = 0; ++ ++ if (p->policy_type != POLICY_KERN && ++ p->policyvers >= MOD_POLICYDB_VERSION_TUNABLE_SEP) { ++ rc = next_entry(buf, fp, sizeof(uint32_t)); ++ if (rc < 0) ++ goto err; ++ booldatum->flags = le32_to_cpu(buf[0]); ++ } ++ + if (hashtab_insert(h, key, booldatum)) + goto err; + +@@ -810,6 +820,14 @@ static int cond_read_node(policydb_t * p, cond_node_t * node, void *fp) + goto err; + } + ++ if (p->policy_type != POLICY_KERN && ++ p->policyvers >= MOD_POLICYDB_VERSION_TUNABLE_SEP) { ++ rc = next_entry(buf, fp, sizeof(uint32_t)); ++ if (rc < 0) ++ goto err; ++ node->flags = le32_to_cpu(buf[0]); ++ } ++ + return 0; + err: + cond_node_destroy(node); +diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c +index 06f11f4..4458de6 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, + return 0; + } + ++ if (bool->flags & COND_BOOL_FLAGS_TUNABLE) { ++ /* Skip tunables */ ++ return 0; ++ } ++ + if (state->verbose) + INFO(state->handle, "copying boolean %s", id); + +@@ -1046,6 +1051,7 @@ static int bool_copy_callback(hashtab_key_t key, hashtab_datum_t datum, + state->boolmap[bool->s.value - 1] = new_bool->s.value; + + new_bool->state = bool->state; ++ new_bool->flags = bool->flags; + + return 0; + } +@@ -1940,6 +1946,13 @@ static int cond_node_copy(expand_state_t * state, cond_node_t * cn) + if (cond_node_copy(state, cn->next)) { + return -1; + } ++ ++ /* If current cond_node_t is of tunable, its effective branch ++ * has been appended to its home decl->avrules list during link ++ * and now we should just skip it. */ ++ if (cn->flags & COND_NODE_FLAGS_TUNABLE) ++ return 0; ++ + 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; + } + ++static void separate_tunables(link_state_t *state, 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; ++ ++ if (state->verbose) ++ INFO(state->handle, "Separating tunables from booleans."); ++ ++ /* 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, i; ++ cond_bool_datum_t *booldatum; ++ cond_bool_datum_t *tmp[COND_EXPR_MAXDEPTH]; ++ ++ booleans = tunables = 0; ++ memset(tmp, 0, sizeof(cond_bool_datum_t *) * COND_EXPR_MAXDEPTH); ++ ++ 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) ++ tmp[tunables++] = booldatum; ++ else ++ 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 */ ++ 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; ++ ++ /* 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; + ++ /* 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); ++ + retval = 0; + cleanup: + for (i = 0; modules != NULL && i < len; i++) { +diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c +index 017aeca..136b450 100644 +--- a/libsepol/src/policydb.c ++++ b/libsepol/src/policydb.c +@@ -221,6 +221,13 @@ static struct policydb_compat_info policydb_compat[] = { + .target_platform = SEPOL_TARGET_SELINUX, + }, + { ++ .type = POLICY_BASE, ++ .version = MOD_POLICYDB_VERSION_TUNABLE_SEP, ++ .sym_num = SYM_NUM, ++ .ocon_num = OCON_NODE6 + 1, ++ .target_platform = SEPOL_TARGET_SELINUX, ++ }, ++ { + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_BASE, + .sym_num = SYM_NUM, +@@ -290,6 +297,13 @@ static struct policydb_compat_info policydb_compat[] = { + .ocon_num = 0, + .target_platform = SEPOL_TARGET_SELINUX, + }, ++ { ++ .type = POLICY_MOD, ++ .version = MOD_POLICYDB_VERSION_TUNABLE_SEP, ++ .sym_num = SYM_NUM, ++ .ocon_num = 0, ++ .target_platform = SEPOL_TARGET_SELINUX, ++ }, + }; + + #if 0 diff --git a/libsepol/src/write.c b/libsepol/src/write.c -index 290e036..7257b0b 100644 +index 290e036..e34ab52 100644 --- a/libsepol/src/write.c +++ b/libsepol/src/write.c -@@ -972,6 +972,19 @@ static int role_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) +@@ -607,6 +607,7 @@ static int cond_write_bool(hashtab_key_t key, hashtab_datum_t datum, void *ptr) + unsigned int items, items2; + struct policy_data *pd = ptr; + struct policy_file *fp = pd->fp; ++ struct policydb *p = pd->p; + + booldatum = (cond_bool_datum_t *) datum; + +@@ -621,6 +622,15 @@ static int cond_write_bool(hashtab_key_t key, hashtab_datum_t datum, void *ptr) + items = put_entry(key, 1, len, fp); + if (items != len) + return POLICYDB_ERROR; ++ ++ if (p->policy_type != POLICY_KERN && ++ p->policyvers >= MOD_POLICYDB_VERSION_TUNABLE_SEP) { ++ buf[0] = cpu_to_le32(booldatum->flags); ++ items = put_entry(buf, sizeof(uint32_t), 1, fp); ++ if (items != 1) ++ return POLICYDB_ERROR; ++ } ++ + return POLICYDB_SUCCESS; + } + +@@ -727,6 +737,14 @@ static int cond_write_node(policydb_t * p, + return POLICYDB_ERROR; + } + ++ if (p->policy_type != POLICY_KERN && ++ p->policyvers >= MOD_POLICYDB_VERSION_TUNABLE_SEP) { ++ buf[0] = cpu_to_le32(node->flags); ++ items = put_entry(buf, sizeof(uint32_t), 1, fp); ++ if (items != 1) ++ return POLICYDB_ERROR; ++ } ++ + return POLICYDB_SUCCESS; + } + +@@ -972,6 +990,19 @@ static int role_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) role = (role_datum_t *) datum; @@ -22,7 +387,7 @@ index 290e036..7257b0b 100644 len = strlen(key); items = 0; buf[items++] = cpu_to_le32(len); -@@ -1795,6 +1808,19 @@ static int type_attr_uncount(hashtab_key_t key __attribute__ ((unused)), +@@ -1795,6 +1826,19 @@ static int type_attr_uncount(hashtab_key_t key __attribute__ ((unused)), return 0; } @@ -42,7 +407,7 @@ index 290e036..7257b0b 100644 /* * Write the configuration data in a policy database * structure to a policy database binary representation -@@ -1926,7 +1952,7 @@ int policydb_write(policydb_t * p, struct policy_file *fp) +@@ -1926,7 +1970,7 @@ int policydb_write(policydb_t * p, struct policy_file *fp) num_syms = info->sym_num; for (i = 0; i < num_syms; i++) { buf[0] = cpu_to_le32(p->symtab[i].nprim); @@ -51,7 +416,7 @@ index 290e036..7257b0b 100644 /* * A special case when writing type/attribute symbol table. -@@ -1939,6 +1965,20 @@ int policydb_write(policydb_t * p, struct policy_file *fp) +@@ -1939,6 +1983,20 @@ int policydb_write(policydb_t * p, struct policy_file *fp) p->policy_type == POLICY_KERN) { hashtab_map(p->symtab[i].table, type_attr_uncount, &buf[1]); } diff --git a/libsepol.spec b/libsepol.spec index af99025..c138128 100644 --- a/libsepol.spec +++ b/libsepol.spec @@ -1,7 +1,7 @@ Summary: SELinux binary policy manipulation library Name: libsepol Version: 2.1.2 -Release: 1%{?dist} +Release: 2%{?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 1 2011 Dan Walsh - 2.1.2-2 +- export expand_module_avrules + * Thu Aug 18 2011 Dan Walsh - 2.1.2-0 - Update to upstream * Only call role_fix_callback for base.p_roles during expansion.