]> Pileus Git - ~andy/linux/blobdiff - security/selinux/ss/policydb.c
Merge branch 'master' of git://git.infradead.org/users/pcmoore/selinux into next
[~andy/linux] / security / selinux / ss / policydb.c
index f6195ebde3c94eef0cdf1cf92933246069b25059..dc4011643b55022fe622260e83244bbaa8f1575f 100644 (file)
@@ -143,6 +143,11 @@ static struct policydb_compat_info policydb_compat[] = {
                .sym_num        = SYM_NUM,
                .ocon_num       = OCON_NUM,
        },
+       {
+               .version        = POLICYDB_VERSION_CONSTRAINT_NAMES,
+               .sym_num        = SYM_NUM,
+               .ocon_num       = OCON_NUM,
+       },
 };
 
 static struct policydb_compat_info *policydb_lookup_compat(int version)
@@ -613,6 +618,19 @@ static int common_destroy(void *key, void *datum, void *p)
        return 0;
 }
 
+static void constraint_expr_destroy(struct constraint_expr *expr)
+{
+       if (expr) {
+               ebitmap_destroy(&expr->names);
+               if (expr->type_names) {
+                       ebitmap_destroy(&expr->type_names->types);
+                       ebitmap_destroy(&expr->type_names->negset);
+                       kfree(expr->type_names);
+               }
+               kfree(expr);
+       }
+}
+
 static int cls_destroy(void *key, void *datum, void *p)
 {
        struct class_datum *cladatum;
@@ -628,10 +646,9 @@ static int cls_destroy(void *key, void *datum, void *p)
                while (constraint) {
                        e = constraint->expr;
                        while (e) {
-                               ebitmap_destroy(&e->names);
                                etmp = e;
                                e = e->next;
-                               kfree(etmp);
+                               constraint_expr_destroy(etmp);
                        }
                        ctemp = constraint;
                        constraint = constraint->next;
@@ -642,16 +659,14 @@ static int cls_destroy(void *key, void *datum, void *p)
                while (constraint) {
                        e = constraint->expr;
                        while (e) {
-                               ebitmap_destroy(&e->names);
                                etmp = e;
                                e = e->next;
-                               kfree(etmp);
+                               constraint_expr_destroy(etmp);
                        }
                        ctemp = constraint;
                        constraint = constraint->next;
                        kfree(ctemp);
                }
-
                kfree(cladatum->comkey);
        }
        kfree(datum);
@@ -1156,8 +1171,34 @@ bad:
        return rc;
 }
 
-static int read_cons_helper(struct constraint_node **nodep, int ncons,
-                           int allowxtarget, void *fp)
+static void type_set_init(struct type_set *t)
+{
+       ebitmap_init(&t->types);
+       ebitmap_init(&t->negset);
+}
+
+static int type_set_read(struct type_set *t, void *fp)
+{
+       __le32 buf[1];
+       int rc;
+
+       if (ebitmap_read(&t->types, fp))
+               return -EINVAL;
+       if (ebitmap_read(&t->negset, fp))
+               return -EINVAL;
+
+       rc = next_entry(buf, fp, sizeof(u32));
+       if (rc < 0)
+               return -EINVAL;
+       t->flags = le32_to_cpu(buf[0]);
+
+       return 0;
+}
+
+
+static int read_cons_helper(struct policydb *p,
+                               struct constraint_node **nodep,
+                               int ncons, int allowxtarget, void *fp)
 {
        struct constraint_node *c, *lc;
        struct constraint_expr *e, *le;
@@ -1225,6 +1266,18 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
                                rc = ebitmap_read(&e->names, fp);
                                if (rc)
                                        return rc;
+                               if (p->policyvers >=
+                                       POLICYDB_VERSION_CONSTRAINT_NAMES) {
+                                               e->type_names = kzalloc(sizeof
+                                               (*e->type_names),
+                                               GFP_KERNEL);
+                                       if (!e->type_names)
+                                               return -ENOMEM;
+                                       type_set_init(e->type_names);
+                                       rc = type_set_read(e->type_names, fp);
+                                       if (rc)
+                                               return rc;
+                               }
                                break;
                        default:
                                return -EINVAL;
@@ -1301,7 +1354,7 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
                        goto bad;
        }
 
-       rc = read_cons_helper(&cladatum->constraints, ncons, 0, fp);
+       rc = read_cons_helper(p, &cladatum->constraints, ncons, 0, fp);
        if (rc)
                goto bad;
 
@@ -1311,7 +1364,8 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
                if (rc)
                        goto bad;
                ncons = le32_to_cpu(buf[0]);
-               rc = read_cons_helper(&cladatum->validatetrans, ncons, 1, fp);
+               rc = read_cons_helper(p, &cladatum->validatetrans,
+                               ncons, 1, fp);
                if (rc)
                        goto bad;
        }
@@ -2753,6 +2807,24 @@ static int common_write(void *vkey, void *datum, void *ptr)
        return 0;
 }
 
+static int type_set_write(struct type_set *t, void *fp)
+{
+       int rc;
+       __le32 buf[1];
+
+       if (ebitmap_write(&t->types, fp))
+               return -EINVAL;
+       if (ebitmap_write(&t->negset, fp))
+               return -EINVAL;
+
+       buf[0] = cpu_to_le32(t->flags);
+       rc = put_entry(buf, sizeof(u32), 1, fp);
+       if (rc)
+               return -EINVAL;
+
+       return 0;
+}
+
 static int write_cons_helper(struct policydb *p, struct constraint_node *node,
                             void *fp)
 {
@@ -2784,6 +2856,12 @@ static int write_cons_helper(struct policydb *p, struct constraint_node *node,
                                rc = ebitmap_write(&e->names, fp);
                                if (rc)
                                        return rc;
+                               if (p->policyvers >=
+                                       POLICYDB_VERSION_CONSTRAINT_NAMES) {
+                                       rc = type_set_write(e->type_names, fp);
+                                       if (rc)
+                                               return rc;
+                               }
                                break;
                        default:
                                break;