diff options
author | John Johansen <john.johansen@canonical.com> | 2017-01-16 00:43:10 -0800 |
---|---|---|
committer | John Johansen <john.johansen@canonical.com> | 2017-01-16 01:18:53 -0800 |
commit | d4669f0b036efd67ec2e00e0adc8f42214c1bdf8 (patch) | |
tree | 92f382c14e6875595b34d835a98636fa7d53b8fd /security/apparmor/lsm.c | |
parent | e3ea1ca59adaefa31935a6f8f06a9168ea0e57d2 (diff) | |
download | linux-next-d4669f0b036efd67ec2e00e0adc8f42214c1bdf8.tar.gz |
apparmor: add per cpu work buffers to avoid allocating buffers at every hook
Signed-off-by: John Johansen <john.johansen@canonical.com>
Diffstat (limited to 'security/apparmor/lsm.c')
-rw-r--r-- | security/apparmor/lsm.c | 51 |
1 files changed, 50 insertions, 1 deletions
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 8a887c392fdb..c249ea0e6328 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -41,6 +41,9 @@ /* Flag indicating whether initialization completed */ int apparmor_initialized __initdata; +DEFINE_PER_CPU(struct aa_buffers, aa_buffers); + + /* * LSM hook functions */ @@ -868,6 +871,43 @@ static int __init set_init_ctx(void) return 0; } +static void destroy_buffers(void) +{ + u32 i, j; + + for_each_possible_cpu(i) { + for_each_cpu_buffer(j) { + kfree(per_cpu(aa_buffers, i).buf[j]); + per_cpu(aa_buffers, i).buf[j] = NULL; + } + } +} + +static int __init alloc_buffers(void) +{ + u32 i, j; + + for_each_possible_cpu(i) { + for_each_cpu_buffer(j) { + char *buffer; + + if (cpu_to_node(i) > num_online_nodes()) + /* fallback to kmalloc for offline nodes */ + buffer = kmalloc(aa_g_path_max, GFP_KERNEL); + else + buffer = kmalloc_node(aa_g_path_max, GFP_KERNEL, + cpu_to_node(i)); + if (!buffer) { + destroy_buffers(); + return -ENOMEM; + } + per_cpu(aa_buffers, i).buf[j] = buffer; + } + } + + return 0; +} + #ifdef CONFIG_SYSCTL static int apparmor_dointvec(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) @@ -937,11 +977,17 @@ static int __init apparmor_init(void) } + error = alloc_buffers(); + if (error) { + AA_ERROR("Unable to allocate work buffers\n"); + goto buffers_out; + } + error = set_init_ctx(); if (error) { AA_ERROR("Failed to set context on init task\n"); aa_free_root_ns(); - goto alloc_out; + goto buffers_out; } security_add_hooks(apparmor_hooks, ARRAY_SIZE(apparmor_hooks)); @@ -956,6 +1002,9 @@ static int __init apparmor_init(void) return error; +buffers_out: + destroy_buffers(); + alloc_out: aa_destroy_aafs(); aa_teardown_dfa_engine(); |