summaryrefslogtreecommitdiffstats
path: root/security/selinux/ss
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/ss')
-rw-r--r--security/selinux/ss/ebitmap.c26
-rw-r--r--security/selinux/ss/ebitmap.h3
-rw-r--r--security/selinux/ss/services.c4
3 files changed, 27 insertions, 6 deletions
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index 9db4709a6877..ad38299164c3 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -24,6 +24,8 @@
#define BITS_PER_U64 (sizeof(u64) * 8)
+static struct kmem_cache *ebitmap_node_cachep;
+
int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2)
{
struct ebitmap_node *n1, *n2;
@@ -54,7 +56,7 @@ int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src)
n = src->node;
prev = NULL;
while (n) {
- new = kzalloc(sizeof(*new), GFP_ATOMIC);
+ new = kmem_cache_zalloc(ebitmap_node_cachep, GFP_ATOMIC);
if (!new) {
ebitmap_destroy(dst);
return -ENOMEM;
@@ -162,7 +164,7 @@ int ebitmap_netlbl_import(struct ebitmap *ebmap,
if (e_iter == NULL ||
offset >= e_iter->startbit + EBITMAP_SIZE) {
e_prev = e_iter;
- e_iter = kzalloc(sizeof(*e_iter), GFP_ATOMIC);
+ e_iter = kmem_cache_zalloc(ebitmap_node_cachep, GFP_ATOMIC);
if (e_iter == NULL)
goto netlbl_import_failure;
e_iter->startbit = offset - (offset % EBITMAP_SIZE);
@@ -288,7 +290,7 @@ int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value)
prev->next = n->next;
else
e->node = n->next;
- kfree(n);
+ kmem_cache_free(ebitmap_node_cachep, n);
}
return 0;
}
@@ -299,7 +301,7 @@ int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value)
if (!value)
return 0;
- new = kzalloc(sizeof(*new), GFP_ATOMIC);
+ new = kmem_cache_zalloc(ebitmap_node_cachep, GFP_ATOMIC);
if (!new)
return -ENOMEM;
@@ -332,7 +334,7 @@ void ebitmap_destroy(struct ebitmap *e)
while (n) {
temp = n;
n = n->next;
- kfree(temp);
+ kmem_cache_free(ebitmap_node_cachep, temp);
}
e->highbit = 0;
@@ -400,7 +402,7 @@ int ebitmap_read(struct ebitmap *e, void *fp)
if (!n || startbit >= n->startbit + EBITMAP_SIZE) {
struct ebitmap_node *tmp;
- tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
+ tmp = kmem_cache_zalloc(ebitmap_node_cachep, GFP_KERNEL);
if (!tmp) {
printk(KERN_ERR
"SELinux: ebitmap: out of memory\n");
@@ -519,3 +521,15 @@ int ebitmap_write(struct ebitmap *e, void *fp)
}
return 0;
}
+
+void ebitmap_cache_init(void)
+{
+ ebitmap_node_cachep = kmem_cache_create("ebitmap_node",
+ sizeof(struct ebitmap_node),
+ 0, SLAB_PANIC, NULL);
+}
+
+void ebitmap_cache_destroy(void)
+{
+ kmem_cache_destroy(ebitmap_node_cachep);
+}
diff --git a/security/selinux/ss/ebitmap.h b/security/selinux/ss/ebitmap.h
index 9637b8c71085..6d5a9ac4251f 100644
--- a/security/selinux/ss/ebitmap.h
+++ b/security/selinux/ss/ebitmap.h
@@ -130,6 +130,9 @@ void ebitmap_destroy(struct ebitmap *e);
int ebitmap_read(struct ebitmap *e, void *fp);
int ebitmap_write(struct ebitmap *e, void *fp);
+void ebitmap_cache_init(void);
+void ebitmap_cache_destroy(void);
+
#ifdef CONFIG_NETLABEL
int ebitmap_netlbl_export(struct ebitmap *ebmap,
struct netlbl_lsm_catmap **catmap);
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 202166612b80..2f02fa67ec2e 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -2054,9 +2054,11 @@ int security_load_policy(void *data, size_t len)
if (!ss_initialized) {
avtab_cache_init();
+ ebitmap_cache_init();
rc = policydb_read(&policydb, fp);
if (rc) {
avtab_cache_destroy();
+ ebitmap_cache_destroy();
goto out;
}
@@ -2067,6 +2069,7 @@ int security_load_policy(void *data, size_t len)
if (rc) {
policydb_destroy(&policydb);
avtab_cache_destroy();
+ ebitmap_cache_destroy();
goto out;
}
@@ -2074,6 +2077,7 @@ int security_load_policy(void *data, size_t len)
if (rc) {
policydb_destroy(&policydb);
avtab_cache_destroy();
+ ebitmap_cache_destroy();
goto out;
}