Re: [PATCH v2] libsepol,checkpolicy: drop support for kernel policy versions < 24
James Carter <[email protected]>
| Newsgroups | org.kernel.vger.selinux |
|---|---|
| Message-ID | <CAP+JOzTTwarKFCiaOmKfcT+M6V_uShJuD3EMfNCWNgfxcsDLag@mail.gmail.com> |
On Wed, Aug 5, 2026 at 3:15 PM Stephen Smalley <[email protected]> wrote: > > Given the recently reported bugs in libsepol's support for policy > versions 20 through 23, let's drop support for kernel policy versions > < 24. This also aligns the minimum SELinux kernel policy version with > the minimum Xen policy version. This makes libsepol's minimum > supported kernel version v2.6.28 which is older than the v3.0 minimum > we already set for libselinux. > > Reported-by: Chen Gong <[email protected]> > Signed-off-by: Stephen Smalley <[email protected]> Acked-by: James Carter <[email protected]> > --- > v2 fixes up a duplicated validate_filename_trans_hashtab() call and > an incorrectly removed mls check for binary modules. > > checkpolicy/checkpolicy.c | 14 +- > libsepol/include/sepol/policydb/policydb.h | 12 +- > libsepol/src/avtab.c | 92 +------ > libsepol/src/kernel_to_common.c | 13 - > libsepol/src/optimize.c | 13 - > libsepol/src/policydb.c | 129 ++------- > libsepol/src/policydb_validate.c | 43 +-- > libsepol/src/write.c | 290 ++------------------- > libsepol/tests/test-downgrade.c | 7 - > 9 files changed, 64 insertions(+), 549 deletions(-) > > diff --git a/checkpolicy/checkpolicy.c b/checkpolicy/checkpolicy.c > index c1b33869..b5a6da3a 100644 > --- a/checkpolicy/checkpolicy.c > +++ b/checkpolicy/checkpolicy.c > @@ -605,18 +605,8 @@ int main(int argc, char **argv) > } > } > > - if (policydbp->policyvers <= POLICYDB_VERSION_PERMISSIVE) { > - if (policyvers > policydbp->policyvers) { > - fprintf(stderr, > - "Binary policies with version <= %u cannot be upgraded\n", > - POLICYDB_VERSION_PERMISSIVE); > - } else if (policyvers) { > - policydbp->policyvers = policyvers; > - } > - } else { > - policydbp->policyvers = > - policyvers ? policyvers : POLICYDB_VERSION_MAX; > - } > + policydbp->policyvers = policyvers ? policyvers : > + POLICYDB_VERSION_MAX; > } else { > if (conf) { > fprintf(stderr, > diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h > index a1b5e99b..985a496e 100644 > --- a/libsepol/include/sepol/policydb/policydb.h > +++ b/libsepol/include/sepol/policydb/policydb.h > @@ -750,16 +750,6 @@ extern int policydb_set_target_platform(policydb_t *p, int platform); > #define PERM_SYMTAB_SIZE 32 > > /* Identify specific policy version changes */ > -#define POLICYDB_VERSION_BASE 15 > -#define POLICYDB_VERSION_BOOL 16 > -#define POLICYDB_VERSION_IPV6 17 > -#define POLICYDB_VERSION_NLCLASS 18 > -#define POLICYDB_VERSION_VALIDATETRANS 19 > -#define POLICYDB_VERSION_MLS 19 > -#define POLICYDB_VERSION_AVTAB 20 > -#define POLICYDB_VERSION_RANGETRANS 21 > -#define POLICYDB_VERSION_POLCAP 22 > -#define POLICYDB_VERSION_PERMISSIVE 23 > #define POLICYDB_VERSION_BOUNDARY 24 > #define POLICYDB_VERSION_FILENAME_TRANS 25 > #define POLICYDB_VERSION_ROLETRANS 26 > @@ -776,7 +766,7 @@ extern int policydb_set_target_platform(policydb_t *p, int platform); > #define POLICYDB_VERSION_NEVERAUDIT 35 /* neveraudit domains */ > > /* Range of policy versions we understand*/ > -#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE > +#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BOUNDARY > #define POLICYDB_VERSION_MAX POLICYDB_VERSION_NEVERAUDIT > > /* Module versions and specific changes*/ > diff --git a/libsepol/src/avtab.c b/libsepol/src/avtab.c > index 4a81e551..2bb67599 100644 > --- a/libsepol/src/avtab.c > +++ b/libsepol/src/avtab.c > @@ -417,23 +417,14 @@ void avtab_hash_eval(avtab_t *h, char *tag) > tag, h->nel, slots_used, h->nslot, max_chain_len); > } > > -/* Ordering of datums in the original avtab format in the policy file. */ > -static const uint16_t spec_order[] = { > - AVTAB_ALLOWED, AVTAB_AUDITDENY, > - AVTAB_AUDITALLOW, AVTAB_TRANSITION, > - AVTAB_CHANGE, AVTAB_MEMBER, > - AVTAB_XPERMS_ALLOWED, AVTAB_XPERMS_AUDITALLOW, > - AVTAB_XPERMS_DONTAUDIT > -}; > - > int avtab_read_item(struct policy_file *fp, uint32_t vers, avtab_t *a, > int (*insertf)(avtab_t *a, avtab_key_t *k, avtab_datum_t *d, > void *p), > void *p) > { > uint8_t buf8; > - uint16_t buf16[4], enabled; > - uint32_t buf32[8], items, items2, val; > + uint16_t buf16[4]; > + uint32_t buf32[8], items; > avtab_key_t key; > avtab_datum_t datum; > avtab_extended_perms_t xperms; > @@ -444,85 +435,6 @@ int avtab_read_item(struct policy_file *fp, uint32_t vers, avtab_t *a, > memset(&datum, 0, sizeof(avtab_datum_t)); > memset(&xperms, 0, sizeof(avtab_extended_perms_t)); > > - if (vers < POLICYDB_VERSION_AVTAB) { > - rc = next_entry(buf32, fp, sizeof(uint32_t)); > - if (rc < 0) { > - ERR(fp->handle, "truncated entry"); > - return -1; > - } > - items2 = le32_to_cpu(buf32[0]); > - > - if (items2 < 5 || items2 > ARRAY_SIZE(buf32)) { > - ERR(fp->handle, "invalid item count"); > - return -1; > - } > - > - rc = next_entry(buf32, fp, sizeof(uint32_t) * items2); > - if (rc < 0) { > - ERR(fp->handle, "truncated entry"); > - return -1; > - } > - > - items = 0; > - val = le32_to_cpu(buf32[items++]); > - key.source_type = (uint16_t)val; > - if (key.source_type != val) { > - ERR(fp->handle, "truncated source type"); > - return -1; > - } > - val = le32_to_cpu(buf32[items++]); > - key.target_type = (uint16_t)val; > - if (key.target_type != val) { > - ERR(fp->handle, "truncated target type"); > - return -1; > - } > - val = le32_to_cpu(buf32[items++]); > - key.target_class = (uint16_t)val; > - if (key.target_class != val) { > - ERR(fp->handle, "truncated target class"); > - return -1; > - } > - > - val = le32_to_cpu(buf32[items++]); > - enabled = (val & AVTAB_ENABLED_OLD) ? AVTAB_ENABLED : 0; > - > - if (!(val & (AVTAB_AV | AVTAB_TYPE))) { > - ERR(fp->handle, "null entry"); > - return -1; > - } > - if ((val & AVTAB_AV) && (val & AVTAB_TYPE)) { > - ERR(fp->handle, "entry has both access " > - "vectors and types"); > - return -1; > - } > - > - for (i = 0; i < ARRAY_SIZE(spec_order); i++) { > - if (val & spec_order[i]) { > - if (items >= > - items2) { /* items is index, items2 is total number */ > - ERR(fp->handle, > - "entry has too many items (%d/%d)", > - items + 1, items2); > - return -1; > - } > - key.specified = spec_order[i] | enabled; > - datum.data = le32_to_cpu(buf32[items++]); > - rc = insertf(a, &key, &datum, p); > - if (rc) > - return rc; > - } > - } > - > - if (items != items2) { > - ERR(fp->handle, > - "entry only had %d items, " > - "expected %d", > - items2, items); > - return -1; > - } > - return 0; > - } > - > rc = next_entry(buf16, fp, sizeof(uint16_t) * 4); > if (rc < 0) { > ERR(fp->handle, "truncated entry"); > diff --git a/libsepol/src/kernel_to_common.c b/libsepol/src/kernel_to_common.c > index c7b6d73a..338dcef6 100644 > --- a/libsepol/src/kernel_to_common.c > +++ b/libsepol/src/kernel_to_common.c > @@ -795,18 +795,5 @@ int check_for_supported_policy(struct policydb *pdb) > return -1; > } > > - if (pdb->policyvers >= POLICYDB_VERSION_AVTAB && > - pdb->policyvers <= POLICYDB_VERSION_PERMISSIVE) { > - /* > - * For policy versions between 20 and 23, attributes exist in the policy, > - * but only in the type_attr_map. This means that there are gaps in both > - * the type_val_to_struct and p_type_val_to_name arrays and policy rules > - * can refer to those gaps. > - */ > - ERR(NULL, > - "Writing out CIL or policy.conf from policy versions between 20 and 23 is not supported"); > - return -1; > - } > - > return 0; > } > diff --git a/libsepol/src/optimize.c b/libsepol/src/optimize.c > index 7a961ca4..eeffee7d 100644 > --- a/libsepol/src/optimize.c > +++ b/libsepol/src/optimize.c > @@ -453,19 +453,6 @@ int policydb_optimize(policydb_t *p) > if (p->policy_type != POLICY_KERN) > return -1; > > - if (p->policyvers >= POLICYDB_VERSION_AVTAB && > - p->policyvers <= POLICYDB_VERSION_PERMISSIVE) { > - /* > - * For policy versions between 20 and 23, attributes exist in the policy, > - * but only in the type_attr_map. This means that there are gaps in both > - * the type_val_to_struct and p_type_val_to_name arrays and policy rules > - * can refer to those gaps. > - */ > - ERR(NULL, > - "Optimizing policy versions between 20 and 23 is not supported"); > - return -1; > - } > - > type_map = build_type_map(p); > if (!type_map) > return -1; > diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c > index 44e26f4f..84b7ac1e 100644 > --- a/libsepol/src/policydb.c > +++ b/libsepol/src/policydb.c > @@ -76,69 +76,6 @@ static const struct policydb_compat_info policydb_compat[] = { > .ocon_num = OCON_XEN_DEVICETREE + 1, > .target_platform = SEPOL_TARGET_XEN, > }, > - { > - .type = POLICY_KERN, > - .version = POLICYDB_VERSION_BASE, > - .sym_num = SYM_NUM - 3, > - .ocon_num = OCON_FSUSE + 1, > - .target_platform = SEPOL_TARGET_SELINUX, > - }, > - { > - .type = POLICY_KERN, > - .version = POLICYDB_VERSION_BOOL, > - .sym_num = SYM_NUM - 2, > - .ocon_num = OCON_FSUSE + 1, > - .target_platform = SEPOL_TARGET_SELINUX, > - }, > - { > - .type = POLICY_KERN, > - .version = POLICYDB_VERSION_IPV6, > - .sym_num = SYM_NUM - 2, > - .ocon_num = OCON_NODE6 + 1, > - .target_platform = SEPOL_TARGET_SELINUX, > - }, > - { > - .type = POLICY_KERN, > - .version = POLICYDB_VERSION_NLCLASS, > - .sym_num = SYM_NUM - 2, > - .ocon_num = OCON_NODE6 + 1, > - .target_platform = SEPOL_TARGET_SELINUX, > - }, > - { > - .type = POLICY_KERN, > - .version = POLICYDB_VERSION_MLS, > - .sym_num = SYM_NUM, > - .ocon_num = OCON_NODE6 + 1, > - .target_platform = SEPOL_TARGET_SELINUX, > - }, > - { > - .type = POLICY_KERN, > - .version = POLICYDB_VERSION_AVTAB, > - .sym_num = SYM_NUM, > - .ocon_num = OCON_NODE6 + 1, > - .target_platform = SEPOL_TARGET_SELINUX, > - }, > - { > - .type = POLICY_KERN, > - .version = POLICYDB_VERSION_RANGETRANS, > - .sym_num = SYM_NUM, > - .ocon_num = OCON_NODE6 + 1, > - .target_platform = SEPOL_TARGET_SELINUX, > - }, > - { > - .type = POLICY_KERN, > - .version = POLICYDB_VERSION_POLCAP, > - .sym_num = SYM_NUM, > - .ocon_num = OCON_NODE6 + 1, > - .target_platform = SEPOL_TARGET_SELINUX, > - }, > - { > - .type = POLICY_KERN, > - .version = POLICYDB_VERSION_PERMISSIVE, > - .sym_num = SYM_NUM, > - .ocon_num = OCON_NODE6 + 1, > - .target_platform = SEPOL_TARGET_SELINUX, > - }, > { > .type = POLICY_KERN, > .version = POLICYDB_VERSION_BOUNDARY, > @@ -2088,8 +2025,7 @@ static int context_read_and_validate(context_struct_t *c, policydb_t *p, > c->user = le32_to_cpu(buf[0]); > c->role = le32_to_cpu(buf[1]); > c->type = le32_to_cpu(buf[2]); > - if ((p->policy_type == POLICY_KERN && > - p->policyvers >= POLICYDB_VERSION_MLS) || > + if ((p->policy_type == POLICY_KERN) || > (p->policy_type == POLICY_BASE && > p->policyvers >= MOD_POLICYDB_VERSION_MLS)) { > if (mls_read_range_helper(&c->range, fp)) { > @@ -2348,8 +2284,7 @@ static int class_read(policydb_t *p, hashtab_t h, struct policy_file *fp) > if (read_cons_helper(p, &cladatum->constraints, ncons, 0, fp)) > goto bad; > > - if ((p->policy_type == POLICY_KERN && > - p->policyvers >= POLICYDB_VERSION_VALIDATETRANS) || > + if ((p->policy_type == POLICY_KERN) || > (p->policy_type == POLICY_BASE && > p->policyvers >= MOD_POLICYDB_VERSION_VALIDATETRANS)) { > /* grab the validatetrans rules */ > @@ -3365,8 +3300,7 @@ static int user_read(policydb_t *p, hashtab_t h, struct policy_file *fp) > * MOD_POLICYDB_VERSION_MLS_USERS, but they could have been > * required - the mls fields will be empty. user declarations in > * non-mls modules will also have empty mls fields */ > - if ((p->policy_type == POLICY_KERN && > - p->policyvers >= POLICYDB_VERSION_MLS) || > + if ((p->policy_type == POLICY_KERN) || > (p->policy_type == POLICY_MOD && > p->policyvers >= MOD_POLICYDB_VERSION_MLS && > p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS) || > @@ -3603,8 +3537,7 @@ static int range_read(policydb_t *p, struct policy_file *fp) > struct mls_range *r = NULL; > range_trans_rule_t *rtr = NULL, *lrtr = NULL; > unsigned int i; > - int new_rangetr = (p->policy_type == POLICY_KERN && > - p->policyvers >= POLICYDB_VERSION_RANGETRANS); > + int new_rangetr = (p->policy_type == POLICY_KERN); > int rc; > > rc = next_entry(buf, fp, sizeof(uint32_t)); > @@ -4361,8 +4294,7 @@ int policydb_read(policydb_t *p, struct policy_file *fp, unsigned verbose) > goto bad; > } > > - if ((p->policyvers >= POLICYDB_VERSION_POLCAP && > - p->policy_type == POLICY_KERN) || > + if ((p->policy_type == POLICY_KERN) || > (p->policyvers >= MOD_POLICYDB_VERSION_POLCAP && > p->policy_type == POLICY_BASE) || > (p->policyvers >= MOD_POLICYDB_VERSION_POLCAP && > @@ -4371,8 +4303,7 @@ int policydb_read(policydb_t *p, struct policy_file *fp, unsigned verbose) > goto bad; > } > > - if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE && > - p->policy_type == POLICY_KERN) { > + if (p->policy_type == POLICY_KERN) { > if (ebitmap_read(&p->permissive_map, fp)) > goto bad; > } > @@ -4422,9 +4353,8 @@ int policydb_read(policydb_t *p, struct policy_file *fp, unsigned verbose) > if (policy_type == POLICY_KERN) { > if (avtab_read(&p->te_avtab, fp, r_policyvers)) > goto bad; > - if (r_policyvers >= POLICYDB_VERSION_BOOL) > - if (cond_read_list(p, &p->cond_list, fp)) > - goto bad; > + if (cond_read_list(p, &p->cond_list, fp)) > + goto bad; > if (role_trans_read(p, fp)) > goto bad; > if (role_allow_read(&p->role_allow, fp)) > @@ -4487,8 +4417,7 @@ int policydb_read(policydb_t *p, struct policy_file *fp, unsigned verbose) > goto bad; > } > > - if ((p->policy_type == POLICY_KERN && > - p->policyvers >= POLICYDB_VERSION_MLS) || > + if ((p->policy_type == POLICY_KERN) || > (p->policy_type == POLICY_BASE && > p->policyvers >= MOD_POLICYDB_VERSION_MLS && > p->policyvers < MOD_POLICYDB_VERSION_RANGETRANS)) { > @@ -4503,30 +4432,28 @@ int policydb_read(policydb_t *p, struct policy_file *fp, unsigned verbose) > if (!p->type_attr_map || !p->attr_type_map) > goto bad; > for (i = 0; i < p->p_types.nprim; i++) { > - if (r_policyvers >= POLICYDB_VERSION_AVTAB) { > - if (ebitmap_read(&p->type_attr_map[i], fp)) > + if (ebitmap_read(&p->type_attr_map[i], fp)) > + goto bad; > + ebitmap_for_each_positive_bit(&p->type_attr_map[i], > + tnode, j) { > + if (i == j) > + continue; > + > + if (j >= p->p_types.nprim) > + goto bad; > + > + if (p->type_val_to_struct[i] && > + p->type_val_to_struct[i]->flavor == > + TYPE_ATTRIB) { > + ERR(fp->handle, > + "Invalid to have type attributes associated with an attribute for a kernel policy"); > goto bad; > - ebitmap_for_each_positive_bit( > - &p->type_attr_map[i], tnode, j) { > - if (i == j) > - continue; > - > - if (j >= p->p_types.nprim) > - goto bad; > - > - if (p->type_val_to_struct[i] && > - p->type_val_to_struct[i]->flavor == > - TYPE_ATTRIB) { > - ERR(fp->handle, > - "Invalid to have type attributes associated with an attribute for a kernel policy"); > - goto bad; > - } > - > - if (ebitmap_set_bit( > - &p->attr_type_map[j], i, 1)) > - goto bad; > } > + > + if (ebitmap_set_bit(&p->attr_type_map[j], i, 1)) > + goto bad; > } > + > /* add the type itself as the degenerate case */ > if (p->type_val_to_struct[i] && > ebitmap_set_bit(&p->type_attr_map[i], i, 1)) > diff --git a/libsepol/src/policydb_validate.c b/libsepol/src/policydb_validate.c > index 4cdf0b78..5687c82b 100644 > --- a/libsepol/src/policydb_validate.c > +++ b/libsepol/src/policydb_validate.c > @@ -77,21 +77,9 @@ static int validate_array_init(const policydb_t *p, validate_t flavors[]) > if (validate_init(&flavors[SYM_ROLES], p->p_role_val_to_name, > p->p_roles.nprim)) > goto bad; > - if (p->policy_type != POLICY_KERN || > - p->policyvers < POLICYDB_VERSION_AVTAB || > - p->policyvers > POLICYDB_VERSION_PERMISSIVE) { > - if (validate_init(&flavors[SYM_TYPES], p->p_type_val_to_name, > - p->p_types.nprim)) > - goto bad; > - } else { > - /* > - * For policy versions between 20 and 23, attributes exist in the policy, > - * but they only exist in the type_attr_map, so there will be references > - * to gaps and we just have to treat this case as if there were no gaps. > - */ > - flavors[SYM_TYPES].nprim = p->p_types.nprim; > - ebitmap_init(&flavors[SYM_TYPES].gaps); > - } > + if (validate_init(&flavors[SYM_TYPES], p->p_type_val_to_name, > + p->p_types.nprim)) > + goto bad; > if (validate_init(&flavors[SYM_USERS], p->p_user_val_to_name, > p->p_users.nprim)) > goto bad; > @@ -954,19 +942,10 @@ static int validate_datum_array_gaps(sepol_handle_t *handle, > goto bad; > } > > - /* > - * For policy versions between 20 and 23, attributes exist in the policy, > - * but only in the type_attr_map, so all gaps must be assumed to be valid. > - */ > - if (p->policy_type != POLICY_KERN || > - p->policyvers < POLICYDB_VERSION_AVTAB || > - p->policyvers > POLICYDB_VERSION_PERMISSIVE) { > - for (i = 0; i < p->p_types.nprim; i++) { > - if (bool_xnor(p->type_val_to_struct[i], > - ebitmap_get_bit(&flavors[SYM_TYPES].gaps, > - i))) > - goto bad; > - } > + for (i = 0; i < p->p_types.nprim; i++) { > + if (bool_xnor(p->type_val_to_struct[i], > + ebitmap_get_bit(&flavors[SYM_TYPES].gaps, i))) > + goto bad; > } > > for (i = 0; i < p->p_users.nprim; i++) { > @@ -1994,8 +1973,6 @@ static int validate_properties(sepol_handle_t *handle, const policydb_t *p) > if (p->policyvers < POLICYDB_VERSION_MIN || > p->policyvers > POLICYDB_VERSION_MAX) > goto bad; > - if (p->mls && p->policyvers < POLICYDB_VERSION_MLS) > - goto bad; > break; > case POLICY_BASE: > case POLICY_MOD: > @@ -2086,10 +2063,8 @@ int policydb_validate(sepol_handle_t *handle, const policydb_t *p) > if (p->policy_type == POLICY_KERN) { > if (validate_avtab(handle, &p->te_avtab, p, flavors)) > goto bad; > - if (p->policyvers >= POLICYDB_VERSION_BOOL) > - if (validate_cond_list(handle, p->cond_list, p, > - flavors)) > - goto bad; > + if (validate_cond_list(handle, p->cond_list, p, flavors)) > + goto bad; > if (validate_role_transes(handle, p->role_tr, flavors)) > goto bad; > if (validate_role_allows(handle, p->role_allow, flavors)) > diff --git a/libsepol/src/write.c b/libsepol/src/write.c > index adec6caf..4e180ef3 100644 > --- a/libsepol/src/write.c > +++ b/libsepol/src/write.c > @@ -92,126 +92,15 @@ static int ebitmap_write(ebitmap_t *e, struct policy_file *fp) > return POLICYDB_SUCCESS; > } > > -/* Ordering of datums in the original avtab format in the policy file. */ > -static uint16_t spec_order[] = { AVTAB_ALLOWED, AVTAB_AUDITDENY, > - AVTAB_AUDITALLOW, AVTAB_TRANSITION, > - AVTAB_CHANGE, AVTAB_MEMBER }; > - > static int avtab_write_item(policydb_t *p, avtab_ptr_t cur, > - struct policy_file *fp, unsigned merge, > - unsigned commit, unsigned conditional, > - uint32_t *nel) > + struct policy_file *fp, unsigned conditional) > { > - avtab_ptr_t node; > uint8_t buf8; > uint16_t buf16[4]; > - uint32_t buf32[10], lookup, val; > - size_t items, items2; > - unsigned set; > - unsigned int oldvers = (p->policy_type == POLICY_KERN && > - p->policyvers < POLICYDB_VERSION_AVTAB); > + uint32_t buf32[10]; > + size_t items; > unsigned int i; > > - if (oldvers) { > - /* Generate the old avtab format. > - Requires merging similar entries if uncond avtab. */ > - if (merge) { > - if (cur->merged) > - return POLICYDB_SUCCESS; /* already merged by prior merge */ > - } > - > - items = 1; /* item 0 is used for the item count */ > - val = cur->key.source_type; > - buf32[items++] = cpu_to_le32(val); > - val = cur->key.target_type; > - buf32[items++] = cpu_to_le32(val); > - val = cur->key.target_class; > - buf32[items++] = cpu_to_le32(val); > - > - val = cur->key.specified & ~AVTAB_ENABLED; > - if (cur->key.specified & AVTAB_ENABLED) > - val |= AVTAB_ENABLED_OLD; > - set = 1; > - > - if (merge) { > - /* Merge specifier values for all similar (av or type) > - entries that have the same key. */ > - if (val & AVTAB_AV) > - lookup = AVTAB_AV; > - else if (val & AVTAB_TYPE) > - lookup = AVTAB_TYPE; > - else > - return POLICYDB_ERROR; > - for (node = avtab_search_node_next(cur, lookup); node; > - node = avtab_search_node_next(node, lookup)) { > - val |= (node->key.specified & ~AVTAB_ENABLED); > - set++; > - if (node->key.specified & AVTAB_ENABLED) > - val |= AVTAB_ENABLED_OLD; > - } > - } > - > - if (!(val & (AVTAB_AV | AVTAB_TYPE))) { > - ERR(fp->handle, "null entry"); > - return POLICYDB_ERROR; > - } > - if ((val & AVTAB_AV) && (val & AVTAB_TYPE)) { > - ERR(fp->handle, "entry has both access " > - "vectors and types"); > - return POLICYDB_ERROR; > - } > - > - buf32[items++] = cpu_to_le32(val); > - > - if (merge) { > - /* Include datums for all similar (av or type) > - entries that have the same key. */ > - for (i = 0; > - i < (sizeof(spec_order) / sizeof(spec_order[0])); > - i++) { > - if (val & spec_order[i]) { > - if (cur->key.specified & spec_order[i]) > - node = cur; > - else { > - node = avtab_search_node_next( > - cur, spec_order[i]); > - if (nel) > - (*nel)--; /* one less node */ > - } > - > - if (!node) { > - ERR(fp->handle, "missing node"); > - return POLICYDB_ERROR; > - } > - buf32[items++] = > - cpu_to_le32(node->datum.data); > - set--; > - node->merged = 1; > - } > - } > - } else { > - buf32[items++] = cpu_to_le32(cur->datum.data); > - cur->merged = 1; > - set--; > - } > - > - if (set) { > - ERR(fp->handle, "data count wrong"); > - return POLICYDB_ERROR; > - } > - > - buf32[0] = cpu_to_le32(items - 1); > - > - if (commit) { > - /* Commit this item to the policy file. */ > - items2 = put_entry(buf32, sizeof(uint32_t), items, fp); > - if (items != items2) > - return POLICYDB_ERROR; > - } > - > - return POLICYDB_SUCCESS; > - } > - > /* Generate the new avtab format. */ > buf16[0] = cpu_to_le16(cur->key.source_type); > buf16[1] = cpu_to_le16(cur->key.target_type); > @@ -271,86 +160,30 @@ static int avtab_write_item(policydb_t *p, avtab_ptr_t cur, > return POLICYDB_SUCCESS; > } > > -static inline void avtab_reset_merged(avtab_t *a) > -{ > - unsigned int i; > - avtab_ptr_t cur; > - for (i = 0; i < a->nslot; i++) { > - for (cur = a->htable[i]; cur; cur = cur->next) > - cur->merged = 0; > - } > -} > - > static int avtab_write(struct policydb *p, avtab_t *a, struct policy_file *fp) > { > unsigned int i; > int rc; > - avtab_t expa; > avtab_ptr_t cur; > uint32_t nel; > size_t items; > - unsigned int oldvers = (p->policy_type == POLICY_KERN && > - p->policyvers < POLICYDB_VERSION_AVTAB); > - > - if (oldvers) { > - /* Old avtab format. > - First, we need to expand attributes. Then, we need to > - merge similar entries, so we need to track merged nodes > - and compute the final nel. */ > - if (avtab_init(&expa)) > - return POLICYDB_ERROR; > - if (expand_avtab(p, a, &expa)) { > - rc = -1; > - goto out; > - } > - a = &expa; > - avtab_reset_merged(a); > - nel = a->nel; > - } else { > - /* New avtab format. nel is good to go. */ > - nel = cpu_to_le32(a->nel); > - items = put_entry(&nel, sizeof(uint32_t), 1, fp); > - if (items != 1) > - return POLICYDB_ERROR; > - } > + > + nel = cpu_to_le32(a->nel); > + items = put_entry(&nel, sizeof(uint32_t), 1, fp); > + if (items != 1) > + return POLICYDB_ERROR; > > for (i = 0; i < a->nslot; i++) { > for (cur = a->htable[i]; cur; cur = cur->next) { > - /* If old format, compute final nel. > - If new format, write out the items. */ > - if (avtab_write_item(p, cur, fp, 1, !oldvers, 0, > - &nel)) { > + if (avtab_write_item(p, cur, fp, 0)) { > rc = -1; > goto out; > } > } > } > > - if (oldvers) { > - /* Old avtab format. > - Write the computed nel value, then write the items. */ > - nel = cpu_to_le32(nel); > - items = put_entry(&nel, sizeof(uint32_t), 1, fp); > - if (items != 1) { > - rc = -1; > - goto out; > - } > - avtab_reset_merged(a); > - for (i = 0; i < a->nslot; i++) { > - for (cur = a->htable[i]; cur; cur = cur->next) { > - if (avtab_write_item(p, cur, fp, 1, 1, 0, > - NULL)) { > - rc = -1; > - goto out; > - } > - } > - } > - } > - > rc = 0; > out: > - if (oldvers) > - avtab_destroy(&expa); > return rc; > } > > @@ -770,21 +603,10 @@ static int cond_write_av_list(policydb_t *p, cond_av_list_t *list, > struct policy_file *fp) > { > uint32_t buf[4]; > - cond_av_list_t *cur_list, *new_list = NULL; > - avtab_t expa; > + cond_av_list_t *cur_list; > uint32_t len, items; > - unsigned int oldvers = (p->policy_type == POLICY_KERN && > - p->policyvers < POLICYDB_VERSION_AVTAB); > int rc = -1; > > - if (oldvers) { > - if (avtab_init(&expa)) > - return POLICYDB_ERROR; > - if (expand_cond_av_list(p, list, &new_list, &expa)) > - goto out; > - list = new_list; > - } > - > len = 0; > for (cur_list = list; cur_list != NULL; cur_list = cur_list->next) { > if (cur_list->node->parse_context) > @@ -803,18 +625,12 @@ static int cond_write_av_list(policydb_t *p, cond_av_list_t *list, > > for (cur_list = list; cur_list != NULL; cur_list = cur_list->next) { > if (cur_list->node->parse_context) > - if (avtab_write_item(p, cur_list->node, fp, 0, 1, 1, > - NULL)) > + if (avtab_write_item(p, cur_list->node, fp, 1)) > goto out; > } > > rc = 0; > out: > - if (oldvers) { > - cond_av_list_destroy(new_list); > - avtab_destroy(&expa); > - } > - > return rc; > } > > @@ -912,8 +728,7 @@ static int context_write(struct policydb *p, context_struct_t *c, > items2 = put_entry(buf, sizeof(uint32_t), items, fp); > if (items2 != items) > return POLICYDB_ERROR; > - if ((p->policyvers >= POLICYDB_VERSION_MLS && > - p->policy_type == POLICY_KERN) || > + if ((p->policy_type == POLICY_KERN) || > (p->policyvers >= MOD_POLICYDB_VERSION_MLS && > p->policy_type == POLICY_BASE)) > if (mls_write_range_helper(&c->range, fp)) > @@ -1086,8 +901,7 @@ static int class_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) > if (write_cons_helper(p, cladatum->constraints, 0, fp)) > return POLICYDB_ERROR; > > - if ((p->policy_type == POLICY_KERN && > - p->policyvers >= POLICYDB_VERSION_VALIDATETRANS) || > + if ((p->policy_type == POLICY_KERN) || > (p->policy_type == POLICY_BASE && > p->policyvers >= MOD_POLICYDB_VERSION_VALIDATETRANS)) { > /* write out the validatetrans rule */ > @@ -1231,15 +1045,6 @@ static int type_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) > > typdatum = (type_datum_t *)datum; > > - /* > - * The kernel policy version less than 24 (= POLICYDB_VERSION_BOUNDARY) > - * does not support to load entries of attribute, so we skip to write it. > - */ > - if (p->policy_type == POLICY_KERN && > - p->policyvers < POLICYDB_VERSION_BOUNDARY && > - typdatum->flavor == TYPE_ATTRIB) > - return POLICYDB_SUCCESS; > - > len = strlen(key); > items = 0; > buf[items++] = cpu_to_le32(len); > @@ -1349,8 +1154,7 @@ static int user_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) > return POLICYDB_ERROR; > } > > - if ((p->policyvers >= POLICYDB_VERSION_MLS && > - p->policy_type == POLICY_KERN) || > + if ((p->policy_type == POLICY_KERN) || > (p->policyvers >= MOD_POLICYDB_VERSION_MLS && > p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS && > p->policy_type == POLICY_MOD) || > @@ -1759,8 +1563,7 @@ static int range_write(policydb_t *p, struct policy_file *fp) > { > size_t items; > uint32_t buf[2]; > - int new_rangetr = (p->policy_type == POLICY_KERN && > - p->policyvers >= POLICYDB_VERSION_RANGETRANS); > + int new_rangetr = (p->policy_type == POLICY_KERN); > struct rangetrans_write_args args; > int rc; > > @@ -2214,19 +2017,6 @@ err: > return rc; > } > > -static int type_attr_uncount(hashtab_key_t key __attribute__((unused)), > - hashtab_datum_t datum, void *args) > -{ > - type_datum_t *typdatum = datum; > - uint32_t *p_nel = args; > - > - if (typdatum->flavor == TYPE_ATTRIB) { > - /* uncount attribute from total number of types */ > - (*p_nel)--; > - } > - return 0; > -} > - > static int role_attr_uncount(hashtab_key_t key __attribute__((unused)), > hashtab_datum_t datum, void *args) > { > @@ -2262,9 +2052,7 @@ int policydb_write(policydb_t *p, struct policy_file *fp) > > config = 0; > if (p->mls) { > - if ((p->policyvers < POLICYDB_VERSION_MLS && > - p->policy_type == POLICY_KERN) || > - (p->policyvers < MOD_POLICYDB_VERSION_MLS && > + if ((p->policyvers < MOD_POLICYDB_VERSION_MLS && > p->policy_type == POLICY_BASE) || > (p->policyvers < MOD_POLICYDB_VERSION_MLS && > p->policy_type == POLICY_MOD)) { > @@ -2344,8 +2132,7 @@ int policydb_write(policydb_t *p, struct policy_file *fp) > return POLICYDB_ERROR; > } > > - if ((p->policyvers >= POLICYDB_VERSION_POLCAP && > - p->policy_type == POLICY_KERN) || > + if ((p->policy_type == POLICY_KERN) || > (p->policyvers >= MOD_POLICYDB_VERSION_POLCAP && > p->policy_type == POLICY_BASE) || > (p->policyvers >= MOD_POLICYDB_VERSION_POLCAP && > @@ -2355,18 +2142,7 @@ int policydb_write(policydb_t *p, struct policy_file *fp) > } > > if (p->policy_type == POLICY_KERN) { > - if (p->policyvers < POLICYDB_VERSION_PERMISSIVE) { > - ebitmap_node_t *tnode; > - > - ebitmap_for_each_positive_bit(&p->permissive_map, tnode, > - i) { > - WARN(fp->handle, > - "Warning! Policy version %d cannot " > - "support permissive types, but some were defined", > - p->policyvers); > - break; > - } > - } else if (ebitmap_write(&p->permissive_map, fp) == -1) > + if (ebitmap_write(&p->permissive_map, fp) == -1) > return POLICYDB_ERROR; > > if (p->policyvers < POLICYDB_VERSION_NEVERAUDIT) { > @@ -2389,19 +2165,6 @@ int policydb_write(policydb_t *p, struct policy_file *fp) > buf[0] = cpu_to_le32(p->symtab[i].nprim); > buf[1] = p->symtab[i].table->nel; > > - /* > - * A special case when writing type/attribute symbol table. > - * The kernel policy version less than 24 does not support > - * to load entries of attribute, so we have to re-calculate > - * the actual number of types except for attributes. > - */ > - if (i == SYM_TYPES && > - p->policyvers < POLICYDB_VERSION_BOUNDARY && > - 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 > @@ -2426,15 +2189,8 @@ int policydb_write(policydb_t *p, struct policy_file *fp) > if (p->policy_type == POLICY_KERN) { > if (avtab_write(p, &p->te_avtab, fp)) > return POLICYDB_ERROR; > - if (p->policyvers < POLICYDB_VERSION_BOOL) { > - if (p->p_bools.nprim) > - WARN(fp->handle, > - "Discarding " > - "booleans and conditional rules"); > - } else { > - if (cond_write_list(p, p->cond_list, fp)) > - return POLICYDB_ERROR; > - } > + if (cond_write_list(p, p->cond_list, fp)) > + return POLICYDB_ERROR; > if (role_trans_write(p, fp)) > return POLICYDB_ERROR; > if (role_allow_write(p->role_allow, fp)) > @@ -2466,8 +2222,7 @@ int policydb_write(policydb_t *p, struct policy_file *fp) > return POLICYDB_ERROR; > } > > - if ((p->policyvers >= POLICYDB_VERSION_MLS && > - p->policy_type == POLICY_KERN) || > + if ((p->policy_type == POLICY_KERN) || > (p->policyvers >= MOD_POLICYDB_VERSION_MLS && > p->policyvers < MOD_POLICYDB_VERSION_RANGETRANS && > p->policy_type == POLICY_BASE)) { > @@ -2476,8 +2231,7 @@ int policydb_write(policydb_t *p, struct policy_file *fp) > } > } > > - if (p->policy_type == POLICY_KERN && > - p->policyvers >= POLICYDB_VERSION_AVTAB) { > + if (p->policy_type == POLICY_KERN) { > for (i = 0; i < p->p_types.nprim; i++) { > if (ebitmap_write(&p->type_attr_map[i], fp) == -1) > return POLICYDB_ERROR; > diff --git a/libsepol/tests/test-downgrade.c b/libsepol/tests/test-downgrade.c > index bf747780..5f879b39 100644 > --- a/libsepol/tests/test-downgrade.c > +++ b/libsepol/tests/test-downgrade.c > @@ -155,13 +155,6 @@ int do_downgrade_test(int mls) > /* Write out modified binary policy */ > if (write_binary_policy(POLICY_BIN_LO, &policydb) != > 0) { > - /* > - * Error from MLS to pre-MLS is expected due > - * to MLS re-implementation in version 19. > - */ > - if (mls && lo < POLICYDB_VERSION_MLS) > - continue; > - > fprintf(stderr, > "error writing %spolicy binary, version %d (downgraded from %d)\n", > mls ? "mls " : "", lo, hi); > -- > 2.55.0 >