On Thu, Sep 4, 2025 at 11:18 AM Paul Moore <p...@paul-moore.com> wrote: > > I'll rework this function, but I'll hold off on posting another > revision until I hear back on some of the reviews that are still > pending in case additional edits are needed.
For the curious, here is what it looks like now: diff --git a/security/inode.c b/security/inode.c index 43382ef8896e..4813d116fd7c 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)) { + 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); } -- paul-moore.com