diff options
Diffstat (limited to 'security/selinux/ss/policydb.c')
-rw-r--r-- | security/selinux/ss/policydb.c | 107 |
1 files changed, 80 insertions, 27 deletions
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index 785c33cf4864..0a758323a9cf 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -91,6 +91,11 @@ static struct policydb_compat_info policydb_compat[] = { .sym_num = SYM_NUM, .ocon_num = OCON_NUM, }, + { + .version = POLICYDB_VERSION_AVTAB, + .sym_num = SYM_NUM, + .ocon_num = OCON_NUM, + }, }; static struct policydb_compat_info *policydb_lookup_compat(int version) @@ -584,6 +589,9 @@ void policydb_destroy(struct policydb *p) struct ocontext *c, *ctmp; struct genfs *g, *gtmp; int i; + struct role_allow *ra, *lra = NULL; + struct role_trans *tr, *ltr = NULL; + struct range_trans *rt, *lrt = NULL; for (i = 0; i < SYM_NUM; i++) { hashtab_map(p->symtab[i].table, destroy_f[i], NULL); @@ -624,6 +632,28 @@ void policydb_destroy(struct policydb *p) cond_policydb_destroy(p); + for (tr = p->role_tr; tr; tr = tr->next) { + if (ltr) kfree(ltr); + ltr = tr; + } + if (ltr) kfree(ltr); + + for (ra = p->role_allow; ra; ra = ra -> next) { + if (lra) kfree(lra); + lra = ra; + } + if (lra) kfree(lra); + + for (rt = p->range_tr; rt; rt = rt -> next) { + if (lrt) kfree(lrt); + lrt = rt; + } + if (lrt) kfree(lrt); + + for (i = 0; i < p->p_types.nprim; i++) + ebitmap_destroy(&p->type_attr_map[i]); + kfree(p->type_attr_map); + return; } @@ -714,7 +744,8 @@ int policydb_context_isvalid(struct policydb *p, struct context *c) */ static int mls_read_range_helper(struct mls_range *r, void *fp) { - u32 buf[2], items; + __le32 buf[2]; + u32 items; int rc; rc = next_entry(buf, fp, sizeof(u32)); @@ -775,7 +806,7 @@ static int context_read_and_validate(struct context *c, struct policydb *p, void *fp) { - u32 buf[3]; + __le32 buf[3]; int rc; rc = next_entry(buf, fp, sizeof buf); @@ -815,7 +846,8 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp) char *key = NULL; struct perm_datum *perdatum; int rc; - u32 buf[2], len; + __le32 buf[2]; + u32 len; perdatum = kmalloc(sizeof(*perdatum), GFP_KERNEL); if (!perdatum) { @@ -855,7 +887,8 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp) { char *key = NULL; struct common_datum *comdatum; - u32 buf[4], len, nel; + __le32 buf[4]; + u32 len, nel; int i, rc; comdatum = kmalloc(sizeof(*comdatum), GFP_KERNEL); @@ -909,7 +942,8 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons, { struct constraint_node *c, *lc; struct constraint_expr *e, *le; - u32 buf[3], nexpr; + __le32 buf[3]; + u32 nexpr; int rc, i, j, depth; lc = NULL; @@ -993,7 +1027,8 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) { char *key = NULL; struct class_datum *cladatum; - u32 buf[6], len, len2, ncons, nel; + __le32 buf[6]; + u32 len, len2, ncons, nel; int i, rc; cladatum = kmalloc(sizeof(*cladatum), GFP_KERNEL); @@ -1087,7 +1122,8 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp) char *key = NULL; struct role_datum *role; int rc; - u32 buf[2], len; + __le32 buf[2]; + u32 len; role = kmalloc(sizeof(*role), GFP_KERNEL); if (!role) { @@ -1147,7 +1183,8 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp) char *key = NULL; struct type_datum *typdatum; int rc; - u32 buf[3], len; + __le32 buf[3]; + u32 len; typdatum = kmalloc(sizeof(*typdatum),GFP_KERNEL); if (!typdatum) { @@ -1191,7 +1228,7 @@ bad: */ static int mls_read_level(struct mls_level *lp, void *fp) { - u32 buf[1]; + __le32 buf[1]; int rc; memset(lp, 0, sizeof(*lp)); @@ -1219,7 +1256,8 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp) char *key = NULL; struct user_datum *usrdatum; int rc; - u32 buf[2], len; + __le32 buf[2]; + u32 len; usrdatum = kmalloc(sizeof(*usrdatum), GFP_KERNEL); if (!usrdatum) { @@ -1273,7 +1311,8 @@ static int sens_read(struct policydb *p, struct hashtab *h, void *fp) char *key = NULL; struct level_datum *levdatum; int rc; - u32 buf[2], len; + __le32 buf[2]; + u32 len; levdatum = kmalloc(sizeof(*levdatum), GFP_ATOMIC); if (!levdatum) { @@ -1324,7 +1363,8 @@ static int cat_read(struct policydb *p, struct hashtab *h, void *fp) char *key = NULL; struct cat_datum *catdatum; int rc; - u32 buf[3], len; + __le32 buf[3]; + u32 len; catdatum = kmalloc(sizeof(*catdatum), GFP_ATOMIC); if (!catdatum) { @@ -1387,7 +1427,8 @@ int policydb_read(struct policydb *p, void *fp) struct ocontext *l, *c, *newc; struct genfs *genfs_p, *genfs, *newgenfs; int i, j, rc; - u32 buf[8], len, len2, config, nprim, nel, nel2; + __le32 buf[8]; + u32 len, len2, config, nprim, nel, nel2; char *policydb_str; struct policydb_compat_info *info; struct range_trans *rt, *lrt; @@ -1403,17 +1444,14 @@ int policydb_read(struct policydb *p, void *fp) if (rc < 0) goto bad; - for (i = 0; i < 2; i++) - buf[i] = le32_to_cpu(buf[i]); - - if (buf[0] != POLICYDB_MAGIC) { + if (le32_to_cpu(buf[0]) != POLICYDB_MAGIC) { printk(KERN_ERR "security: policydb magic number 0x%x does " "not match expected magic number 0x%x\n", - buf[0], POLICYDB_MAGIC); + le32_to_cpu(buf[0]), POLICYDB_MAGIC); goto bad; } - len = buf[1]; + len = le32_to_cpu(buf[1]); if (len != strlen(POLICYDB_STRING)) { printk(KERN_ERR "security: policydb string length %d does not " "match expected length %Zu\n", @@ -1448,19 +1486,17 @@ int policydb_read(struct policydb *p, void *fp) rc = next_entry(buf, fp, sizeof(u32)*4); if (rc < 0) goto bad; - for (i = 0; i < 4; i++) - buf[i] = le32_to_cpu(buf[i]); - p->policyvers = buf[0]; + p->policyvers = le32_to_cpu(buf[0]); if (p->policyvers < POLICYDB_VERSION_MIN || p->policyvers > POLICYDB_VERSION_MAX) { printk(KERN_ERR "security: policydb version %d does not match " "my version range %d-%d\n", - buf[0], POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX); + le32_to_cpu(buf[0]), POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX); goto bad; } - if ((buf[1] & POLICYDB_CONFIG_MLS)) { + if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) { if (ss_initialized && !selinux_mls_enabled) { printk(KERN_ERR "Cannot switch between non-MLS and MLS " "policies\n"); @@ -1489,9 +1525,11 @@ int policydb_read(struct policydb *p, void *fp) goto bad; } - if (buf[2] != info->sym_num || buf[3] != info->ocon_num) { + if (le32_to_cpu(buf[2]) != info->sym_num || + le32_to_cpu(buf[3]) != info->ocon_num) { printk(KERN_ERR "security: policydb table sizes (%d,%d) do " - "not match mine (%d,%d)\n", buf[2], buf[3], + "not match mine (%d,%d)\n", le32_to_cpu(buf[2]), + le32_to_cpu(buf[3]), info->sym_num, info->ocon_num); goto bad; } @@ -1511,7 +1549,7 @@ int policydb_read(struct policydb *p, void *fp) p->symtab[i].nprim = nprim; } - rc = avtab_read(&p->te_avtab, fp, config); + rc = avtab_read(&p->te_avtab, fp, p->policyvers); if (rc) goto bad; @@ -1825,6 +1863,21 @@ int policydb_read(struct policydb *p, void *fp) } } + p->type_attr_map = kmalloc(p->p_types.nprim*sizeof(struct ebitmap), GFP_KERNEL); + if (!p->type_attr_map) + goto bad; + + for (i = 0; i < p->p_types.nprim; i++) { + ebitmap_init(&p->type_attr_map[i]); + if (p->policyvers >= POLICYDB_VERSION_AVTAB) { + if (ebitmap_read(&p->type_attr_map[i], fp)) + goto bad; + } + /* add the type itself as the degenerate case */ + if (ebitmap_set_bit(&p->type_attr_map[i], i, 1)) + goto bad; + } + rc = 0; out: return rc; |