[PATCH v3 11/34] lsm: get rid of the lsm_names list and do some cleanup

Paul Moore paul at paul-moore.com
Thu Sep 4 15:18:57 UTC 2025


On Thu, Sep 4, 2025 at 4:48 AM John Johansen
<john.johansen at canonical.com> wrote:
> On 9/4/25 01:12, Roberto Sassu wrote:
> > On Tue, 2025-09-02 at 10:20 -0700, John Johansen wrote:
> >> On 8/14/25 15:50, Paul Moore wrote:
> >>> 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 at paul-moore.com>
> >>> ---
> >>>    include/linux/lsm_hooks.h |  1 -
> >>>    security/inode.c          | 59 +++++++++++++++++++++++++++++++++++++--
> >>>    security/lsm_init.c       | 49 --------------------------------
> >>>    3 files changed, 57 insertions(+), 52 deletions(-)
> >>>
> >>> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> >>> index 7343dd60b1d5..65a8227bece7 100644
> >>> --- a/include/linux/lsm_hooks.h
> >>> +++ b/include/linux/lsm_hooks.h
> >>> @@ -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;
> >>>
> >>>    /**
> >>> diff --git a/security/inode.c b/security/inode.c
> >>> index 43382ef8896e..a5e7a073e672 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,65 @@ void securityfs_remove(struct dentry *dentry)
> >>>    EXPORT_SYMBOL_GPL(securityfs_remove);
> >>>
> >>>    #ifdef CONFIG_SECURITY
> >>> +#include <linux/spinlock.h>
> >>> +
> >>>    static struct dentry *lsm_dentry;
> >>> +
> >>> +/* NOTE: we never free the string below once it is set. */
> >>> +static DEFINE_SPINLOCK(lsm_read_lock);
> >>
> >> nit, this is only used on the write side, so not the best name
> >>
> >>> +static char *lsm_read_str = NULL;
> >>> +static ssize_t lsm_read_len = 0;
> >>> +
> >>>    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;
> >>> +   char *str;
> >>> +   ssize_t len;
> >>> +
> >>> +restart:
> >>> +
> >>> +   rcu_read_lock();
> >
> > Uhm, it seems we cannot use plain RCU here, simple_read_from_buffer()
> > can sleep.
>
> doh, yes.

D'oh indeed!  Thanks for catching this.

> But we shouldn't need RCU here either. This is a write once, never update
> again situation. Instead we can get away with just a lock on the write
> side to ensure exclusion on setting the value.
>
> We don't even need the read side memory barrier, if the assumption that
> the pointer is read as a single value holds, and the the null read will
> go to the lock, and end up rereading.

It's funny you bring this up, my first draft of this function
(unposted) did just that, although I figured I'd add the RCU read side
protection ... "just in case".

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.

-- 
paul-moore.com



More information about the Linux-security-module-archive mailing list