diff options
| author | Paul Moore <paul@paul-moore.com> | 2025-02-13 17:34:12 -0500 |
|---|---|---|
| committer | Paul Moore <paul@paul-moore.com> | 2025-10-22 19:24:19 -0400 |
| commit | 935d508d4d7ab9d19c603bd7eb2937249551d507 (patch) | |
| tree | bcbb3eb0ba2e56b02fea8eecb6da0291e91fd82d /security/inode.c | |
| parent | 250898ca335f337bc032a9693dc0a30a1cb85825 (diff) | |
| download | net-935d508d4d7ab9d19c603bd7eb2937249551d507.tar.gz | |
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>
Diffstat (limited to 'security/inode.c')
| -rw-r--r-- | security/inode.c | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/security/inode.c b/security/inode.c index 43382ef8896e1d..6620c3e42af263 100644 --- a/security/inode.c +++ b/security/inode.c @@ -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 = { |
