-void mls_user_destroy(struct user_datum *usrdatum)
-{
- struct mls_range_list *rnode, *rtmp;
- rnode = usrdatum->ranges;
- while (rnode) {
- rtmp = rnode;
- rnode = rnode->next;
- ebitmap_destroy(&rtmp->range.level[0].cat);
- ebitmap_destroy(&rtmp->range.level[1].cat);
- kfree(rtmp);
- }
-}
-
-int mls_read_perm(struct perm_datum *perdatum, void *fp)
-{
- u32 *buf;
-
- buf = next_entry(fp, sizeof(u32));
- if (!buf)
- return -EINVAL;
- perdatum->base_perms = le32_to_cpu(buf[0]);
- return 0;
-}
-
-/*
- * Read a MLS level structure from a policydb binary
- * representation file.
- */
-struct mls_level *mls_read_level(void *fp)
-{
- struct mls_level *l;
- u32 *buf;
-
- l = kmalloc(sizeof(*l), GFP_ATOMIC);
- if (!l) {
- printk(KERN_ERR "security: mls: out of memory\n");
- return NULL;
- }
- memset(l, 0, sizeof(*l));
-
- buf = next_entry(fp, sizeof(u32));
- if (!buf) {
- printk(KERN_ERR "security: mls: truncated level\n");
- goto bad;
- }
- l->sens = cpu_to_le32(buf[0]);
-
- if (ebitmap_read(&l->cat, fp)) {
- printk(KERN_ERR "security: mls: error reading level "
- "categories\n");
- goto bad;
- }
- return l;
-
-bad:
- kfree(l);
- return NULL;
-}
-
-
-/*
- * Read a MLS range structure from a policydb binary
- * representation file.
- */
-static int mls_read_range_helper(struct mls_range *r, void *fp)
-{
- u32 *buf;
- int items, rc = -EINVAL;
-
- buf = next_entry(fp, sizeof(u32));
- if (!buf)
- goto out;
-
- items = le32_to_cpu(buf[0]);
- buf = next_entry(fp, sizeof(u32) * items);
- if (!buf) {
- printk(KERN_ERR "security: mls: truncated range\n");
- goto out;
- }
- r->level[0].sens = le32_to_cpu(buf[0]);
- if (items > 1) {
- r->level[1].sens = le32_to_cpu(buf[1]);
- } else {
- r->level[1].sens = r->level[0].sens;
- }
-
- rc = ebitmap_read(&r->level[0].cat, fp);
- if (rc) {
- printk(KERN_ERR "security: mls: error reading low "
- "categories\n");
- goto out;
- }
- if (items > 1) {
- rc = ebitmap_read(&r->level[1].cat, fp);
- if (rc) {
- printk(KERN_ERR "security: mls: error reading high "
- "categories\n");
- goto bad_high;
- }
- } else {
- rc = ebitmap_cpy(&r->level[1].cat, &r->level[0].cat);
- if (rc) {
- printk(KERN_ERR "security: mls: out of memory\n");
- goto bad_high;
- }
- }
-
- rc = 0;
-out:
- return rc;
-bad_high:
- ebitmap_destroy(&r->level[0].cat);
- goto out;
-}
-
-int mls_read_range(struct context *c, void *fp)
-{
- return mls_read_range_helper(&c->range, fp);
-}
-
-
-/*
- * Read a MLS perms structure from a policydb binary
- * representation file.
- */
-int mls_read_class(struct class_datum *cladatum, void *fp)
-{
- struct mls_perms *p = &cladatum->mlsperms;
- u32 *buf;
-
- buf = next_entry(fp, sizeof(u32)*4);
- if (!buf) {
- printk(KERN_ERR "security: mls: truncated mls permissions\n");
- return -EINVAL;
- }
- p->read = le32_to_cpu(buf[0]);
- p->readby = le32_to_cpu(buf[1]);
- p->write = le32_to_cpu(buf[2]);
- p->writeby = le32_to_cpu(buf[3]);
- return 0;
-}
-
-int mls_read_user(struct user_datum *usrdatum, void *fp)
-{
- struct mls_range_list *r, *l;
- int rc = 0;
- u32 nel, i;
- u32 *buf;
-
- buf = next_entry(fp, sizeof(u32));
- if (!buf) {
- rc = -EINVAL;
- goto out;
- }
- nel = le32_to_cpu(buf[0]);
- l = NULL;
- for (i = 0; i < nel; i++) {
- r = kmalloc(sizeof(*r), GFP_ATOMIC);
- if (!r) {
- rc = -ENOMEM;
- goto out;
- }
- memset(r, 0, sizeof(*r));
-
- rc = mls_read_range_helper(&r->range, fp);
- if (rc) {
- kfree(r);
- goto out;
- }
-
- if (l)
- l->next = r;
- else
- usrdatum->ranges = r;
- l = r;
- }
-out:
- return rc;
-}
-
-int mls_read_nlevels(struct policydb *p, void *fp)
-{
- u32 *buf;
-
- buf = next_entry(fp, sizeof(u32));
- if (!buf)
- return -EINVAL;
- p->nlevels = le32_to_cpu(buf[0]);
- return 0;
-}
-
-int mls_read_trusted(struct policydb *p, void *fp)
-{
- int rc = 0;
-
- rc = ebitmap_read(&p->trustedreaders, fp);
- if (rc)
- goto out;
- rc = ebitmap_read(&p->trustedwriters, fp);
- if (rc)
- goto bad;
- rc = ebitmap_read(&p->trustedobjects, fp);
- if (rc)
- goto bad2;
-out:
- return rc;
-bad2:
- ebitmap_destroy(&p->trustedwriters);
-bad:
- ebitmap_destroy(&p->trustedreaders);
- goto out;
-}
-
-int sens_index(void *key, void *datum, void *datap)
-{
- struct policydb *p;
- struct level_datum *levdatum;
-
-
- levdatum = datum;
- p = datap;
-
- if (!levdatum->isalias)
- p->p_sens_val_to_name[levdatum->level->sens - 1] = key;
-
- return 0;
-}
-
-int cat_index(void *key, void *datum, void *datap)
-{
- struct policydb *p;
- struct cat_datum *catdatum;
-
-
- catdatum = datum;
- p = datap;
-
-
- if (!catdatum->isalias)
- p->p_cat_val_to_name[catdatum->value - 1] = key;
-
- return 0;
-}
-
-int sens_destroy(void *key, void *datum, void *p)
-{
- struct level_datum *levdatum;
-
- kfree(key);
- levdatum = datum;
- if (!levdatum->isalias) {
- ebitmap_destroy(&levdatum->level->cat);
- kfree(levdatum->level);
- }
- kfree(datum);
- return 0;
-}
-
-int cat_destroy(void *key, void *datum, void *p)
-{
- kfree(key);
- kfree(datum);
- return 0;
-}
-
-int sens_read(struct policydb *p, struct hashtab *h, void *fp)
-{
- char *key = NULL;
- struct level_datum *levdatum;
- int rc;
- u32 *buf, len;
-
- levdatum = kmalloc(sizeof(*levdatum), GFP_ATOMIC);
- if (!levdatum) {
- rc = -ENOMEM;
- goto out;
- }
- memset(levdatum, 0, sizeof(*levdatum));
-
- buf = next_entry(fp, sizeof(u32)*2);
- if (!buf) {
- rc = -EINVAL;
- goto bad;
- }
-
- len = le32_to_cpu(buf[0]);
- levdatum->isalias = le32_to_cpu(buf[1]);
-
- buf = next_entry(fp, len);
- if (!buf) {
- rc = -EINVAL;
- goto bad;
- }
- key = kmalloc(len + 1,GFP_ATOMIC);
- if (!key) {
- rc = -ENOMEM;
- goto bad;
- }
- memcpy(key, buf, len);
- key[len] = 0;
-
- levdatum->level = mls_read_level(fp);
- if (!levdatum->level) {
- rc = -EINVAL;
- goto bad;
- }
-
- rc = hashtab_insert(h, key, levdatum);
- if (rc)
- goto bad;
-out:
- return rc;
-bad:
- sens_destroy(key, levdatum, NULL);
- goto out;
-}
-
-
-int cat_read(struct policydb *p, struct hashtab *h, void *fp)
-{
- char *key = NULL;
- struct cat_datum *catdatum;
- int rc;
- u32 *buf, len;
-
- catdatum = kmalloc(sizeof(*catdatum), GFP_ATOMIC);
- if (!catdatum) {
- rc = -ENOMEM;
- goto out;
- }
- memset(catdatum, 0, sizeof(*catdatum));
-
- buf = next_entry(fp, sizeof(u32)*3);
- if (!buf) {
- rc = -EINVAL;
- goto bad;
- }
-
- len = le32_to_cpu(buf[0]);
- catdatum->value = le32_to_cpu(buf[1]);
- catdatum->isalias = le32_to_cpu(buf[2]);
-
- buf = next_entry(fp, len);
- if (!buf) {
- rc = -EINVAL;
- goto bad;
- }
- key = kmalloc(len + 1,GFP_ATOMIC);
- if (!key) {
- rc = -ENOMEM;
- goto bad;
- }
- memcpy(key, buf, len);
- key[len] = 0;
-
- rc = hashtab_insert(h, key, catdatum);
- if (rc)
- goto bad;
-out:
- return rc;
-
-bad:
- cat_destroy(key, catdatum, NULL);
- goto out;
-}