[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