[PATCH 2/7] LSM: Implement x array functions for secmarks
Casey Schaufler <[email protected]>
| Newsgroups | gmane.comp.security.firewalls.netfilter.devel,gmane.linux.kernel.lsm,gmane.linux.kernel |
|---|---|
| Message-ID | <[email protected]> |
Implement, but don't use (yet) the functions required to use xarray indexes in secmarks. Signed-off-by: Casey Schaufler <[email protected]> --- include/linux/lsm_secxa.h | 19 ++++--- security/Makefile | 1 + security/lsm_secxa.c | 105 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 117 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..569c7f242b78 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..50ce613e35c0 --- /dev/null +++ b/security/lsm_secxa.c @@ -0,0 +1,105 @@ +// 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 CBS * @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; CBS } + } + + 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; CBS +} +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