[PATCH v2 2/7] LSM: Implement x array functions for secmarks

John Johansen john.johansen at canonical.com
Thu Sep 3 05:36:53 UTC 2026


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 <casey at schaufler-ca.com>

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 <casey at schaufler-ca.com>
> + */
> +#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);




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