mirror of https://github.com/torvalds/linux.git
lsm: get rid of the lsm_names list and do some cleanup
The LSM currently has a lot of code to maintain a list of the currently active LSMs in a human readable string, with the only user being the "/sys/kernel/security/lsm" code. Let's drop all of that code and generate the string on first use and then cache it for subsequent use. Signed-off-by: Paul Moore <paul@paul-moore.com>
This commit is contained in:
parent
250898ca33
commit
935d508d4d
|
|
@ -172,7 +172,6 @@ struct lsm_info {
|
|||
|
||||
|
||||
/* DO NOT tamper with these variables outside of the LSM framework */
|
||||
extern char *lsm_names;
|
||||
extern struct lsm_static_calls_table static_calls_table __ro_after_init;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
#include <linux/lsm_hooks.h>
|
||||
#include <linux/magic.h>
|
||||
|
||||
#include "lsm.h"
|
||||
|
||||
static struct vfsmount *mount;
|
||||
static int mount_count;
|
||||
|
||||
|
|
@ -315,12 +317,49 @@ void securityfs_remove(struct dentry *dentry)
|
|||
EXPORT_SYMBOL_GPL(securityfs_remove);
|
||||
|
||||
#ifdef CONFIG_SECURITY
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
static struct dentry *lsm_dentry;
|
||||
|
||||
static ssize_t lsm_read(struct file *filp, char __user *buf, size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
return simple_read_from_buffer(buf, count, ppos, lsm_names,
|
||||
strlen(lsm_names));
|
||||
int i;
|
||||
static char *str;
|
||||
static size_t len;
|
||||
static DEFINE_SPINLOCK(lock);
|
||||
|
||||
/* NOTE: we never free or modify the string once it is set */
|
||||
|
||||
if (unlikely(!str || !len)) {
|
||||
char *str_tmp;
|
||||
size_t len_tmp = 0;
|
||||
|
||||
for (i = 0; i < lsm_active_cnt; i++)
|
||||
/* the '+ 1' accounts for either a comma or a NUL */
|
||||
len_tmp += strlen(lsm_idlist[i]->name) + 1;
|
||||
|
||||
str_tmp = kmalloc(len_tmp, GFP_KERNEL);
|
||||
if (!str_tmp)
|
||||
return -ENOMEM;
|
||||
str_tmp[0] = '\0';
|
||||
|
||||
for (i = 0; i < lsm_active_cnt; i++) {
|
||||
if (i > 0)
|
||||
strcat(str_tmp, ",");
|
||||
strcat(str_tmp, lsm_idlist[i]->name);
|
||||
}
|
||||
|
||||
spin_lock(&lock);
|
||||
if (!str) {
|
||||
str = str_tmp;
|
||||
len = len_tmp - 1;
|
||||
} else
|
||||
kfree(str_tmp);
|
||||
spin_unlock(&lock);
|
||||
}
|
||||
|
||||
return simple_read_from_buffer(buf, count, ppos, str, len);
|
||||
}
|
||||
|
||||
static const struct file_operations lsm_ops = {
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@
|
|||
|
||||
#include "lsm.h"
|
||||
|
||||
char *lsm_names;
|
||||
|
||||
/* Pointers to LSM sections defined in include/asm-generic/vmlinux.lds.h */
|
||||
extern struct lsm_info __start_lsm_info[], __end_lsm_info[];
|
||||
extern struct lsm_info __start_early_lsm_info[], __end_early_lsm_info[];
|
||||
|
|
@ -371,42 +369,6 @@ static void __init lsm_init_ordered(void)
|
|||
}
|
||||
}
|
||||
|
||||
static bool match_last_lsm(const char *list, const char *lsm)
|
||||
{
|
||||
const char *last;
|
||||
|
||||
if (WARN_ON(!list || !lsm))
|
||||
return false;
|
||||
last = strrchr(list, ',');
|
||||
if (last)
|
||||
/* Pass the comma, strcmp() will check for '\0' */
|
||||
last++;
|
||||
else
|
||||
last = list;
|
||||
return !strcmp(last, lsm);
|
||||
}
|
||||
|
||||
static int lsm_append(const char *new, char **result)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
if (*result == NULL) {
|
||||
*result = kstrdup(new, GFP_KERNEL);
|
||||
if (*result == NULL)
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
/* Check if it is the last registered name */
|
||||
if (match_last_lsm(*result, new))
|
||||
return 0;
|
||||
cp = kasprintf(GFP_KERNEL, "%s,%s", *result, new);
|
||||
if (cp == NULL)
|
||||
return -ENOMEM;
|
||||
kfree(*result);
|
||||
*result = cp;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init lsm_static_call_init(struct security_hook_list *hl)
|
||||
{
|
||||
struct lsm_static_call *scall = hl->scalls;
|
||||
|
|
@ -443,15 +405,6 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,
|
|||
hooks[i].lsmid = lsmid;
|
||||
lsm_static_call_init(&hooks[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't try to append during early_security_init(), we'll come back
|
||||
* and fix this up afterwards.
|
||||
*/
|
||||
if (slab_is_available()) {
|
||||
if (lsm_append(lsmid->name, &lsm_names) < 0)
|
||||
panic("%s - Cannot get early memory.\n", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
int __init early_security_init(void)
|
||||
|
|
@ -488,8 +441,6 @@ int __init security_init(void)
|
|||
lsm_early_for_each_raw(lsm) {
|
||||
init_debug(" early started: %s (%s)\n", lsm->id->name,
|
||||
is_enabled(lsm) ? "enabled" : "disabled");
|
||||
if (lsm->enabled)
|
||||
lsm_append(lsm->id->name, &lsm_names);
|
||||
}
|
||||
|
||||
/* Load LSMs in specified order. */
|
||||
|
|
|
|||
Loading…
Reference in New Issue