diff --git a/.gitignore b/.gitignore index ce8c213..bb3b6f0 100644 --- a/.gitignore +++ b/.gitignore @@ -155,3 +155,4 @@ libsepol-2.0.41.tgz /libsepol-2.1.0.tgz /libsepol-2.1.1.tgz /libsepol-2.1.2.tgz +/libsepol-2.1.3.tgz diff --git a/libsepol-rhat.patch b/libsepol-rhat.patch index 6ae1159..e69de29 100644 --- a/libsepol-rhat.patch +++ b/libsepol-rhat.patch @@ -1,525 +0,0 @@ -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..48ec106 100644 ---- a/libsepol/include/sepol/policydb/conditional.h -+++ b/libsepol/include/sepol/policydb/conditional.h -@@ -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; -- /* 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; -+ /* a tunable conditional, calculated and used at expansion */ -+#define COND_NODE_FLAGS_TUNABLE 0x01 -+ 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..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, - 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; -@@ -2665,6 +2678,106 @@ int expand_module_avrules(sepol_handle_t * handle, policydb_t * base, - return copy_and_expand_avrule_block(&state); - } - -+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, preserve_tunables = 0; -+ avrule_t *tail, *to_be_appended; -+ -+ if (sh && sh->preserve_tunables) -+ preserve_tunables = 1; -+ -+ /* Iterate through all cond_node of all enabled decls, if a cond_node -+ * 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 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; -+ 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++; -+ } -+ -+ /* 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"); -+ 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 +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. 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); -+ - 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 -+++ 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..e34ab52 100644 ---- a/libsepol/src/write.c -+++ b/libsepol/src/write.c -@@ -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; - -+ /* -+ * Role attributes are redundant for policy.X, skip them -+ * when writing the roles symbol table. They are also skipped -+ * when pp is downgraded. -+ * -+ * Their numbers would be deducted in policydb_write(). -+ */ -+ if ((role->flavor == ROLE_ATTRIB) && -+ ((p->policy_type == POLICY_KERN) || -+ (p->policy_type != POLICY_KERN && -+ p->policyvers < MOD_POLICYDB_VERSION_ROLEATTRIB))) -+ return POLICYDB_SUCCESS; -+ - len = strlen(key); - items = 0; - buf[items++] = cpu_to_le32(len); -@@ -1795,6 +1826,19 @@ static int type_attr_uncount(hashtab_key_t key __attribute__ ((unused)), - return 0; - } - -+static int role_attr_uncount(hashtab_key_t key __attribute__ ((unused)), -+ hashtab_datum_t datum, void *args) -+{ -+ role_datum_t *role = datum; -+ uint32_t *p_nel = args; -+ -+ if (role->flavor == ROLE_ATTRIB) { -+ /* uncount attribute from total number of roles */ -+ (*p_nel)--; -+ } -+ return 0; -+} -+ - /* - * Write the configuration data in a policy database - * structure to a policy database binary representation -@@ -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); -- buf[1] = cpu_to_le32(p->symtab[i].table->nel); -+ buf[1] = p->symtab[i].table->nel; - - /* - * A special case when writing type/attribute symbol table. -@@ -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]); - } -+ -+ /* -+ * Another special case when writing role/attribute symbol -+ * table, role attributes are redundant for policy.X, or -+ * when the pp's version is not big enough. So deduct -+ * their numbers from p_roles.table->nel. -+ */ -+ if ((i == SYM_ROLES) && -+ ((p->policy_type == POLICY_KERN) || -+ (p->policy_type != POLICY_KERN && -+ p->policyvers < MOD_POLICYDB_VERSION_ROLEATTRIB))) -+ hashtab_map(p->symtab[i].table, role_attr_uncount, &buf[1]); -+ -+ buf[1] = cpu_to_le32(buf[1]); - items = put_entry(buf, sizeof(uint32_t), 2, fp); - if (items != 2) - return POLICYDB_ERROR; diff --git a/libsepol.spec b/libsepol.spec index 1e64543..2b5e254 100644 --- a/libsepol.spec +++ b/libsepol.spec @@ -1,12 +1,11 @@ Summary: SELinux binary policy manipulation library Name: libsepol -Version: 2.1.2 -Release: 3%{?dist} +Version: 2.1.3 +Release: 1%{?dist} License: LGPLv2+ Group: System Environment/Libraries Source: http://www.nsa.gov/selinux/archives/libsepol-%{version}.tgz URL: http://www.selinuxproject.org -patch: libsepol-rhat.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) %description @@ -45,7 +44,6 @@ needed for developing applications that manipulate binary policies. %prep %setup -q -%patch -p2 -b .rhat # sparc64 is an -fPIC arch, so we need to fix it here %ifarch sparc64 sed -i 's/fpic/fPIC/g' src/Makefile @@ -98,6 +96,20 @@ exit 0 /%{_lib}/libsepol.so.1 %changelog +* Mon Sep 19 2011 Dan Walsh - 2.1.3-1 +-Update to upstream + * Skip writing role attributes for policy.X and + * Indicate when boolean is indeed a tunable. + * Separate tunable from boolean during compile. + * Write and read TUNABLE flags in related + * Copy and check the cond_bool_datum_t.flags during link. + * Permanently discard disabled branches of tunables in + * Skip tunable identifier and cond_node_t in expansion. + * Create a new preserve_tunables flag + * Preserve tunables when required by semodule program. + * setools expects expand_module_avrules to be an exported + * tree: default make target to all not + * Thu Sep 14 2011 Dan Walsh - 2.1.2-3 - Add patch to handle preserving tunables diff --git a/sources b/sources index b75b42f..46040cc 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -b5633c3d0326cf492b88eb5e010923f0 libsepol-2.1.2.tgz +8278689ecf9d5219887b72fc24ff66ff libsepol-2.1.3.tgz