security: update selinux
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / security / selinux / ss / policydb.c
index bcdca73033f3da87bfd3035fd9e9e40d4ad2a25f..8a07ac6416b325ec8486849aa3c8e26f82b077bf 100644 (file)
@@ -143,6 +143,16 @@ 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,
+       },
+       {
+               .version        = POLICYDB_VERSION_XPERMS_IOCTL,
+               .sym_num        = SYM_NUM,
+               .ocon_num       = OCON_NUM,
+       },
 };
 
 static struct policydb_compat_info *policydb_lookup_compat(int version)
@@ -613,6 +623,20 @@ 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 +652,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 +665,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 +1177,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 +1272,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 +1360,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 +1370,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;
        }
@@ -1455,6 +1515,8 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp)
                goto bad;
        return 0;
 bad:
+       panic("SELinux:Failed to type read");
+
        type_destroy(key, typdatum, NULL);
        return rc;
 }
@@ -2505,6 +2567,8 @@ int policydb_read(struct policydb *p, void *fp)
 out:
        return rc;
 bad:
+       panic("SELinux:Failed to load policy");
+
        policydb_destroy(p);
        goto out;
 }
@@ -2762,6 +2826,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)
 {
@@ -2793,6 +2875,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;