[PATCH v2 2/7] LSM: Implement x array functions for secmarks
From: Casey Schaufler <casey@schaufler-ca.com>
Date: 2026-09-02 22:02:20
Also in:
lkml, netfilter-devel, selinux
Subsystem:
security subsystem, the rest · Maintainers:
Paul Moore, James Morris, "Serge E. Hallyn", Linus Torvalds
Implement, but don't use (yet) the functions required to use xarray indexes in secmarks. Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> --- 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@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; + 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);
--
2.54.0