Re: [PATCH v2 2/7] LSM: Implement x array functions for secmarks
John Johansen <[email protected]>
| Newsgroups | gmane.linux.kernel,gmane.linux.kernel.lsm,gmane.comp.security.firewalls.netfilter.devel |
|---|---|
| Organization | Canonical |
| Message-ID | <[email protected]> |
On 9/2/26 15:01, Casey Schaufler wrote: > Implement, but don't use (yet) the functions required to use > xarray indexes in secmarks. > > Signed-off-by: Casey Schaufler <[email protected]> minor nit below > --- > include/linux/lsm_secxa.h | 19 ++++--- > security/Makefile | 1 + > security/lsm_secxa.c | 109 ++++++++++++++++++++++++++++++++++++++ > 3 files changed, 121 insertions(+), 8 deletions(-) > create mode 100644 security/lsm_secxa.c > > diff --git a/include/linux/lsm_secxa.h b/include/linux/lsm_secxa.h > index 926257d4730c..84b06c093460 100644 > --- a/include/linux/lsm_secxa.h > +++ b/include/linux/lsm_secxa.h > @@ -7,19 +7,22 @@ > #ifndef __LINUX_LSM_SECXA_H > #define __LINUX_LSM_SECXA_H > > -#ifdef CONFIG_NETWORK_SECMARK > +#ifdef CONFIG_SECURITY > > -#include <linux/security.h> > -#include <linux/skbuff.h> > +struct lsm_prop; > > -static inline void secxa_set_secmark(struct sk_buff *skb, u32 secxa) > -{ > - skb->secmark = secxa; > -} > -#else /* CONFIG_NETWORK_SECMARK */ > +int secxa_from_lsmprop(struct lsm_prop *prop, u32 *secxa); > +int secxa_get_lsmprop(struct lsm_prop **pro, u32 secxa); > + > +#endif /* CONFIG_SECURITY */ > + > +#ifdef CONFIG_NETWORK_SECMARK > > struct sk_buff; > > +void secxa_set_secmark(struct sk_buff *skb, u32 secxa); > +#else /* CONFIG_NETWORK_SECMARK */ > + > static inline void secxa_set_secmark(struct sk_buff *skb, u32 secxa) > { > } > diff --git a/security/Makefile b/security/Makefile > index 4601230ba442..e93be00bb6ae 100644 > --- a/security/Makefile > +++ b/security/Makefile > @@ -8,6 +8,7 @@ obj-$(CONFIG_KEYS) += keys/ > # always enable default capabilities > obj-y += commoncap.o > obj-$(CONFIG_SECURITY) += lsm_syscalls.o > +obj-$(CONFIG_NETWORK_SECMARK) += lsm_secxa.o > obj-$(CONFIG_MMU) += min_addr.o > > # Object file lists > diff --git a/security/lsm_secxa.c b/security/lsm_secxa.c > new file mode 100644 > index 000000000000..ccbe78095d70 > --- /dev/null > +++ b/security/lsm_secxa.c > @@ -0,0 +1,109 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > + > +/* > + * Implement functions supporting an x array for LSM properties. > + * > + * Copyright (C) 2026 Casey Schaufler <[email protected]> > + */ > +#define pr_fmt(fmt) "secxa: "fmt > + > +#include <linux/xarray.h> > +#include <linux/export.h> > +#include <linux/security.h> > +#include <linux/lsm_secxa.h> > +#include <linux/skbuff.h> > + > +/* > + * An Xarray of lsm_prop structures. > + */ > +struct xarray secxa_xa; > + > +/** > + * secxa_init - initialize the xarry of lsm_prop structures. > + */ > +static int __init secxa_init(void) > +{ > + xa_init_flags(&secxa_xa, XA_FLAGS_ALLOC1 | XA_FLAGS_LOCK_BH); > + > + return 0; > +} > +core_initcall(secxa_init); > + > +/** > + * secxa_get_lsmprop - get the lsm_prop associated with a secxa > + * @pro: destination for the lsm_prop pointer > + * @secxa: index to look up > + * > + * Find the lsm_prop associated with @secxa and place a pointer > + * to it in @pro. > + * > + * Returns 0, or -EINVAL if the mapping can't be found. > + */ > +int secxa_get_lsmprop(struct lsm_prop **pro, u32 secxa) > +{ > + struct lsm_prop *lp; > + > + if (!secxa) > + return -EINVAL; > + > + lp = xa_load(&secxa_xa, secxa); > + if (!lp) > + return -EINVAL; > + > + *pro = lp; > + return 0; > +} > +EXPORT_SYMBOL(secxa_get_lsmprop); > + > +/** > + * secxa_from_lsmprop - get the secxa associated with a lsm_prop > + * @prop: lsm_prop pointer > + * @secxa: result > + * > + * Find the secxa associated with @prop. If there is none, create it. > + * > + * Returns 0, or an error if the mapping cannot be created > + */ > +int secxa_from_lsmprop(struct lsm_prop *prop, u32 *secxa) > +{ > + struct lsm_prop *lp; > + unsigned long il; > + u32 index = 0; > + int rc; > + > + xa_for_each(&secxa_xa, il, lp) { > + if (!memcmp(prop, lp, sizeof(*prop))) { > + *secxa = il; this needs an explicit cast to (u32) to avoid some warnings on some architecture + warning flags combinations > + return 0; > + } > + } > + > + lp = kzalloc(sizeof(*lp), GFP_ATOMIC); > + if (!lp) > + return -ENOMEM; > + *lp = *prop; > + > + rc = xa_alloc_bh(&secxa_xa, &index, lp, xa_limit_31b, GFP_ATOMIC); > + if (rc) { > + kfree(lp); > + return -EINVAL; > + } > + > + *secxa = index; > + return 0; > +} > +EXPORT_SYMBOL(secxa_from_lsmprop); > + > +/** > + * secxa_set_secmark - add LSM information to a secmark > + * @skb: buffer with the secmark > + * @secxa: index of the information to add > + * > + * If the secmark in @skb is not set, set it to @secxa. > + */ > +void secxa_set_secmark(struct sk_buff *skb, u32 secxa) > +{ > + if (!skb->secmark) > + skb->secmark = secxa; > +} > +EXPORT_SYMBOL(secxa_set_secmark);