.sym_num = SYM_NUM,
.ocon_num = OCON_NUM,
},
+ {
+ .version = POLICYDB_VERSION_FILENAME_TRANS,
+ .sym_num = SYM_NUM,
+ .ocon_num = OCON_NUM,
+ },
+ {
+ .version = POLICYDB_VERSION_ROLETRANS,
+ .sym_num = SYM_NUM,
+ .ocon_num = OCON_NUM,
+ },
};
static struct policydb_compat_info *policydb_lookup_compat(int version)
if (!p->range_tr)
goto out;
+ ebitmap_init(&p->filename_trans_ttypes);
ebitmap_init(&p->policycaps);
ebitmap_init(&p->permissive_map);
};
#ifdef DEBUG_HASHES
-static void symtab_hash_eval(struct symtab *s)
+static void hash_eval(struct hashtab *h, const char *hash_name)
{
- int i;
-
- for (i = 0; i < SYM_NUM; i++) {
- struct hashtab *h = s[i].table;
- struct hashtab_info info;
+ struct hashtab_info info;
- hashtab_stat(h, &info);
- printk(KERN_DEBUG "SELinux: %s: %d entries and %d/%d buckets used, "
- "longest chain length %d\n", symtab_name[i], h->nel,
- info.slots_used, h->size, info.max_chain_len);
- }
+ hashtab_stat(h, &info);
+ printk(KERN_DEBUG "SELinux: %s: %d entries and %d/%d buckets used, "
+ "longest chain length %d\n", hash_name, h->nel,
+ info.slots_used, h->size, info.max_chain_len);
}
-static void rangetr_hash_eval(struct hashtab *h)
+static void symtab_hash_eval(struct symtab *s)
{
- struct hashtab_info info;
+ int i;
- hashtab_stat(h, &info);
- printk(KERN_DEBUG "SELinux: rangetr: %d entries and %d/%d buckets used, "
- "longest chain length %d\n", h->nel,
- info.slots_used, h->size, info.max_chain_len);
+ for (i = 0; i < SYM_NUM; i++)
+ hash_eval(s[i].table, symtab_name[i]);
}
+
#else
-static inline void rangetr_hash_eval(struct hashtab *h)
+static inline void hash_eval(struct hashtab *h, char *hash_name)
{
}
#endif
int i;
struct role_allow *ra, *lra = NULL;
struct role_trans *tr, *ltr = NULL;
+ struct filename_trans *ft, *nft;
for (i = 0; i < SYM_NUM; i++) {
cond_resched();
}
flex_array_free(p->type_attr_map_array);
}
+
+ ft = p->filename_trans;
+ while (ft) {
+ nft = ft->next;
+ kfree(ft->name);
+ kfree(ft);
+ ft = nft;
+ }
+
+ ebitmap_destroy(&p->filename_trans_ttypes);
ebitmap_destroy(&p->policycaps);
ebitmap_destroy(&p->permissive_map);
rt = NULL;
r = NULL;
}
- rangetr_hash_eval(p->range_tr);
+ hash_eval(p->range_tr, "rangetr");
rc = 0;
out:
kfree(rt);
return rc;
}
+static int filename_trans_read(struct policydb *p, void *fp)
+{
+ struct filename_trans *ft, *last;
+ u32 nel, len;
+ char *name;
+ __le32 buf[4];
+ int rc, i;
+
+ if (p->policyvers < POLICYDB_VERSION_FILENAME_TRANS)
+ return 0;
+
+ rc = next_entry(buf, fp, sizeof(u32));
+ if (rc)
+ goto out;
+ nel = le32_to_cpu(buf[0]);
+
+ last = p->filename_trans;
+ while (last && last->next)
+ last = last->next;
+
+ for (i = 0; i < nel; i++) {
+ rc = -ENOMEM;
+ ft = kzalloc(sizeof(*ft), GFP_KERNEL);
+ if (!ft)
+ goto out;
+
+ /* add it to the tail of the list */
+ if (!last)
+ p->filename_trans = ft;
+ else
+ last->next = ft;
+ last = ft;
+
+ /* length of the path component string */
+ rc = next_entry(buf, fp, sizeof(u32));
+ if (rc)
+ goto out;
+ len = le32_to_cpu(buf[0]);
+
+ rc = -ENOMEM;
+ name = kmalloc(len + 1, GFP_KERNEL);
+ if (!name)
+ goto out;
+
+ ft->name = name;
+
+ /* path component string */
+ rc = next_entry(name, fp, len);
+ if (rc)
+ goto out;
+ name[len] = 0;
+
+ rc = next_entry(buf, fp, sizeof(u32) * 4);
+ if (rc)
+ goto out;
+
+ ft->stype = le32_to_cpu(buf[0]);
+ ft->ttype = le32_to_cpu(buf[1]);
+ ft->tclass = le32_to_cpu(buf[2]);
+ ft->otype = le32_to_cpu(buf[3]);
+
+ rc = ebitmap_set_bit(&p->filename_trans_ttypes, ft->ttype, 1);
+ if (rc)
+ goto out;
+ }
+ rc = 0;
+out:
+ return rc;
+}
+
static int genfs_read(struct policydb *p, void *fp)
{
int i, j, rc;
p->symtab[i].nprim = nprim;
}
+ rc = -EINVAL;
+ p->process_class = string_to_security_class(p, "process");
+ if (!p->process_class)
+ goto bad;
+
rc = avtab_read(&p->te_avtab, fp, p);
if (rc)
goto bad;
tr->role = le32_to_cpu(buf[0]);
tr->type = le32_to_cpu(buf[1]);
tr->new_role = le32_to_cpu(buf[2]);
+ if (p->policyvers >= POLICYDB_VERSION_ROLETRANS) {
+ rc = next_entry(buf, fp, sizeof(u32));
+ if (rc)
+ goto bad;
+ tr->tclass = le32_to_cpu(buf[0]);
+ } else
+ tr->tclass = p->process_class;
+
if (!policydb_role_isvalid(p, tr->role) ||
!policydb_type_isvalid(p, tr->type) ||
+ !policydb_class_isvalid(p, tr->tclass) ||
!policydb_role_isvalid(p, tr->new_role))
goto bad;
ltr = tr;
lra = ra;
}
- rc = policydb_index(p);
+ rc = filename_trans_read(p, fp);
if (rc)
goto bad;
- rc = -EINVAL;
- p->process_class = string_to_security_class(p, "process");
- if (!p->process_class)
+ rc = policydb_index(p);
+ if (rc)
goto bad;
rc = -EINVAL;
return 0;
}
-static int role_trans_write(struct role_trans *r, void *fp)
+static int role_trans_write(struct policydb *p, void *fp)
{
+ struct role_trans *r = p->role_tr;
struct role_trans *tr;
u32 buf[3];
size_t nel;
rc = put_entry(buf, sizeof(u32), 3, fp);
if (rc)
return rc;
+ if (p->policyvers >= POLICYDB_VERSION_ROLETRANS) {
+ buf[0] = cpu_to_le32(tr->tclass);
+ rc = put_entry(buf, sizeof(u32), 1, fp);
+ if (rc)
+ return rc;
+ }
}
return 0;
return 0;
}
-static int range_count(void *key, void *data, void *ptr)
+static int hashtab_cnt(void *key, void *data, void *ptr)
{
int *cnt = ptr;
*cnt = *cnt + 1;
/* count the number of entries in the hashtab */
nel = 0;
- rc = hashtab_map(p->range_tr, range_count, &nel);
+ rc = hashtab_map(p->range_tr, hashtab_cnt, &nel);
if (rc)
return rc;
return 0;
}
+static int filename_trans_write(struct policydb *p, void *fp)
+{
+ struct filename_trans *ft;
+ u32 len, nel = 0;
+ __le32 buf[4];
+ int rc;
+
+ for (ft = p->filename_trans; ft; ft = ft->next)
+ nel++;
+
+ buf[0] = cpu_to_le32(nel);
+ rc = put_entry(buf, sizeof(u32), 1, fp);
+ if (rc)
+ return rc;
+
+ for (ft = p->filename_trans; ft; ft = ft->next) {
+ len = strlen(ft->name);
+ buf[0] = cpu_to_le32(len);
+ rc = put_entry(buf, sizeof(u32), 1, fp);
+ if (rc)
+ return rc;
+
+ rc = put_entry(ft->name, sizeof(char), len, fp);
+ if (rc)
+ return rc;
+
+ buf[0] = ft->stype;
+ buf[1] = ft->ttype;
+ buf[2] = ft->tclass;
+ buf[3] = ft->otype;
+
+ rc = put_entry(buf, sizeof(u32), 4, fp);
+ if (rc)
+ return rc;
+ }
+ return 0;
+}
/*
* Write the configuration data in a policy database
* structure to a policy database binary representation
if (rc)
return rc;
- rc = role_trans_write(p->role_tr, fp);
+ rc = role_trans_write(p, fp);
if (rc)
return rc;
if (rc)
return rc;
+ rc = filename_trans_write(p, fp);
+ if (rc)
+ return rc;
+
rc = ocontext_write(p, info, fp);
if (rc)
return rc;