summaryrefslogtreecommitdiff
path: root/src/write.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/write.c')
-rw-r--r--src/write.c60
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;