* [PATCH v2 1/7] net, smack: Create a function to set secmarks
2026-09-02 22:01 ` [PATCH v2 0/7] Change skb secmarks to x-array indexes Casey Schaufler
@ 2026-09-02 22:01 ` Casey Schaufler
2026-09-03 5:35 ` John Johansen
2026-09-02 22:01 ` [PATCH v2 2/7] LSM: Implement x array functions for secmarks Casey Schaufler
` (5 subsequent siblings)
6 siblings, 1 reply; 15+ messages in thread
From: Casey Schaufler @ 2026-09-02 22:01 UTC (permalink / raw)
To: casey, paul, linux-security-module, pablo, fw, phil
Cc: linux-kernel, netfilter-devel, coreteam, jmorris, serge, keescook,
john.johansen, penguin-kernel, stephen.smalley.work, selinux
Rather than open coding assignments to skb->secmark, use a helper function
secxa_set_secmark(). This allows for a case where assigning a secmark
is more complex than a simple assignment. The version of the function
here does the legacy simple assignment.
Change the functions that currently assign values to skb->secmark to
use this function.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
include/linux/lsm_secxa.h | 28 ++++++++++++++++++++++++++++
net/netfilter/nft_meta.c | 5 +++--
net/netfilter/xt_CONNSECMARK.c | 3 ++-
net/netfilter/xt_SECMARK.c | 3 ++-
security/smack/smack_netfilter.c | 3 ++-
5 files changed, 37 insertions(+), 5 deletions(-)
create mode 100644 include/linux/lsm_secxa.h
diff --git a/include/linux/lsm_secxa.h b/include/linux/lsm_secxa.h
new file mode 100644
index 000000000000..926257d4730c
--- /dev/null
+++ b/include/linux/lsm_secxa.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * Copyright (C) 2026 Casey Schaufler <casey@schaufler-ca.com>
+ */
+
+#ifndef __LINUX_LSM_SECXA_H
+#define __LINUX_LSM_SECXA_H
+
+#ifdef CONFIG_NETWORK_SECMARK
+
+#include <linux/security.h>
+#include <linux/skbuff.h>
+
+static inline void secxa_set_secmark(struct sk_buff *skb, u32 secxa)
+{
+ skb->secmark = secxa;
+}
+#else /* CONFIG_NETWORK_SECMARK */
+
+struct sk_buff;
+
+static inline void secxa_set_secmark(struct sk_buff *skb, u32 secxa)
+{
+}
+#endif /* CONFIG_NETWORK_SECMARK */
+
+#endif /* __LINUX_LSM_SECXA_H */
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index 0a43e0787a68..bd0f7a0931f4 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -17,6 +17,7 @@
#include <linux/random.h>
#include <linux/smp.h>
#include <linux/static_key.h>
+#include <linux/lsm_secxa.h>
#include <net/dst.h>
#include <net/ip.h>
#include <net/sock.h>
@@ -502,7 +503,7 @@ void nft_meta_set_eval(const struct nft_expr *expr,
break;
#ifdef CONFIG_NETWORK_SECMARK
case NFT_META_SECMARK:
- skb->secmark = value;
+ secxa_set_secmark(skb, value);
break;
#endif
default:
@@ -950,7 +951,7 @@ static void nft_secmark_obj_eval(struct nft_object *obj, struct nft_regs *regs,
const struct nft_secmark *priv = nft_obj_data(obj);
struct sk_buff *skb = pkt->skb;
- skb->secmark = priv->secid;
+ secxa_set_secmark(skb, priv->secid);
}
static int nft_secmark_obj_init(const struct nft_ctx *ctx,
diff --git a/net/netfilter/xt_CONNSECMARK.c b/net/netfilter/xt_CONNSECMARK.c
index 1494b3ee30e1..9d799d2459dc 100644
--- a/net/netfilter/xt_CONNSECMARK.c
+++ b/net/netfilter/xt_CONNSECMARK.c
@@ -14,6 +14,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/skbuff.h>
+#include <linux/lsm_secxa.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_CONNSECMARK.h>
#include <net/netfilter/nf_conntrack.h>
@@ -55,7 +56,7 @@ static void secmark_restore(struct sk_buff *skb)
ct = nf_ct_get(skb, &ctinfo);
if (ct && ct->secmark)
- skb->secmark = ct->secmark;
+ secxa_set_secmark(skb, ct->secmark);
}
}
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c
index 5bc5ea505eb9..ea67aa92ddc2 100644
--- a/net/netfilter/xt_SECMARK.c
+++ b/net/netfilter/xt_SECMARK.c
@@ -11,6 +11,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/security.h>
+#include <linux/lsm_secxa.h>
#include <linux/skbuff.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_SECMARK.h>
@@ -36,7 +37,7 @@ secmark_tg(struct sk_buff *skb, const struct xt_secmark_target_info_v1 *info)
BUG();
}
- skb->secmark = secmark;
+ secxa_set_secmark(skb, secmark);
return XT_CONTINUE;
}
diff --git a/security/smack/smack_netfilter.c b/security/smack/smack_netfilter.c
index 17ba578b1308..b363c42f252e 100644
--- a/security/smack/smack_netfilter.c
+++ b/security/smack/smack_netfilter.c
@@ -14,6 +14,7 @@
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter_ipv6.h>
#include <linux/netdevice.h>
+#include <linux/lsm_secxa.h>
#include <net/inet_sock.h>
#include <net/net_namespace.h>
#include "smack.h"
@@ -29,7 +30,7 @@ static unsigned int smack_ip_output(void *priv,
if (sk) {
ssp = smack_sock(sk);
skp = ssp->smk_out;
- skb->secmark = skp->smk_secid;
+ secxa_set_secmark(skb, skp->smk_secid);
}
return NF_ACCEPT;
--
2.54.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH v2 1/7] net, smack: Create a function to set secmarks
2026-09-02 22:01 ` [PATCH v2 1/7] net, smack: Create a function to set secmarks Casey Schaufler
@ 2026-09-03 5:35 ` John Johansen
0 siblings, 0 replies; 15+ messages in thread
From: John Johansen @ 2026-09-03 5:35 UTC (permalink / raw)
To: Casey Schaufler, paul, linux-security-module, pablo, fw, phil
Cc: linux-kernel, netfilter-devel, coreteam, jmorris, serge, keescook,
penguin-kernel, stephen.smalley.work, selinux
On 9/2/26 15:01, Casey Schaufler wrote:
> Rather than open coding assignments to skb->secmark, use a helper function
> secxa_set_secmark(). This allows for a case where assigning a secmark
> is more complex than a simple assignment. The version of the function
> here does the legacy simple assignment.
>
> Change the functions that currently assign values to skb->secmark to
> use this function.
>
> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
looks good
Reviewed-by: John Johansen <john.johansen@canonical.com>
> ---
> include/linux/lsm_secxa.h | 28 ++++++++++++++++++++++++++++
> net/netfilter/nft_meta.c | 5 +++--
> net/netfilter/xt_CONNSECMARK.c | 3 ++-
> net/netfilter/xt_SECMARK.c | 3 ++-
> security/smack/smack_netfilter.c | 3 ++-
> 5 files changed, 37 insertions(+), 5 deletions(-)
> create mode 100644 include/linux/lsm_secxa.h
>
> diff --git a/include/linux/lsm_secxa.h b/include/linux/lsm_secxa.h
> new file mode 100644
> index 000000000000..926257d4730c
> --- /dev/null
> +++ b/include/linux/lsm_secxa.h
> @@ -0,0 +1,28 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +/*
> + * Copyright (C) 2026 Casey Schaufler <casey@schaufler-ca.com>
> + */
> +
> +#ifndef __LINUX_LSM_SECXA_H
> +#define __LINUX_LSM_SECXA_H
> +
> +#ifdef CONFIG_NETWORK_SECMARK
> +
> +#include <linux/security.h>
> +#include <linux/skbuff.h>
> +
> +static inline void secxa_set_secmark(struct sk_buff *skb, u32 secxa)
> +{
> + skb->secmark = secxa;
> +}
> +#else /* CONFIG_NETWORK_SECMARK */
> +
> +struct sk_buff;
> +
> +static inline void secxa_set_secmark(struct sk_buff *skb, u32 secxa)
> +{
> +}
> +#endif /* CONFIG_NETWORK_SECMARK */
> +
> +#endif /* __LINUX_LSM_SECXA_H */
> diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
> index 0a43e0787a68..bd0f7a0931f4 100644
> --- a/net/netfilter/nft_meta.c
> +++ b/net/netfilter/nft_meta.c
> @@ -17,6 +17,7 @@
> #include <linux/random.h>
> #include <linux/smp.h>
> #include <linux/static_key.h>
> +#include <linux/lsm_secxa.h>
> #include <net/dst.h>
> #include <net/ip.h>
> #include <net/sock.h>
> @@ -502,7 +503,7 @@ void nft_meta_set_eval(const struct nft_expr *expr,
> break;
> #ifdef CONFIG_NETWORK_SECMARK
> case NFT_META_SECMARK:
> - skb->secmark = value;
> + secxa_set_secmark(skb, value);
> break;
> #endif
> default:
> @@ -950,7 +951,7 @@ static void nft_secmark_obj_eval(struct nft_object *obj, struct nft_regs *regs,
> const struct nft_secmark *priv = nft_obj_data(obj);
> struct sk_buff *skb = pkt->skb;
>
> - skb->secmark = priv->secid;
> + secxa_set_secmark(skb, priv->secid);
> }
>
> static int nft_secmark_obj_init(const struct nft_ctx *ctx,
> diff --git a/net/netfilter/xt_CONNSECMARK.c b/net/netfilter/xt_CONNSECMARK.c
> index 1494b3ee30e1..9d799d2459dc 100644
> --- a/net/netfilter/xt_CONNSECMARK.c
> +++ b/net/netfilter/xt_CONNSECMARK.c
> @@ -14,6 +14,7 @@
> #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> #include <linux/module.h>
> #include <linux/skbuff.h>
> +#include <linux/lsm_secxa.h>
> #include <linux/netfilter/x_tables.h>
> #include <linux/netfilter/xt_CONNSECMARK.h>
> #include <net/netfilter/nf_conntrack.h>
> @@ -55,7 +56,7 @@ static void secmark_restore(struct sk_buff *skb)
>
> ct = nf_ct_get(skb, &ctinfo);
> if (ct && ct->secmark)
> - skb->secmark = ct->secmark;
> + secxa_set_secmark(skb, ct->secmark);
> }
> }
>
> diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c
> index 5bc5ea505eb9..ea67aa92ddc2 100644
> --- a/net/netfilter/xt_SECMARK.c
> +++ b/net/netfilter/xt_SECMARK.c
> @@ -11,6 +11,7 @@
> #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> #include <linux/module.h>
> #include <linux/security.h>
> +#include <linux/lsm_secxa.h>
> #include <linux/skbuff.h>
> #include <linux/netfilter/x_tables.h>
> #include <linux/netfilter/xt_SECMARK.h>
> @@ -36,7 +37,7 @@ secmark_tg(struct sk_buff *skb, const struct xt_secmark_target_info_v1 *info)
> BUG();
> }
>
> - skb->secmark = secmark;
> + secxa_set_secmark(skb, secmark);
> return XT_CONTINUE;
> }
>
> diff --git a/security/smack/smack_netfilter.c b/security/smack/smack_netfilter.c
> index 17ba578b1308..b363c42f252e 100644
> --- a/security/smack/smack_netfilter.c
> +++ b/security/smack/smack_netfilter.c
> @@ -14,6 +14,7 @@
> #include <linux/netfilter_ipv4.h>
> #include <linux/netfilter_ipv6.h>
> #include <linux/netdevice.h>
> +#include <linux/lsm_secxa.h>
> #include <net/inet_sock.h>
> #include <net/net_namespace.h>
> #include "smack.h"
> @@ -29,7 +30,7 @@ static unsigned int smack_ip_output(void *priv,
> if (sk) {
> ssp = smack_sock(sk);
> skp = ssp->smk_out;
> - skb->secmark = skp->smk_secid;
> + secxa_set_secmark(skb, skp->smk_secid);
> }
>
> return NF_ACCEPT;
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 2/7] LSM: Implement x array functions for secmarks
2026-09-02 22:01 ` [PATCH v2 0/7] Change skb secmarks to x-array indexes Casey Schaufler
2026-09-02 22:01 ` [PATCH v2 1/7] net, smack: Create a function to set secmarks Casey Schaufler
@ 2026-09-02 22:01 ` Casey Schaufler
2026-09-03 5:36 ` John Johansen
2026-09-02 22:01 ` [PATCH v2 3/7] LSM: Two hooks for manipulating struct lsm_prop Casey Schaufler
` (4 subsequent siblings)
6 siblings, 1 reply; 15+ messages in thread
From: Casey Schaufler @ 2026-09-02 22:01 UTC (permalink / raw)
To: casey, paul, linux-security-module, pablo, fw, phil
Cc: linux-kernel, netfilter-devel, coreteam, jmorris, serge, keescook,
john.johansen, penguin-kernel, stephen.smalley.work, selinux
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
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH v2 2/7] LSM: Implement x array functions for secmarks
2026-09-02 22:01 ` [PATCH v2 2/7] LSM: Implement x array functions for secmarks Casey Schaufler
@ 2026-09-03 5:36 ` John Johansen
0 siblings, 0 replies; 15+ messages in thread
From: John Johansen @ 2026-09-03 5:36 UTC (permalink / raw)
To: Casey Schaufler, paul, linux-security-module, pablo, fw, phil
Cc: linux-kernel, netfilter-devel, coreteam, jmorris, serge, keescook,
penguin-kernel, stephen.smalley.work, selinux
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@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@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);
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 3/7] LSM: Two hooks for manipulating struct lsm_prop
2026-09-02 22:01 ` [PATCH v2 0/7] Change skb secmarks to x-array indexes Casey Schaufler
2026-09-02 22:01 ` [PATCH v2 1/7] net, smack: Create a function to set secmarks Casey Schaufler
2026-09-02 22:01 ` [PATCH v2 2/7] LSM: Implement x array functions for secmarks Casey Schaufler
@ 2026-09-02 22:01 ` Casey Schaufler
2026-09-03 9:40 ` John Johansen
2026-09-02 22:01 ` [PATCH v2 4/7] SELinux: hooks for secctx_to_lsmprop and update_lsmprop Casey Schaufler
` (3 subsequent siblings)
6 siblings, 1 reply; 15+ messages in thread
From: Casey Schaufler @ 2026-09-02 22:01 UTC (permalink / raw)
To: casey, paul, linux-security-module, pablo, fw, phil
Cc: linux-kernel, netfilter-devel, coreteam, jmorris, serge, keescook,
john.johansen, penguin-kernel, stephen.smalley.work, selinux
security_update_lsmprop() updates the property of the
specified LSM in the @dest structure with that in the @src.
security_secctx_to_lsmprop() sets the @prop field associated
with the LSM specified to the value of the passed security
context.
LSM specific implementations of these hooks to follow.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
include/linux/lsm_hook_defs.h | 4 ++++
include/linux/security.h | 16 ++++++++++++++++
security/security.c | 32 ++++++++++++++++++++++++++++++++
3 files changed, 52 insertions(+)
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 65c9609ec207..679c40a8e127 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -305,7 +305,11 @@ LSM_HOOK(int, 0, ismaclabel, const char *name)
LSM_HOOK(int, -EOPNOTSUPP, secid_to_secctx, u32 secid, struct lsm_context *cp)
LSM_HOOK(int, -EOPNOTSUPP, lsmprop_to_secctx, struct lsm_prop *prop,
struct lsm_context *cp)
+LSM_HOOK(void, LSM_RET_VOID, update_lsmprop, struct lsm_prop *dest,
+ struct lsm_prop *src, int lsmid)
LSM_HOOK(int, 0, secctx_to_secid, const char *secdata, u32 seclen, u32 *secid)
+LSM_HOOK(int, -EINVAL, secctx_to_lsmprop, const char *secdata, u32 seclen,
+ struct lsm_prop *prop)
LSM_HOOK(void, LSM_RET_VOID, release_secctx, struct lsm_context *cp)
LSM_HOOK(void, LSM_RET_VOID, inode_invalidate_secctx, struct inode *inode)
LSM_HOOK(int, 0, inode_notifysecctx, struct inode *inode, void *ctx, u32 ctxlen)
diff --git a/include/linux/security.h b/include/linux/security.h
index 153e9043058f..19adc19eb9af 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -576,6 +576,11 @@ int security_secid_to_secctx(u32 secid, struct lsm_context *cp);
int security_lsmprop_to_secctx(struct lsm_prop *prop, struct lsm_context *cp,
int lsmid);
int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
+int security_secctx_to_lsmprop(const char *secdata, u32 seclen,
+ struct lsm_prop *prop, int lsmid);
+
+void security_update_lsmprop(struct lsm_prop *dest, struct lsm_prop *src,
+ int lsmid);
void security_release_secctx(struct lsm_context *cp);
void security_inode_invalidate_secctx(struct inode *inode);
int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
@@ -1581,6 +1586,11 @@ static inline int security_lsmprop_to_secctx(struct lsm_prop *prop,
return -EOPNOTSUPP;
}
+static inline void security_update_lsmprop(struct lsm_prop *dest,
+ struct lsm_prop *src, int lsmid)
+{
+}
+
static inline int security_secctx_to_secid(const char *secdata,
u32 seclen,
u32 *secid)
@@ -1588,6 +1598,12 @@ static inline int security_secctx_to_secid(const char *secdata,
return -EOPNOTSUPP;
}
+static inline int security_secctx_to_lsmprop(const char *secdata, u32 seclen,
+ struct lsm_prop *prop, int lsmid)
+{
+ return -EOPNOTSUPP;
+}
+
static inline void security_release_secctx(struct lsm_context *cp)
{
}
diff --git a/security/security.c b/security/security.c
index 71aea8fdf014..1dec0037370b 100644
--- a/security/security.c
+++ b/security/security.c
@@ -3965,6 +3965,13 @@ int security_lsmprop_to_secctx(struct lsm_prop *prop, struct lsm_context *cp,
}
EXPORT_SYMBOL(security_lsmprop_to_secctx);
+void security_update_lsmprop(struct lsm_prop *dest, struct lsm_prop *src,
+ int lsmid)
+{
+ call_void_hook(update_lsmprop, dest, src, lsmid);
+}
+EXPORT_SYMBOL(security_update_lsmprop);
+
/**
* security_secctx_to_secid() - Convert a secctx to a secid
* @secdata: secctx
@@ -3982,6 +3989,31 @@ int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
}
EXPORT_SYMBOL(security_secctx_to_secid);
+/**
+ * security_secctx_to_lsmprop() - Convert a secctx to a lsmprop
+ * @secdata: secctx
+ * @seclen: length of secctx
+ * @prop: prop
+ * @lsmid: which LSM the context is appropriate to.
+ *
+ * Convert security context to an lsmprop.
+ *
+ * Return: Returns 0 on success, error on failure.
+ */
+int security_secctx_to_lsmprop(const char *secdata, u32 seclen,
+ struct lsm_prop *prop, int lsmid)
+{
+ struct lsm_static_call *scall;
+
+ lsm_for_each_hook(scall, secctx_to_lsmprop) {
+ if (lsmid != LSM_ID_UNDEF && lsmid != scall->hl->lsmid->id)
+ continue;
+ return scall->hl->hook.secctx_to_lsmprop(secdata, seclen, prop);
+ }
+ return LSM_RET_DEFAULT(secctx_to_lsmprop);
+}
+EXPORT_SYMBOL(security_secctx_to_lsmprop);
+
/**
* security_release_secctx() - Free a secctx buffer
* @cp: the security context
--
2.54.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH v2 3/7] LSM: Two hooks for manipulating struct lsm_prop
2026-09-02 22:01 ` [PATCH v2 3/7] LSM: Two hooks for manipulating struct lsm_prop Casey Schaufler
@ 2026-09-03 9:40 ` John Johansen
0 siblings, 0 replies; 15+ messages in thread
From: John Johansen @ 2026-09-03 9:40 UTC (permalink / raw)
To: Casey Schaufler, paul, linux-security-module, pablo, fw, phil
Cc: linux-kernel, netfilter-devel, coreteam, jmorris, serge, keescook,
penguin-kernel, stephen.smalley.work, selinux
On 9/2/26 15:01, Casey Schaufler wrote:
> security_update_lsmprop() updates the property of the
> specified LSM in the @dest structure with that in the @src.
>
> security_secctx_to_lsmprop() sets the @prop field associated
> with the LSM specified to the value of the passed security
> context.
>
> LSM specific implementations of these hooks to follow.
>
> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
lgtm
Reviewed-by: John Johansen <john.johansen@canonical.com>
> ---
> include/linux/lsm_hook_defs.h | 4 ++++
> include/linux/security.h | 16 ++++++++++++++++
> security/security.c | 32 ++++++++++++++++++++++++++++++++
> 3 files changed, 52 insertions(+)
>
> diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
> index 65c9609ec207..679c40a8e127 100644
> --- a/include/linux/lsm_hook_defs.h
> +++ b/include/linux/lsm_hook_defs.h
> @@ -305,7 +305,11 @@ LSM_HOOK(int, 0, ismaclabel, const char *name)
> LSM_HOOK(int, -EOPNOTSUPP, secid_to_secctx, u32 secid, struct lsm_context *cp)
> LSM_HOOK(int, -EOPNOTSUPP, lsmprop_to_secctx, struct lsm_prop *prop,
> struct lsm_context *cp)
> +LSM_HOOK(void, LSM_RET_VOID, update_lsmprop, struct lsm_prop *dest,
> + struct lsm_prop *src, int lsmid)
> LSM_HOOK(int, 0, secctx_to_secid, const char *secdata, u32 seclen, u32 *secid)
> +LSM_HOOK(int, -EINVAL, secctx_to_lsmprop, const char *secdata, u32 seclen,
> + struct lsm_prop *prop)
> LSM_HOOK(void, LSM_RET_VOID, release_secctx, struct lsm_context *cp)
> LSM_HOOK(void, LSM_RET_VOID, inode_invalidate_secctx, struct inode *inode)
> LSM_HOOK(int, 0, inode_notifysecctx, struct inode *inode, void *ctx, u32 ctxlen)
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 153e9043058f..19adc19eb9af 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -576,6 +576,11 @@ int security_secid_to_secctx(u32 secid, struct lsm_context *cp);
> int security_lsmprop_to_secctx(struct lsm_prop *prop, struct lsm_context *cp,
> int lsmid);
> int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
> +int security_secctx_to_lsmprop(const char *secdata, u32 seclen,
> + struct lsm_prop *prop, int lsmid);
> +
> +void security_update_lsmprop(struct lsm_prop *dest, struct lsm_prop *src,
> + int lsmid);
> void security_release_secctx(struct lsm_context *cp);
> void security_inode_invalidate_secctx(struct inode *inode);
> int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
> @@ -1581,6 +1586,11 @@ static inline int security_lsmprop_to_secctx(struct lsm_prop *prop,
> return -EOPNOTSUPP;
> }
>
> +static inline void security_update_lsmprop(struct lsm_prop *dest,
> + struct lsm_prop *src, int lsmid)
> +{
> +}
> +
> static inline int security_secctx_to_secid(const char *secdata,
> u32 seclen,
> u32 *secid)
> @@ -1588,6 +1598,12 @@ static inline int security_secctx_to_secid(const char *secdata,
> return -EOPNOTSUPP;
> }
>
> +static inline int security_secctx_to_lsmprop(const char *secdata, u32 seclen,
> + struct lsm_prop *prop, int lsmid)
> +{
> + return -EOPNOTSUPP;
> +}
> +
> static inline void security_release_secctx(struct lsm_context *cp)
> {
> }
> diff --git a/security/security.c b/security/security.c
> index 71aea8fdf014..1dec0037370b 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -3965,6 +3965,13 @@ int security_lsmprop_to_secctx(struct lsm_prop *prop, struct lsm_context *cp,
> }
> EXPORT_SYMBOL(security_lsmprop_to_secctx);
>
> +void security_update_lsmprop(struct lsm_prop *dest, struct lsm_prop *src,
> + int lsmid)
> +{
> + call_void_hook(update_lsmprop, dest, src, lsmid);
> +}
> +EXPORT_SYMBOL(security_update_lsmprop);
> +
> /**
> * security_secctx_to_secid() - Convert a secctx to a secid
> * @secdata: secctx
> @@ -3982,6 +3989,31 @@ int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
> }
> EXPORT_SYMBOL(security_secctx_to_secid);
>
> +/**
> + * security_secctx_to_lsmprop() - Convert a secctx to a lsmprop
> + * @secdata: secctx
> + * @seclen: length of secctx
> + * @prop: prop
> + * @lsmid: which LSM the context is appropriate to.
> + *
> + * Convert security context to an lsmprop.
> + *
> + * Return: Returns 0 on success, error on failure.
> + */
> +int security_secctx_to_lsmprop(const char *secdata, u32 seclen,
> + struct lsm_prop *prop, int lsmid)
> +{
> + struct lsm_static_call *scall;
> +
> + lsm_for_each_hook(scall, secctx_to_lsmprop) {
> + if (lsmid != LSM_ID_UNDEF && lsmid != scall->hl->lsmid->id)
> + continue;
> + return scall->hl->hook.secctx_to_lsmprop(secdata, seclen, prop);
> + }
> + return LSM_RET_DEFAULT(secctx_to_lsmprop);
> +}
> +EXPORT_SYMBOL(security_secctx_to_lsmprop);
> +
> /**
> * security_release_secctx() - Free a secctx buffer
> * @cp: the security context
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 4/7] SELinux: hooks for secctx_to_lsmprop and update_lsmprop
2026-09-02 22:01 ` [PATCH v2 0/7] Change skb secmarks to x-array indexes Casey Schaufler
` (2 preceding siblings ...)
2026-09-02 22:01 ` [PATCH v2 3/7] LSM: Two hooks for manipulating struct lsm_prop Casey Schaufler
@ 2026-09-02 22:01 ` Casey Schaufler
2026-09-03 6:10 ` John Johansen
2026-09-02 22:01 ` [PATCH v2 5/7] Smack: " Casey Schaufler
` (2 subsequent siblings)
6 siblings, 1 reply; 15+ messages in thread
From: Casey Schaufler @ 2026-09-02 22:01 UTC (permalink / raw)
To: casey, paul, linux-security-module, pablo, fw, phil
Cc: linux-kernel, netfilter-devel, coreteam, jmorris, serge, keescook,
john.johansen, penguin-kernel, stephen.smalley.work, selinux
Implement these hooks.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
security/selinux/hooks.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 18dd28b2bb13..12614478b638 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6946,6 +6946,13 @@ static int selinux_ismaclabel(const char *name)
return (strcmp(name, XATTR_SELINUX_SUFFIX) == 0);
}
+static void selinux_update_lsmprop(struct lsm_prop *dest, struct lsm_prop *src,
+ int lsmid)
+{
+ if (lsmid == LSM_ID_SELINUX || lsmid == LSM_ID_UNDEF)
+ dest->selinux.secid = src->selinux.secid;
+}
+
static int selinux_secid_to_secctx(u32 secid, struct lsm_context *cp)
{
u32 seclen;
@@ -6964,6 +6971,13 @@ static int selinux_secid_to_secctx(u32 secid, struct lsm_context *cp)
return seclen;
}
+static int selinux_secctx_to_lsmprop(const char *secdata, u32 seclen,
+ struct lsm_prop *prop)
+{
+ return security_context_to_sid(secdata, seclen, &prop->selinux.secid,
+ GFP_KERNEL);
+}
+
static int selinux_lsmprop_to_secctx(struct lsm_prop *prop,
struct lsm_context *cp)
{
@@ -7694,6 +7708,7 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = {
LSM_HOOK_INIT(ismaclabel, selinux_ismaclabel),
LSM_HOOK_INIT(secctx_to_secid, selinux_secctx_to_secid),
+ LSM_HOOK_INIT(secctx_to_lsmprop, selinux_secctx_to_lsmprop),
LSM_HOOK_INIT(release_secctx, selinux_release_secctx),
LSM_HOOK_INIT(inode_invalidate_secctx, selinux_inode_invalidate_secctx),
LSM_HOOK_INIT(inode_notifysecctx, selinux_inode_notifysecctx),
@@ -7812,6 +7827,7 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = {
LSM_HOOK_INIT(sem_alloc_security, selinux_sem_alloc_security),
LSM_HOOK_INIT(secid_to_secctx, selinux_secid_to_secctx),
LSM_HOOK_INIT(lsmprop_to_secctx, selinux_lsmprop_to_secctx),
+ LSM_HOOK_INIT(update_lsmprop, selinux_update_lsmprop),
LSM_HOOK_INIT(inode_getsecctx, selinux_inode_getsecctx),
LSM_HOOK_INIT(sk_alloc_security, selinux_sk_alloc_security),
LSM_HOOK_INIT(tun_dev_alloc_security, selinux_tun_dev_alloc_security),
--
2.54.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH v2 4/7] SELinux: hooks for secctx_to_lsmprop and update_lsmprop
2026-09-02 22:01 ` [PATCH v2 4/7] SELinux: hooks for secctx_to_lsmprop and update_lsmprop Casey Schaufler
@ 2026-09-03 6:10 ` John Johansen
0 siblings, 0 replies; 15+ messages in thread
From: John Johansen @ 2026-09-03 6:10 UTC (permalink / raw)
To: Casey Schaufler, paul, linux-security-module, pablo, fw, phil
Cc: linux-kernel, netfilter-devel, coreteam, jmorris, serge, keescook,
penguin-kernel, stephen.smalley.work, selinux
On 9/2/26 15:01, Casey Schaufler wrote:
> Implement these hooks.
>
other than the question below, this is looking good
> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
> ---
> security/selinux/hooks.c | 16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
>
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 18dd28b2bb13..12614478b638 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -6946,6 +6946,13 @@ static int selinux_ismaclabel(const char *name)
> return (strcmp(name, XATTR_SELINUX_SUFFIX) == 0);
> }
>
> +static void selinux_update_lsmprop(struct lsm_prop *dest, struct lsm_prop *src,
> + int lsmid)
> +{
> + if (lsmid == LSM_ID_SELINUX || lsmid == LSM_ID_UNDEF)
you have added similar boiler plate to each of the LSMs using this hook. If
all LSMs are going to do this, then shouldn't we just move this into the
LSM similar to what is done with secctx_to_lsm_prop
if (lsmid != LSM_ID_UNDEF && lsmid != scall->hl->lsmid->id)
continue;
> + dest->selinux.secid = src->selinux.secid;
> +}
> +
> static int selinux_secid_to_secctx(u32 secid, struct lsm_context *cp)
> {
> u32 seclen;
> @@ -6964,6 +6971,13 @@ static int selinux_secid_to_secctx(u32 secid, struct lsm_context *cp)
> return seclen;
> }
>
> +static int selinux_secctx_to_lsmprop(const char *secdata, u32 seclen,
> + struct lsm_prop *prop)
> +{
> + return security_context_to_sid(secdata, seclen, &prop->selinux.secid,
> + GFP_KERNEL);
> +}
> +
> static int selinux_lsmprop_to_secctx(struct lsm_prop *prop,
> struct lsm_context *cp)
> {
> @@ -7694,6 +7708,7 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = {
>
> LSM_HOOK_INIT(ismaclabel, selinux_ismaclabel),
> LSM_HOOK_INIT(secctx_to_secid, selinux_secctx_to_secid),
> + LSM_HOOK_INIT(secctx_to_lsmprop, selinux_secctx_to_lsmprop),
> LSM_HOOK_INIT(release_secctx, selinux_release_secctx),
> LSM_HOOK_INIT(inode_invalidate_secctx, selinux_inode_invalidate_secctx),
> LSM_HOOK_INIT(inode_notifysecctx, selinux_inode_notifysecctx),
> @@ -7812,6 +7827,7 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = {
> LSM_HOOK_INIT(sem_alloc_security, selinux_sem_alloc_security),
> LSM_HOOK_INIT(secid_to_secctx, selinux_secid_to_secctx),
> LSM_HOOK_INIT(lsmprop_to_secctx, selinux_lsmprop_to_secctx),
> + LSM_HOOK_INIT(update_lsmprop, selinux_update_lsmprop),
> LSM_HOOK_INIT(inode_getsecctx, selinux_inode_getsecctx),
> LSM_HOOK_INIT(sk_alloc_security, selinux_sk_alloc_security),
> LSM_HOOK_INIT(tun_dev_alloc_security, selinux_tun_dev_alloc_security),
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 5/7] Smack: hooks for secctx_to_lsmprop and update_lsmprop
2026-09-02 22:01 ` [PATCH v2 0/7] Change skb secmarks to x-array indexes Casey Schaufler
` (3 preceding siblings ...)
2026-09-02 22:01 ` [PATCH v2 4/7] SELinux: hooks for secctx_to_lsmprop and update_lsmprop Casey Schaufler
@ 2026-09-02 22:01 ` Casey Schaufler
2026-09-03 6:15 ` John Johansen
2026-09-02 22:01 ` [PATCH v2 6/7] Apparmor: " Casey Schaufler
2026-09-02 22:01 ` [PATCH v2 7/7] net, lsm: Change skb secmarks to x-array indexes Casey Schaufler
6 siblings, 1 reply; 15+ messages in thread
From: Casey Schaufler @ 2026-09-02 22:01 UTC (permalink / raw)
To: casey, paul, linux-security-module, pablo, fw, phil
Cc: linux-kernel, netfilter-devel, coreteam, jmorris, serge, keescook,
john.johansen, penguin-kernel, stephen.smalley.work, selinux
Implement these hooks.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
security/smack/smack_lsm.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index ff115068c5c0..fcfadd5d9994 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -4909,6 +4909,37 @@ static int smack_lsmprop_to_secctx(struct lsm_prop *prop,
return smack_to_secctx(prop->smack.skp, cp);
}
+/**
+ * smack_secctx_to_lsmprop - add the smack label to an lsmprop
+ * @secdata: smack label
+ * @seclen: how long label is
+ * @prop: where to put the result
+ *
+ * Exists for audit and networking code.
+ */
+static int smack_secctx_to_lsmprop(const char *secdata, u32 seclen,
+ struct lsm_prop *prop)
+{
+ prop->smack.skp = smk_find_entry(secdata);
+
+ return 0;
+}
+
+/**
+ * smack_update_lsmprop - set the smack label in an lsmprop
+ * @dest: destination properties
+ * @src: source properties
+ * @lsmid: which LSM is relevant.
+ *
+ * Set the Smack entry in the @dest if appropriate.
+ */
+static void smack_update_lsmprop(struct lsm_prop *dest, struct lsm_prop *src,
+ int lsmid)
+{
+ if (lsmid == LSM_ID_SMACK || lsmid == LSM_ID_UNDEF)
+ dest->smack.skp = src->smack.skp;
+}
+
/**
* smack_secctx_to_secid - return the secid for a smack label
* @secdata: smack label
@@ -5269,6 +5300,8 @@ static struct security_hook_list smack_hooks[] __ro_after_init = {
LSM_HOOK_INIT(secid_to_secctx, smack_secid_to_secctx),
LSM_HOOK_INIT(lsmprop_to_secctx, smack_lsmprop_to_secctx),
LSM_HOOK_INIT(secctx_to_secid, smack_secctx_to_secid),
+ LSM_HOOK_INIT(secctx_to_lsmprop, smack_secctx_to_lsmprop),
+ LSM_HOOK_INIT(update_lsmprop, smack_update_lsmprop),
LSM_HOOK_INIT(inode_notifysecctx, smack_inode_notifysecctx),
LSM_HOOK_INIT(inode_setsecctx, smack_inode_setsecctx),
LSM_HOOK_INIT(inode_getsecctx, smack_inode_getsecctx),
--
2.54.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH v2 5/7] Smack: hooks for secctx_to_lsmprop and update_lsmprop
2026-09-02 22:01 ` [PATCH v2 5/7] Smack: " Casey Schaufler
@ 2026-09-03 6:15 ` John Johansen
0 siblings, 0 replies; 15+ messages in thread
From: John Johansen @ 2026-09-03 6:15 UTC (permalink / raw)
To: Casey Schaufler, paul, linux-security-module, pablo, fw, phil
Cc: linux-kernel, netfilter-devel, coreteam, jmorris, serge, keescook,
penguin-kernel, stephen.smalley.work, selinux
On 9/2/26 15:01, Casey Schaufler wrote:
> Implement these hooks.
>
beyond the question from the previous patch, wanting more in the
description, and the quick double check question below.
This is looks right
> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
> ---
> security/smack/smack_lsm.c | 33 +++++++++++++++++++++++++++++++++
> 1 file changed, 33 insertions(+)
>
> diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
> index ff115068c5c0..fcfadd5d9994 100644
> --- a/security/smack/smack_lsm.c
> +++ b/security/smack/smack_lsm.c
> @@ -4909,6 +4909,37 @@ static int smack_lsmprop_to_secctx(struct lsm_prop *prop,
> return smack_to_secctx(prop->smack.skp, cp);
> }
>
> +/**
> + * smack_secctx_to_lsmprop - add the smack label to an lsmprop
> + * @secdata: smack label
> + * @seclen: how long label is
> + * @prop: where to put the result
> + *
> + * Exists for audit and networking code.
> + */
> +static int smack_secctx_to_lsmprop(const char *secdata, u32 seclen,
> + struct lsm_prop *prop)
> +{
> + prop->smack.skp = smk_find_entry(secdata);
just double checking a null value here, looks to be okay, but just double
checking as I just did a quick skim of the code.
> +
> + return 0;
> +}
> +
> +/**
> + * smack_update_lsmprop - set the smack label in an lsmprop
> + * @dest: destination properties
> + * @src: source properties
> + * @lsmid: which LSM is relevant.
> + *
> + * Set the Smack entry in the @dest if appropriate.
> + */
> +static void smack_update_lsmprop(struct lsm_prop *dest, struct lsm_prop *src,
> + int lsmid)
> +{
> + if (lsmid == LSM_ID_SMACK || lsmid == LSM_ID_UNDEF)
> + dest->smack.skp = src->smack.skp;
> +}
> +
> /**
> * smack_secctx_to_secid - return the secid for a smack label
> * @secdata: smack label
> @@ -5269,6 +5300,8 @@ static struct security_hook_list smack_hooks[] __ro_after_init = {
> LSM_HOOK_INIT(secid_to_secctx, smack_secid_to_secctx),
> LSM_HOOK_INIT(lsmprop_to_secctx, smack_lsmprop_to_secctx),
> LSM_HOOK_INIT(secctx_to_secid, smack_secctx_to_secid),
> + LSM_HOOK_INIT(secctx_to_lsmprop, smack_secctx_to_lsmprop),
> + LSM_HOOK_INIT(update_lsmprop, smack_update_lsmprop),
> LSM_HOOK_INIT(inode_notifysecctx, smack_inode_notifysecctx),
> LSM_HOOK_INIT(inode_setsecctx, smack_inode_setsecctx),
> LSM_HOOK_INIT(inode_getsecctx, smack_inode_getsecctx),
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 6/7] Apparmor: hooks for secctx_to_lsmprop and update_lsmprop
2026-09-02 22:01 ` [PATCH v2 0/7] Change skb secmarks to x-array indexes Casey Schaufler
` (4 preceding siblings ...)
2026-09-02 22:01 ` [PATCH v2 5/7] Smack: " Casey Schaufler
@ 2026-09-02 22:01 ` Casey Schaufler
2026-09-03 9:39 ` John Johansen
2026-09-02 22:01 ` [PATCH v2 7/7] net, lsm: Change skb secmarks to x-array indexes Casey Schaufler
6 siblings, 1 reply; 15+ messages in thread
From: Casey Schaufler @ 2026-09-02 22:01 UTC (permalink / raw)
To: casey, paul, linux-security-module, pablo, fw, phil
Cc: linux-kernel, netfilter-devel, coreteam, jmorris, serge, keescook,
john.johansen, penguin-kernel, stephen.smalley.work, selinux
Implement these hooks.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
security/apparmor/include/secid.h | 4 ++++
security/apparmor/lsm.c | 2 ++
security/apparmor/secid.c | 21 +++++++++++++++++++++
3 files changed, 27 insertions(+)
diff --git a/security/apparmor/include/secid.h b/security/apparmor/include/secid.h
index 6025d3849cf8..ba7adf2fc09e 100644
--- a/security/apparmor/include/secid.h
+++ b/security/apparmor/include/secid.h
@@ -28,6 +28,10 @@ struct aa_label *aa_secid_to_label(u32 secid);
int apparmor_secid_to_secctx(u32 secid, struct lsm_context *cp);
int apparmor_lsmprop_to_secctx(struct lsm_prop *prop, struct lsm_context *cp);
int apparmor_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
+int apparmor_secctx_to_lsmprop(const char *secdata, u32 seclen,
+ struct lsm_prop *prop);
+void apparmor_update_lsmprop(struct lsm_prop *dest, struct lsm_prop *src,
+ int lsmid);
void apparmor_release_secctx(struct lsm_context *cp);
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 88d12e89d115..1f304b88eaf9 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -1766,6 +1766,8 @@ static struct security_hook_list apparmor_hooks[] __ro_after_init = {
LSM_HOOK_INIT(secid_to_secctx, apparmor_secid_to_secctx),
LSM_HOOK_INIT(lsmprop_to_secctx, apparmor_lsmprop_to_secctx),
LSM_HOOK_INIT(secctx_to_secid, apparmor_secctx_to_secid),
+ LSM_HOOK_INIT(secctx_to_lsmprop, apparmor_secctx_to_lsmprop),
+ LSM_HOOK_INIT(update_lsmprop, apparmor_update_lsmprop),
LSM_HOOK_INIT(release_secctx, apparmor_release_secctx),
#ifdef CONFIG_IO_URING
diff --git a/security/apparmor/secid.c b/security/apparmor/secid.c
index 28caf66b9033..d35fdbf074e0 100644
--- a/security/apparmor/secid.c
+++ b/security/apparmor/secid.c
@@ -106,6 +106,27 @@ int apparmor_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
return 0;
}
+int apparmor_secctx_to_lsmprop(const char *secdata, u32 seclen,
+ struct lsm_prop *prop)
+{
+ struct aa_label *label;
+
+ label = aa_label_strn_parse(&root_ns->unconfined->label, secdata,
+ seclen, GFP_KERNEL, false, false);
+ if (IS_ERR(label))
+ return PTR_ERR(label);
+ prop->apparmor.label = label;
+
+ return 0;
+}
+
+void apparmor_update_lsmprop(struct lsm_prop *dest, struct lsm_prop *src,
+ int lsmid)
+{
+ if (lsmid == LSM_ID_APPARMOR || lsmid == LSM_ID_UNDEF)
+ dest->apparmor.label = src->apparmor.label;
+}
+
void apparmor_release_secctx(struct lsm_context *cp)
{
if (cp->id == LSM_ID_APPARMOR) {
--
2.54.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH v2 6/7] Apparmor: hooks for secctx_to_lsmprop and update_lsmprop
2026-09-02 22:01 ` [PATCH v2 6/7] Apparmor: " Casey Schaufler
@ 2026-09-03 9:39 ` John Johansen
0 siblings, 0 replies; 15+ messages in thread
From: John Johansen @ 2026-09-03 9:39 UTC (permalink / raw)
To: Casey Schaufler, paul, linux-security-module, pablo, fw, phil
Cc: linux-kernel, netfilter-devel, coreteam, jmorris, serge, keescook,
penguin-kernel, stephen.smalley.work, selinux
the code itself looks right
same nit on update_lsmprop as previous two patches.
I know you are working within the insane constraints of the secid, but it really
hurts that apparmor has a local xarray for secids, and now the LSM infra has
one too. I know its a problem to be solved later, I am just griping about the
current state of affairs.
On 9/2/26 15:01, Casey Schaufler wrote:
> Implement these hooks.
>
> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
> ---
> security/apparmor/include/secid.h | 4 ++++
> security/apparmor/lsm.c | 2 ++
> security/apparmor/secid.c | 21 +++++++++++++++++++++
> 3 files changed, 27 insertions(+)
>
> diff --git a/security/apparmor/include/secid.h b/security/apparmor/include/secid.h
> index 6025d3849cf8..ba7adf2fc09e 100644
> --- a/security/apparmor/include/secid.h
> +++ b/security/apparmor/include/secid.h
> @@ -28,6 +28,10 @@ struct aa_label *aa_secid_to_label(u32 secid);
> int apparmor_secid_to_secctx(u32 secid, struct lsm_context *cp);
> int apparmor_lsmprop_to_secctx(struct lsm_prop *prop, struct lsm_context *cp);
> int apparmor_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
> +int apparmor_secctx_to_lsmprop(const char *secdata, u32 seclen,
> + struct lsm_prop *prop);
> +void apparmor_update_lsmprop(struct lsm_prop *dest, struct lsm_prop *src,
> + int lsmid);
> void apparmor_release_secctx(struct lsm_context *cp);
>
>
> diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
> index 88d12e89d115..1f304b88eaf9 100644
> --- a/security/apparmor/lsm.c
> +++ b/security/apparmor/lsm.c
> @@ -1766,6 +1766,8 @@ static struct security_hook_list apparmor_hooks[] __ro_after_init = {
> LSM_HOOK_INIT(secid_to_secctx, apparmor_secid_to_secctx),
> LSM_HOOK_INIT(lsmprop_to_secctx, apparmor_lsmprop_to_secctx),
> LSM_HOOK_INIT(secctx_to_secid, apparmor_secctx_to_secid),
> + LSM_HOOK_INIT(secctx_to_lsmprop, apparmor_secctx_to_lsmprop),
> + LSM_HOOK_INIT(update_lsmprop, apparmor_update_lsmprop),
> LSM_HOOK_INIT(release_secctx, apparmor_release_secctx),
>
> #ifdef CONFIG_IO_URING
> diff --git a/security/apparmor/secid.c b/security/apparmor/secid.c
> index 28caf66b9033..d35fdbf074e0 100644
> --- a/security/apparmor/secid.c
> +++ b/security/apparmor/secid.c
> @@ -106,6 +106,27 @@ int apparmor_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
> return 0;
> }
>
> +int apparmor_secctx_to_lsmprop(const char *secdata, u32 seclen,
> + struct lsm_prop *prop)
> +{
> + struct aa_label *label;
> +
> + label = aa_label_strn_parse(&root_ns->unconfined->label, secdata,
> + seclen, GFP_KERNEL, false, false);
> + if (IS_ERR(label))
> + return PTR_ERR(label);
> + prop->apparmor.label = label;
> +
> + return 0;
> +}
> +
> +void apparmor_update_lsmprop(struct lsm_prop *dest, struct lsm_prop *src,
> + int lsmid)
> +{
> + if (lsmid == LSM_ID_APPARMOR || lsmid == LSM_ID_UNDEF)
> + dest->apparmor.label = src->apparmor.label;
> +}
> +
> void apparmor_release_secctx(struct lsm_context *cp)
> {
> if (cp->id == LSM_ID_APPARMOR) {
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 7/7] net, lsm: Change skb secmarks to x-array indexes
2026-09-02 22:01 ` [PATCH v2 0/7] Change skb secmarks to x-array indexes Casey Schaufler
` (5 preceding siblings ...)
2026-09-02 22:01 ` [PATCH v2 6/7] Apparmor: " Casey Schaufler
@ 2026-09-02 22:01 ` Casey Schaufler
2026-09-03 7:31 ` John Johansen
6 siblings, 1 reply; 15+ messages in thread
From: Casey Schaufler @ 2026-09-02 22:01 UTC (permalink / raw)
To: casey, paul, linux-security-module, pablo, fw, phil
Cc: linux-kernel, netfilter-devel, coreteam, jmorris, serge, keescook,
john.johansen, penguin-kernel, stephen.smalley.work, selinux
Maintain a xarray of lsm_prop structures which represent the
LSM security information passed via skb->secmark. Pass the xarray
index of the appropriate lsm_prop (the secxa) instead of an LSM
specific secid. Allow multiple LSMs to specify their components
in xarray entries, or create new entries as necessary.
Change uses of security_secctx_to_secid() to security_secctx_to_lsmprop()
in the netfilter and iptables code. Change security_secmark_relabel_packet()
to accept an lsm_prop pointer rather than a secid. Change secxa_set_secmark()
to update and create new entries as necessary.
Update the SELinux, Smack and AppArmor hooks that use secmarks to
expect a secxa xarray index instead of a secid.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
include/linux/lsm_hook_defs.h | 2 +-
include/linux/lsm_secxa.h | 2 +
include/linux/security.h | 4 +-
net/netfilter/nfnetlink_queue.c | 12 +++++-
net/netfilter/nft_meta.c | 15 ++++---
net/netfilter/xt_SECMARK.c | 16 +++++--
security/apparmor/net.c | 8 +++-
security/lsm_secxa.c | 20 ++++++++-
security/security.c | 6 +--
security/selinux/hooks.c | 71 +++++++++++++++++++++++++++-----
security/smack/smack_lsm.c | 10 ++++-
security/smack/smack_netfilter.c | 10 +++--
12 files changed, 141 insertions(+), 35 deletions(-)
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 679c40a8e127..8ecf07e0e3f0 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -371,7 +371,7 @@ LSM_HOOK(void, LSM_RET_VOID, inet_csk_clone, struct sock *newsk,
const struct request_sock *req)
LSM_HOOK(void, LSM_RET_VOID, inet_conn_established, struct sock *sk,
struct sk_buff *skb)
-LSM_HOOK(int, 0, secmark_relabel_packet, u32 secid)
+LSM_HOOK(int, 0, secmark_relabel_packet, struct lsm_prop *prop)
LSM_HOOK(void, LSM_RET_VOID, secmark_refcount_inc, void)
LSM_HOOK(void, LSM_RET_VOID, secmark_refcount_dec, void)
LSM_HOOK(void, LSM_RET_VOID, req_classify_flow, const struct request_sock *req,
diff --git a/include/linux/lsm_secxa.h b/include/linux/lsm_secxa.h
index 84b06c093460..5be9d64e67e4 100644
--- a/include/linux/lsm_secxa.h
+++ b/include/linux/lsm_secxa.h
@@ -7,6 +7,8 @@
#ifndef __LINUX_LSM_SECXA_H
#define __LINUX_LSM_SECXA_H
+#include <linux/types.h>
+
#ifdef CONFIG_SECURITY
struct lsm_prop;
diff --git a/include/linux/security.h b/include/linux/security.h
index 19adc19eb9af..ffbd1708065f 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1715,7 +1715,7 @@ void security_inet_csk_clone(struct sock *newsk,
const struct request_sock *req);
void security_inet_conn_established(struct sock *sk,
struct sk_buff *skb);
-int security_secmark_relabel_packet(u32 secid);
+int security_secmark_relabel_packet(struct lsm_prop *prop);
void security_secmark_refcount_inc(void);
void security_secmark_refcount_dec(void);
int security_tun_dev_alloc_security(void **security);
@@ -1898,7 +1898,7 @@ static inline void security_inet_conn_established(struct sock *sk,
{
}
-static inline int security_secmark_relabel_packet(u32 secid)
+static inline int security_secmark_relabel_packet(struct lsm_prop *prop)
{
return 0;
}
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index b8aaf39cb4d8..ebab037edc6b 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -32,6 +32,7 @@
#include <linux/cgroup-defs.h>
#include <linux/rhashtable.h>
#include <linux/jhash.h>
+#include <linux/lsm_secxa.h>
#include <net/gso.h>
#include <net/sock.h>
#include <net/tcp_states.h>
@@ -606,8 +607,15 @@ static int nfqnl_get_sk_secctx(struct sk_buff *skb, struct lsm_context *ctx)
{
int seclen = 0;
#if IS_ENABLED(CONFIG_NETWORK_SECMARK)
- if (skb->secmark)
- seclen = security_secid_to_secctx(skb->secmark, ctx);
+ struct lsm_prop *prop;
+ int rc;
+
+ if (skb->secmark) {
+ rc = secxa_get_lsmprop(&prop, skb->secmark);
+ if (rc)
+ return 0;
+ seclen = security_lsmprop_to_secctx(prop, ctx, LSM_ID_UNDEF);
+ }
#endif
return seclen;
}
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index bd0f7a0931f4..664191dfa4b2 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -927,21 +927,24 @@ static const struct nla_policy nft_secmark_policy[NFTA_SECMARK_MAX + 1] = {
static int nft_secmark_compute_secid(struct nft_secmark *priv)
{
- u32 tmp_secid = 0;
+ struct lsm_prop tmp_prop;
+ u32 secxa = 0;
int err;
- err = security_secctx_to_secid(priv->ctx, strlen(priv->ctx), &tmp_secid);
+ err = security_secctx_to_lsmprop(priv->ctx, strlen(priv->ctx),
+ &tmp_prop, LSM_ID_UNDEF);
if (err)
return err;
- if (!tmp_secid)
- return -ENOENT;
+ err = secxa_from_lsmprop(&tmp_prop, &secxa);
+ if (err)
+ return err;
- err = security_secmark_relabel_packet(tmp_secid);
+ err = security_secmark_relabel_packet(&tmp_prop);
if (err)
return err;
- priv->secid = tmp_secid;
+ priv->secid = secxa;
return 0;
}
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c
index ea67aa92ddc2..05b023a7c576 100644
--- a/net/netfilter/xt_SECMARK.c
+++ b/net/netfilter/xt_SECMARK.c
@@ -43,13 +43,15 @@ secmark_tg(struct sk_buff *skb, const struct xt_secmark_target_info_v1 *info)
static int checkentry_lsm(struct xt_secmark_target_info_v1 *info)
{
+ struct lsm_prop prop;
int err;
info->secctx[SECMARK_SECCTX_MAX - 1] = '\0';
info->secid = 0;
- err = security_secctx_to_secid(info->secctx, strlen(info->secctx),
- &info->secid);
+ err = security_secctx_to_lsmprop(info->secctx, strlen(info->secctx),
+ &prop, LSM_ID_UNDEF);
+
if (err) {
if (err == -EINVAL)
pr_info_ratelimited("invalid security context \'%s\'\n",
@@ -57,18 +59,24 @@ static int checkentry_lsm(struct xt_secmark_target_info_v1 *info)
return err;
}
- if (!info->secid) {
+ if (!lsmprop_is_set(&prop)) {
pr_info_ratelimited("unable to map security context \'%s\'\n",
info->secctx);
return -ENOENT;
}
- err = security_secmark_relabel_packet(info->secid);
+ err = security_secmark_relabel_packet(&prop);
if (err) {
pr_info_ratelimited("unable to obtain relabeling permission\n");
return err;
}
+ err = secxa_from_lsmprop(&prop, &info->secid);
+ if (err) {
+ pr_info_ratelimited("unable to obtain secmark\n");
+ return err;
+ }
+
security_secmark_refcount_inc();
return 0;
}
diff --git a/security/apparmor/net.c b/security/apparmor/net.c
index cf590dd08540..e26e15c2d947 100644
--- a/security/apparmor/net.c
+++ b/security/apparmor/net.c
@@ -8,6 +8,7 @@
* Copyright 2009-2017 Canonical Ltd.
*/
+#include <linux/lsm_secxa.h>
#include "include/af_unix.h"
#include "include/apparmor.h"
#include "include/audit.h"
@@ -365,12 +366,17 @@ static int aa_secmark_perm(struct aa_profile *profile, u32 request, u32 secid,
struct apparmor_audit_data *ad)
{
int i, ret;
+ struct lsm_prop *prop;
struct aa_perms perms = { };
struct aa_ruleset *rules = profile->label.rules[0];
if (rules->secmark_count == 0)
return 0;
+ ret = secxa_get_lsmprop(&prop, secid);
+ if (ret)
+ return ret;
+
for (i = 0; i < rules->secmark_count; i++) {
if (!rules->secmark[i].secid) {
ret = apparmor_secmark_init(&rules->secmark[i]);
@@ -378,7 +384,7 @@ static int aa_secmark_perm(struct aa_profile *profile, u32 request, u32 secid,
return ret;
}
- if (rules->secmark[i].secid == secid ||
+ if (rules->secmark[i].secid == prop->apparmor.label->secid ||
rules->secmark[i].secid == AA_SECID_WILDCARD) {
if (rules->secmark[i].deny)
perms.deny = ALL_PERMS_MASK;
diff --git a/security/lsm_secxa.c b/security/lsm_secxa.c
index ccbe78095d70..f0702ac5601d 100644
--- a/security/lsm_secxa.c
+++ b/security/lsm_secxa.c
@@ -103,7 +103,25 @@ EXPORT_SYMBOL(secxa_from_lsmprop);
*/
void secxa_set_secmark(struct sk_buff *skb, u32 secxa)
{
- if (!skb->secmark)
+ struct lsm_prop *olp;
+ struct lsm_prop *nlp;
+ struct lsm_prop prop;
+ u32 tsecxa;
+ int rc;
+
+ if (!skb->secmark) {
skb->secmark = secxa;
+ return;
+ }
+
+ olp = xa_load(&secxa_xa, skb->secmark);
+ nlp = xa_load(&secxa_xa, secxa);
+
+ prop = *olp;
+ security_update_lsmprop(&prop, nlp, LSM_ID_UNDEF);
+
+ rc = secxa_from_lsmprop(&prop, &tsecxa);
+ if (!rc)
+ skb->secmark = tsecxa;
}
EXPORT_SYMBOL(secxa_set_secmark);
diff --git a/security/security.c b/security/security.c
index 1dec0037370b..e80e7823ce14 100644
--- a/security/security.c
+++ b/security/security.c
@@ -4646,15 +4646,15 @@ EXPORT_SYMBOL(security_inet_conn_established);
/**
* security_secmark_relabel_packet() - Check if setting a secmark is allowed
- * @secid: new secmark value
+ * @lsmprop: new secmark value
*
* Check if the process should be allowed to relabel packets to @secid.
*
* Return: Returns 0 if permission is granted.
*/
-int security_secmark_relabel_packet(u32 secid)
+int security_secmark_relabel_packet(struct lsm_prop *prop)
{
- return call_int_hook(secmark_relabel_packet, secid);
+ return call_int_hook(secmark_relabel_packet, prop);
}
EXPORT_SYMBOL(security_secmark_relabel_packet);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 12614478b638..bf832eff0b92 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -94,6 +94,7 @@
#include <linux/io_uring/cmd.h>
#include <uapi/linux/lsm.h>
#include <linux/memfd.h>
+#include <linux/lsm_secxa.h>
#include "initcalls.h"
#include "avc.h"
@@ -5414,7 +5415,16 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
return err;
if (selinux_secmark_enabled()) {
- err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET,
+ struct lsm_prop *prop;
+ u32 secmark = 0;
+
+ if (skb->secmark) {
+ err = secxa_get_lsmprop(&prop, skb->secmark);
+ if (!err)
+ secmark = prop->selinux.secid;
+ }
+
+ err = avc_has_perm(sk_sid, secmark, SECCLASS_PACKET,
PACKET__RECV, &ad);
if (err)
return err;
@@ -5483,7 +5493,15 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
}
if (secmark_active) {
- err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET,
+ struct lsm_prop *prop;
+ u32 secmark = 0;
+
+ if (skb->secmark) {
+ err = secxa_get_lsmprop(&prop, skb->secmark);
+ if (!err)
+ secmark = prop->selinux.secid;
+ }
+ err = avc_has_perm(sk_sid, secmark, SECCLASS_PACKET,
PACKET__RECV, &ad);
if (err)
return err;
@@ -5885,10 +5903,10 @@ static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid);
}
-static int selinux_secmark_relabel_packet(u32 sid)
+static int selinux_secmark_relabel_packet(struct lsm_prop *lsmprop)
{
- return avc_has_perm(current_sid(), sid, SECCLASS_PACKET, PACKET__RELABELTO,
- NULL);
+ return avc_has_perm(current_sid(), lsmprop->selinux.secid,
+ SECCLASS_PACKET, PACKET__RELABELTO, NULL);
}
static void selinux_secmark_refcount_inc(void)
@@ -6016,10 +6034,21 @@ static unsigned int selinux_ip_forward(void *priv, struct sk_buff *skb,
}
}
- if (secmark_active)
- if (avc_has_perm(peer_sid, skb->secmark,
+ if (secmark_active) {
+ struct lsm_prop *prop;
+ u32 secmark = 0;
+ int err;
+
+ if (skb->secmark) {
+ err = secxa_get_lsmprop(&prop, skb->secmark);
+ if (!err)
+ secmark = prop->selinux.secid;
+ }
+
+ if (avc_has_perm(peer_sid, secmark,
SECCLASS_PACKET, PACKET__FORWARD_IN, &ad))
return NF_DROP;
+ }
if (netlbl_enabled())
/* we do this in the FORWARD path and not the POST_ROUTING
@@ -6093,10 +6122,20 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
if (selinux_parse_skb(skb, &ad, NULL, 0, &proto))
return NF_DROP;
- if (selinux_secmark_enabled())
- if (avc_has_perm(sksec->sid, skb->secmark,
+ if (selinux_secmark_enabled()) {
+ struct lsm_prop *prop;
+ u32 secmark = 0;
+ int err;
+
+ if (skb->secmark) {
+ err = secxa_get_lsmprop(&prop, skb->secmark);
+ if (!err)
+ secmark = prop->selinux.secid;
+ }
+ if (avc_has_perm(sksec->sid, secmark,
SECCLASS_PACKET, PACKET__SEND, &ad))
return NF_DROP_ERR(-ECONNREFUSED);
+ }
if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto))
return NF_DROP_ERR(-ECONNREFUSED);
@@ -6215,10 +6254,20 @@ static unsigned int selinux_ip_postroute(void *priv,
if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL))
return NF_DROP;
- if (secmark_active)
- if (avc_has_perm(peer_sid, skb->secmark,
+ if (secmark_active) {
+ struct lsm_prop *prop;
+ u32 secmark = 0;
+ int err;
+
+ if (skb->secmark) {
+ err = secxa_get_lsmprop(&prop, skb->secmark);
+ if (!err)
+ secmark = prop->selinux.secid;
+ }
+ if (avc_has_perm(peer_sid, secmark,
SECCLASS_PACKET, secmark_perm, &ad))
return NF_DROP_ERR(-ECONNREFUSED);
+ }
if (peerlbl_active) {
u32 if_sid;
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index fcfadd5d9994..79140e6829a4 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -42,6 +42,7 @@
#include <linux/fs_context.h>
#include <linux/fs_parser.h>
#include <linux/watch_queue.h>
+#include <linux/lsm_secxa.h>
#include <linux/io_uring/cmd.h>
#include <uapi/linux/lsm.h>
#include "smack.h"
@@ -4189,10 +4190,17 @@ static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip)
#ifdef CONFIG_NETWORK_SECMARK
static struct smack_known *smack_from_skb(struct sk_buff *skb)
{
+ struct lsm_prop *prop;
+ int rc;
+
if (skb == NULL || skb->secmark == 0)
return NULL;
- return smack_from_secid(skb->secmark);
+ rc = secxa_get_lsmprop(&prop, skb->secmark);
+ if (prop)
+ return prop->smack.skp;
+
+ return NULL;
}
#else
static inline struct smack_known *smack_from_skb(struct sk_buff *skb)
diff --git a/security/smack/smack_netfilter.c b/security/smack/smack_netfilter.c
index b363c42f252e..0378f74aa22b 100644
--- a/security/smack/smack_netfilter.c
+++ b/security/smack/smack_netfilter.c
@@ -24,13 +24,17 @@ static unsigned int smack_ip_output(void *priv,
const struct nf_hook_state *state)
{
struct sock *sk = skb_to_full_sk(skb);
+ struct lsm_prop prop = { };
struct socket_smack *ssp;
- struct smack_known *skp;
+ u32 secxa;
+ int rc;
if (sk) {
ssp = smack_sock(sk);
- skp = ssp->smk_out;
- secxa_set_secmark(skb, skp->smk_secid);
+ prop.smack.skp = ssp->smk_out;
+ rc = secxa_from_lsmprop(&prop, &secxa);
+ if (!rc)
+ secxa_set_secmark(skb, secxa);
}
return NF_ACCEPT;
--
2.54.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH v2 7/7] net, lsm: Change skb secmarks to x-array indexes
2026-09-02 22:01 ` [PATCH v2 7/7] net, lsm: Change skb secmarks to x-array indexes Casey Schaufler
@ 2026-09-03 7:31 ` John Johansen
0 siblings, 0 replies; 15+ messages in thread
From: John Johansen @ 2026-09-03 7:31 UTC (permalink / raw)
To: Casey Schaufler, paul, linux-security-module, pablo, fw, phil
Cc: linux-kernel, netfilter-devel, coreteam, jmorris, serge, keescook,
penguin-kernel, stephen.smalley.work, selinux
On 9/2/26 15:01, Casey Schaufler wrote:
> Maintain a xarray of lsm_prop structures which represent the
> LSM security information passed via skb->secmark. Pass the xarray
> index of the appropriate lsm_prop (the secxa) instead of an LSM
> specific secid. Allow multiple LSMs to specify their components
> in xarray entries, or create new entries as necessary.
>
> Change uses of security_secctx_to_secid() to security_secctx_to_lsmprop()
> in the netfilter and iptables code. Change security_secmark_relabel_packet()
> to accept an lsm_prop pointer rather than a secid. Change secxa_set_secmark()
> to update and create new entries as necessary.
>
> Update the SELinux, Smack and AppArmor hooks that use secmarks to
> expect a secxa xarray index instead of a secid.
>
see comments below
> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
> ---
> include/linux/lsm_hook_defs.h | 2 +-
> include/linux/lsm_secxa.h | 2 +
> include/linux/security.h | 4 +-
> net/netfilter/nfnetlink_queue.c | 12 +++++-
> net/netfilter/nft_meta.c | 15 ++++---
> net/netfilter/xt_SECMARK.c | 16 +++++--
> security/apparmor/net.c | 8 +++-
> security/lsm_secxa.c | 20 ++++++
> security/security.c | 6 +--
> security/selinux/hooks.c | 71 +++++++++++++++++++++++++++-----
> security/smack/smack_lsm.c | 10 ++++-
> security/smack/smack_netfilter.c | 10 +++--
> 12 files changed, 141 insertions(+), 35 deletions(-)
>
> diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
> index 679c40a8e127..8ecf07e0e3f0 100644
> --- a/include/linux/lsm_hook_defs.h
> +++ b/include/linux/lsm_hook_defs.h
> @@ -371,7 +371,7 @@ LSM_HOOK(void, LSM_RET_VOID, inet_csk_clone, struct sock *newsk,
> const struct request_sock *req)
> LSM_HOOK(void, LSM_RET_VOID, inet_conn_established, struct sock *sk,
> struct sk_buff *skb)
> -LSM_HOOK(int, 0, secmark_relabel_packet, u32 secid)
> +LSM_HOOK(int, 0, secmark_relabel_packet, struct lsm_prop *prop)
> LSM_HOOK(void, LSM_RET_VOID, secmark_refcount_inc, void)
> LSM_HOOK(void, LSM_RET_VOID, secmark_refcount_dec, void)
> LSM_HOOK(void, LSM_RET_VOID, req_classify_flow, const struct request_sock *req,
> diff --git a/include/linux/lsm_secxa.h b/include/linux/lsm_secxa.h
> index 84b06c093460..5be9d64e67e4 100644
> --- a/include/linux/lsm_secxa.h
> +++ b/include/linux/lsm_secxa.h
> @@ -7,6 +7,8 @@
> #ifndef __LINUX_LSM_SECXA_H
> #define __LINUX_LSM_SECXA_H
>
> +#include <linux/types.h>
> +
> #ifdef CONFIG_SECURITY
>
> struct lsm_prop;
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 19adc19eb9af..ffbd1708065f 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -1715,7 +1715,7 @@ void security_inet_csk_clone(struct sock *newsk,
> const struct request_sock *req);
> void security_inet_conn_established(struct sock *sk,
> struct sk_buff *skb);
> -int security_secmark_relabel_packet(u32 secid);
> +int security_secmark_relabel_packet(struct lsm_prop *prop);
> void security_secmark_refcount_inc(void);
> void security_secmark_refcount_dec(void);
> int security_tun_dev_alloc_security(void **security);
> @@ -1898,7 +1898,7 @@ static inline void security_inet_conn_established(struct sock *sk,
> {
> }
>
> -static inline int security_secmark_relabel_packet(u32 secid)
> +static inline int security_secmark_relabel_packet(struct lsm_prop *prop)
> {
> return 0;
> }
> diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
> index b8aaf39cb4d8..ebab037edc6b 100644
> --- a/net/netfilter/nfnetlink_queue.c
> +++ b/net/netfilter/nfnetlink_queue.c
> @@ -32,6 +32,7 @@
> #include <linux/cgroup-defs.h>
> #include <linux/rhashtable.h>
> #include <linux/jhash.h>
> +#include <linux/lsm_secxa.h>
> #include <net/gso.h>
> #include <net/sock.h>
> #include <net/tcp_states.h>
> @@ -606,8 +607,15 @@ static int nfqnl_get_sk_secctx(struct sk_buff *skb, struct lsm_context *ctx)
> {
> int seclen = 0;
> #if IS_ENABLED(CONFIG_NETWORK_SECMARK)
> - if (skb->secmark)
> - seclen = security_secid_to_secctx(skb->secmark, ctx);
> + struct lsm_prop *prop;
> + int rc;
> +
> + if (skb->secmark) {
> + rc = secxa_get_lsmprop(&prop, skb->secmark);
> + if (rc)
> + return 0;
> + seclen = security_lsmprop_to_secctx(prop, ctx, LSM_ID_UNDEF);
> + }
> #endif
> return seclen;
> }
> diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
> index bd0f7a0931f4..664191dfa4b2 100644
> --- a/net/netfilter/nft_meta.c
> +++ b/net/netfilter/nft_meta.c
> @@ -927,21 +927,24 @@ static const struct nla_policy nft_secmark_policy[NFTA_SECMARK_MAX + 1] = {
>
> static int nft_secmark_compute_secid(struct nft_secmark *priv)
> {
> - u32 tmp_secid = 0;
> + struct lsm_prop tmp_prop;
> + u32 secxa = 0;
> int err;
>
> - err = security_secctx_to_secid(priv->ctx, strlen(priv->ctx), &tmp_secid);
> + err = security_secctx_to_lsmprop(priv->ctx, strlen(priv->ctx),
> + &tmp_prop, LSM_ID_UNDEF);
> if (err)
> return err;
>
> - if (!tmp_secid)
> - return -ENOENT;
> + err = secxa_from_lsmprop(&tmp_prop, &secxa);
> + if (err)
> + return err;
>
> - err = security_secmark_relabel_packet(tmp_secid);
> + err = security_secmark_relabel_packet(&tmp_prop);
> if (err)
> return err;
>
> - priv->secid = tmp_secid;
> + priv->secid = secxa;
> return 0;
> }
>
> diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c
> index ea67aa92ddc2..05b023a7c576 100644
> --- a/net/netfilter/xt_SECMARK.c
> +++ b/net/netfilter/xt_SECMARK.c
> @@ -43,13 +43,15 @@ secmark_tg(struct sk_buff *skb, const struct xt_secmark_target_info_v1 *info)
>
> static int checkentry_lsm(struct xt_secmark_target_info_v1 *info)
> {
> + struct lsm_prop prop;
> int err;
>
> info->secctx[SECMARK_SECCTX_MAX - 1] = '\0';
> info->secid = 0;
>
> - err = security_secctx_to_secid(info->secctx, strlen(info->secctx),
> - &info->secid);
> + err = security_secctx_to_lsmprop(info->secctx, strlen(info->secctx),
> + &prop, LSM_ID_UNDEF);
> +
> if (err) {
> if (err == -EINVAL)
> pr_info_ratelimited("invalid security context \'%s\'\n",
> @@ -57,18 +59,24 @@ static int checkentry_lsm(struct xt_secmark_target_info_v1 *info)
> return err;
> }
>
> - if (!info->secid) {
> + if (!lsmprop_is_set(&prop)) {
> pr_info_ratelimited("unable to map security context \'%s\'\n",
> info->secctx);
> return -ENOENT;
> }
>
> - err = security_secmark_relabel_packet(info->secid);
> + err = security_secmark_relabel_packet(&prop);
> if (err) {
> pr_info_ratelimited("unable to obtain relabeling permission\n");
> return err;
> }
>
> + err = secxa_from_lsmprop(&prop, &info->secid);
> + if (err) {
> + pr_info_ratelimited("unable to obtain secmark\n");
> + return err;
> + }
> +
> security_secmark_refcount_inc();
> return 0;
> }
> diff --git a/security/apparmor/net.c b/security/apparmor/net.c
> index cf590dd08540..e26e15c2d947 100644
> --- a/security/apparmor/net.c
> +++ b/security/apparmor/net.c
> @@ -8,6 +8,7 @@
> * Copyright 2009-2017 Canonical Ltd.
> */
>
> +#include <linux/lsm_secxa.h>
> #include "include/af_unix.h"
> #include "include/apparmor.h"
> #include "include/audit.h"
> @@ -365,12 +366,17 @@ static int aa_secmark_perm(struct aa_profile *profile, u32 request, u32 secid,
> struct apparmor_audit_data *ad)
> {
> int i, ret;
> + struct lsm_prop *prop;
> struct aa_perms perms = { };
> struct aa_ruleset *rules = profile->label.rules[0];
>
> if (rules->secmark_count == 0)
> return 0;
>
> + ret = secxa_get_lsmprop(&prop, secid);
> + if (ret)
> + return ret;
> +
> for (i = 0; i < rules->secmark_count; i++) {
> if (!rules->secmark[i].secid) {
> ret = apparmor_secmark_init(&rules->secmark[i]);
> @@ -378,7 +384,7 @@ static int aa_secmark_perm(struct aa_profile *profile, u32 request, u32 secid,
> return ret;
> }
>
> - if (rules->secmark[i].secid == secid ||
> + if (rules->secmark[i].secid == prop->apparmor.label->secid ||
> rules->secmark[i].secid == AA_SECID_WILDCARD) {
> if (rules->secmark[i].deny)
> perms.deny = ALL_PERMS_MASK;
> diff --git a/security/lsm_secxa.c b/security/lsm_secxa.c
> index ccbe78095d70..f0702ac5601d 100644
> --- a/security/lsm_secxa.c
> +++ b/security/lsm_secxa.c
> @@ -103,7 +103,25 @@ EXPORT_SYMBOL(secxa_from_lsmprop);
> */
> void secxa_set_secmark(struct sk_buff *skb, u32 secxa)
> {
> - if (!skb->secmark)
> + struct lsm_prop *olp;
> + struct lsm_prop *nlp;
> + struct lsm_prop prop;
> + u32 tsecxa;
> + int rc;
> +
> + if (!skb->secmark) {
> skb->secmark = secxa;
> + return;
> + }
> +
> + olp = xa_load(&secxa_xa, skb->secmark);
> + nlp = xa_load(&secxa_xa, secxa);
> +
> + prop = *olp;
> + security_update_lsmprop(&prop, nlp, LSM_ID_UNDEF);
> +
> + rc = secxa_from_lsmprop(&prop, &tsecxa);
> + if (!rc)
> + skb->secmark = tsecxa;
> }
> EXPORT_SYMBOL(secxa_set_secmark);
> diff --git a/security/security.c b/security/security.c
> index 1dec0037370b..e80e7823ce14 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -4646,15 +4646,15 @@ EXPORT_SYMBOL(security_inet_conn_established);
>
> /**
> * security_secmark_relabel_packet() - Check if setting a secmark is allowed
> - * @secid: new secmark value
> + * @lsmprop: new secmark value
> *
> * Check if the process should be allowed to relabel packets to @secid.
change @secid to @lsmprop
> *
> * Return: Returns 0 if permission is granted.
> */
> -int security_secmark_relabel_packet(u32 secid)
> +int security_secmark_relabel_packet(struct lsm_prop *prop)
> {
> - return call_int_hook(secmark_relabel_packet, secid);
> + return call_int_hook(secmark_relabel_packet, prop);
> }
> EXPORT_SYMBOL(security_secmark_relabel_packet);
>
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 12614478b638..bf832eff0b92 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -94,6 +94,7 @@
> #include <linux/io_uring/cmd.h>
> #include <uapi/linux/lsm.h>
> #include <linux/memfd.h>
> +#include <linux/lsm_secxa.h>
>
> #include "initcalls.h"
> #include "avc.h"
> @@ -5414,7 +5415,16 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
> return err;
>
> if (selinux_secmark_enabled()) {
> - err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET,
> + struct lsm_prop *prop;
> + u32 secmark = 0;
> +
> + if (skb->secmark) {
> + err = secxa_get_lsmprop(&prop, skb->secmark);
> + if (!err)
> + secmark = prop->selinux.secid;
> + }
> +
> + err = avc_has_perm(sk_sid, secmark, SECCLASS_PACKET,
> PACKET__RECV, &ad);
> if (err)
> return err;
> @@ -5483,7 +5493,15 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
> }
>
> if (secmark_active) {
> - err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET,
> + struct lsm_prop *prop;
> + u32 secmark = 0;
> +
> + if (skb->secmark) {
> + err = secxa_get_lsmprop(&prop, skb->secmark);
> + if (!err)
> + secmark = prop->selinux.secid;
> + }
> + err = avc_has_perm(sk_sid, secmark, SECCLASS_PACKET,
> PACKET__RECV, &ad);
> if (err)
> return err;
> @@ -5885,10 +5903,10 @@ static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
> selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid);
> }
>
> -static int selinux_secmark_relabel_packet(u32 sid)
> +static int selinux_secmark_relabel_packet(struct lsm_prop *lsmprop)
> {
> - return avc_has_perm(current_sid(), sid, SECCLASS_PACKET, PACKET__RELABELTO,
> - NULL);
> + return avc_has_perm(current_sid(), lsmprop->selinux.secid,
> + SECCLASS_PACKET, PACKET__RELABELTO, NULL);
> }
>
> static void selinux_secmark_refcount_inc(void)
> @@ -6016,10 +6034,21 @@ static unsigned int selinux_ip_forward(void *priv, struct sk_buff *skb,
> }
> }
>
> - if (secmark_active)
> - if (avc_has_perm(peer_sid, skb->secmark,
> + if (secmark_active) {
> + struct lsm_prop *prop;
> + u32 secmark = 0;
> + int err;
> +
> + if (skb->secmark) {
> + err = secxa_get_lsmprop(&prop, skb->secmark);
> + if (!err)
> + secmark = prop->selinux.secid;
> + }
> +
> + if (avc_has_perm(peer_sid, secmark,
> SECCLASS_PACKET, PACKET__FORWARD_IN, &ad))
> return NF_DROP;
> + }
>
> if (netlbl_enabled())
> /* we do this in the FORWARD path and not the POST_ROUTING
> @@ -6093,10 +6122,20 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
> if (selinux_parse_skb(skb, &ad, NULL, 0, &proto))
> return NF_DROP;
>
> - if (selinux_secmark_enabled())
> - if (avc_has_perm(sksec->sid, skb->secmark,
> + if (selinux_secmark_enabled()) {
> + struct lsm_prop *prop;
> + u32 secmark = 0;
> + int err;
> +
> + if (skb->secmark) {
> + err = secxa_get_lsmprop(&prop, skb->secmark);
> + if (!err)
> + secmark = prop->selinux.secid;
> + }
> + if (avc_has_perm(sksec->sid, secmark,
> SECCLASS_PACKET, PACKET__SEND, &ad))
> return NF_DROP_ERR(-ECONNREFUSED);
> + }
>
> if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto))
> return NF_DROP_ERR(-ECONNREFUSED);
> @@ -6215,10 +6254,20 @@ static unsigned int selinux_ip_postroute(void *priv,
> if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL))
> return NF_DROP;
>
> - if (secmark_active)
> - if (avc_has_perm(peer_sid, skb->secmark,
> + if (secmark_active) {
> + struct lsm_prop *prop;
> + u32 secmark = 0;
> + int err;
> +
> + if (skb->secmark) {
> + err = secxa_get_lsmprop(&prop, skb->secmark);
> + if (!err)
> + secmark = prop->selinux.secid;
> + }
> + if (avc_has_perm(peer_sid, secmark,
> SECCLASS_PACKET, secmark_perm, &ad))
> return NF_DROP_ERR(-ECONNREFUSED);
> + }
doesn't
selinux_socket_getpeersec_dgram()
selinux_req_classify_flow()
I haven't detangled yet whether the xfrm hooks, every grab the
secmark of a packet directly. It looks to me so far to be only
the skb->xfrm->security->ctx_sid. Paul?
overall this conversion bothers me, in that we need to put this
boiler plate into every hook, instead of having the infrastructure
handle the conversion for the specific LSM.
I know this is partly being done because of the
if (secmakr_active)
check, but I think it would be far cleaner, and less prone to error
if the infra could grab the per LSM property and pass that instead,
and not expose the secid value that has to go through the mapping.
At a minimum the API should identify this mapped secid is different
from the secid being passed in some of the other hooks.
Perhaps we could have a way to store if the LSM is using the secid
so the LSM infra could do the secmark_active check before calling the
hook?
>
> if (peerlbl_active) {
> u32 if_sid;
> diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
> index fcfadd5d9994..79140e6829a4 100644
> --- a/security/smack/smack_lsm.c
> +++ b/security/smack/smack_lsm.c
> @@ -42,6 +42,7 @@
> #include <linux/fs_context.h>
> #include <linux/fs_parser.h>
> #include <linux/watch_queue.h>
> +#include <linux/lsm_secxa.h>
> #include <linux/io_uring/cmd.h>
> #include <uapi/linux/lsm.h>
> #include "smack.h"
> @@ -4189,10 +4190,17 @@ static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip)
> #ifdef CONFIG_NETWORK_SECMARK
> static struct smack_known *smack_from_skb(struct sk_buff *skb)
> {
> + struct lsm_prop *prop;
> + int rc;
> +
> if (skb == NULL || skb->secmark == 0)
> return NULL;
>
> - return smack_from_secid(skb->secmark);
> + rc = secxa_get_lsmprop(&prop, skb->secmark);
> + if (prop)
> + return prop->smack.skp;
> +
> + return NULL;
> }
> #else
> static inline struct smack_known *smack_from_skb(struct sk_buff *skb)
> diff --git a/security/smack/smack_netfilter.c b/security/smack/smack_netfilter.c
> index b363c42f252e..0378f74aa22b 100644
> --- a/security/smack/smack_netfilter.c
> +++ b/security/smack/smack_netfilter.c
> @@ -24,13 +24,17 @@ static unsigned int smack_ip_output(void *priv,
> const struct nf_hook_state *state)
> {
> struct sock *sk = skb_to_full_sk(skb);
> + struct lsm_prop prop = { };
> struct socket_smack *ssp;
> - struct smack_known *skp;
> + u32 secxa;
> + int rc;
>
> if (sk) {
> ssp = smack_sock(sk);
> - skp = ssp->smk_out;
> - secxa_set_secmark(skb, skp->smk_secid);
> + prop.smack.skp = ssp->smk_out;
> + rc = secxa_from_lsmprop(&prop, &secxa);
> + if (!rc)
> + secxa_set_secmark(skb, secxa);
> }
>
> return NF_ACCEPT;
^ permalink raw reply [flat|nested] 15+ messages in thread