]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - security/selinux/ss/policydb.c
selinux: convert the policy type_attr_map to flex_array
[net-next-2.6.git] / security / selinux / ss / policydb.c
index 674ddfe0ba03440ad72b2f279a861b03a634daf6..3a29704be8ce10f4409dd0a3d4f0bea8bb0d1086 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/audit.h>
+#include <linux/flex_array.h>
 #include "security.h"
 
 #include "policydb.h"
@@ -739,11 +740,17 @@ void policydb_destroy(struct policydb *p)
        hashtab_map(p->range_tr, range_tr_destroy, NULL);
        hashtab_destroy(p->range_tr);
 
-       if (p->type_attr_map) {
-               for (i = 0; i < p->p_types.nprim; i++)
-                       ebitmap_destroy(&p->type_attr_map[i]);
+       if (p->type_attr_map_array) {
+               for (i = 0; i < p->p_types.nprim; i++) {
+                       struct ebitmap *e;
+
+                       e = flex_array_get(p->type_attr_map_array, i);
+                       if (!e)
+                               continue;
+                       ebitmap_destroy(e);
+               }
+               flex_array_free(p->type_attr_map_array);
        }
-       kfree(p->type_attr_map);
        ebitmap_destroy(&p->policycaps);
        ebitmap_destroy(&p->permissive_map);
 
@@ -2257,19 +2264,33 @@ int policydb_read(struct policydb *p, void *fp)
        if (rc)
                goto bad;
 
-       p->type_attr_map = kmalloc(p->p_types.nprim * sizeof(struct ebitmap), GFP_KERNEL);
-       if (!p->type_attr_map)
+       rc = -ENOMEM;
+       p->type_attr_map_array = flex_array_alloc(sizeof(struct ebitmap),
+                                                 p->p_types.nprim,
+                                                 GFP_KERNEL | __GFP_ZERO);
+       if (!p->type_attr_map_array)
+               goto bad;
+
+       /* preallocate so we don't have to worry about the put ever failing */
+       rc = flex_array_prealloc(p->type_attr_map_array, 0, p->p_types.nprim - 1,
+                                GFP_KERNEL | __GFP_ZERO);
+       if (rc)
                goto bad;
 
        for (i = 0; i < p->p_types.nprim; i++) {
-               ebitmap_init(&p->type_attr_map[i]);
+               struct ebitmap *e = flex_array_get(p->type_attr_map_array, i);
+
+               BUG_ON(!e);
+               ebitmap_init(e);
                if (p->policyvers >= POLICYDB_VERSION_AVTAB) {
-                       if (ebitmap_read(&p->type_attr_map[i], fp))
+                       rc = ebitmap_read(e, fp);
+                       if (rc)
                                goto bad;
                }
                /* add the type itself as the degenerate case */
-               if (ebitmap_set_bit(&p->type_attr_map[i], i, 1))
-                               goto bad;
+               rc = ebitmap_set_bit(e, i, 1);
+               if (rc)
+                       goto bad;
        }
 
        rc = policydb_bounds_sanity_check(p);