diff options
Diffstat (limited to 'src/write.c')
-rw-r--r-- | src/write.c | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/src/write.c b/src/write.c index 290e036..e34ab52 100644 --- a/src/write.c +++ b/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; |