diff options
Diffstat (limited to 'security/selinux/ss/policydb.c')
-rw-r--r-- | security/selinux/ss/policydb.c | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index 674ddfe0ba03..3a29704be8ce 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/string.h> | 31 | #include <linux/string.h> |
32 | #include <linux/errno.h> | 32 | #include <linux/errno.h> |
33 | #include <linux/audit.h> | 33 | #include <linux/audit.h> |
34 | #include <linux/flex_array.h> | ||
34 | #include "security.h" | 35 | #include "security.h" |
35 | 36 | ||
36 | #include "policydb.h" | 37 | #include "policydb.h" |
@@ -739,11 +740,17 @@ void policydb_destroy(struct policydb *p) | |||
739 | hashtab_map(p->range_tr, range_tr_destroy, NULL); | 740 | hashtab_map(p->range_tr, range_tr_destroy, NULL); |
740 | hashtab_destroy(p->range_tr); | 741 | hashtab_destroy(p->range_tr); |
741 | 742 | ||
742 | if (p->type_attr_map) { | 743 | if (p->type_attr_map_array) { |
743 | for (i = 0; i < p->p_types.nprim; i++) | 744 | for (i = 0; i < p->p_types.nprim; i++) { |
744 | ebitmap_destroy(&p->type_attr_map[i]); | 745 | struct ebitmap *e; |
746 | |||
747 | e = flex_array_get(p->type_attr_map_array, i); | ||
748 | if (!e) | ||
749 | continue; | ||
750 | ebitmap_destroy(e); | ||
751 | } | ||
752 | flex_array_free(p->type_attr_map_array); | ||
745 | } | 753 | } |
746 | kfree(p->type_attr_map); | ||
747 | ebitmap_destroy(&p->policycaps); | 754 | ebitmap_destroy(&p->policycaps); |
748 | ebitmap_destroy(&p->permissive_map); | 755 | ebitmap_destroy(&p->permissive_map); |
749 | 756 | ||
@@ -2257,19 +2264,33 @@ int policydb_read(struct policydb *p, void *fp) | |||
2257 | if (rc) | 2264 | if (rc) |
2258 | goto bad; | 2265 | goto bad; |
2259 | 2266 | ||
2260 | p->type_attr_map = kmalloc(p->p_types.nprim * sizeof(struct ebitmap), GFP_KERNEL); | 2267 | rc = -ENOMEM; |
2261 | if (!p->type_attr_map) | 2268 | p->type_attr_map_array = flex_array_alloc(sizeof(struct ebitmap), |
2269 | p->p_types.nprim, | ||
2270 | GFP_KERNEL | __GFP_ZERO); | ||
2271 | if (!p->type_attr_map_array) | ||
2272 | goto bad; | ||
2273 | |||
2274 | /* preallocate so we don't have to worry about the put ever failing */ | ||
2275 | rc = flex_array_prealloc(p->type_attr_map_array, 0, p->p_types.nprim - 1, | ||
2276 | GFP_KERNEL | __GFP_ZERO); | ||
2277 | if (rc) | ||
2262 | goto bad; | 2278 | goto bad; |
2263 | 2279 | ||
2264 | for (i = 0; i < p->p_types.nprim; i++) { | 2280 | for (i = 0; i < p->p_types.nprim; i++) { |
2265 | ebitmap_init(&p->type_attr_map[i]); | 2281 | struct ebitmap *e = flex_array_get(p->type_attr_map_array, i); |
2282 | |||
2283 | BUG_ON(!e); | ||
2284 | ebitmap_init(e); | ||
2266 | if (p->policyvers >= POLICYDB_VERSION_AVTAB) { | 2285 | if (p->policyvers >= POLICYDB_VERSION_AVTAB) { |
2267 | if (ebitmap_read(&p->type_attr_map[i], fp)) | 2286 | rc = ebitmap_read(e, fp); |
2287 | if (rc) | ||
2268 | goto bad; | 2288 | goto bad; |
2269 | } | 2289 | } |
2270 | /* add the type itself as the degenerate case */ | 2290 | /* add the type itself as the degenerate case */ |
2271 | if (ebitmap_set_bit(&p->type_attr_map[i], i, 1)) | 2291 | rc = ebitmap_set_bit(e, i, 1); |
2272 | goto bad; | 2292 | if (rc) |
2293 | goto bad; | ||
2273 | } | 2294 | } |
2274 | 2295 | ||
2275 | rc = policydb_bounds_sanity_check(p); | 2296 | rc = policydb_bounds_sanity_check(p); |