* [PATCH 0/7] Change skb secmarks to x-array indexes
[not found] <20260813204854.19211-1-casey.ref@schaufler-ca.com>
@ 2026-08-13 20:48 ` Casey Schaufler
2026-08-13 20:48 ` [PATCH 1/7] net, smack: Create a function to set secmarks Casey Schaufler
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Casey Schaufler @ 2026-08-13 20:48 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
When security secmarks were added to the Linux network stack there was
only one Linux Security Module (LSM), SELinux. SELinux already used the
concept of a security ID (secid) as the representation of the security
information about a system subject (active entity) or object (passive
entity). Adding a container for a secid, the secmark, to the sk_buff
structure allowed for efficient transmission of the SELinux secid for
socket based access controls.
Subsequent LSMs have chosen to represent security information more
directly. Smack and AppArmor use pointers to structures containing
relevant information. Alas, these pointers do not fit in the u32 secmark
on most modern architectures. These LSMs are required to provide a secid
mapping to use secmarks.
Even with all LSMs that use secmarks having a secid to reference the
security information the mechanism is imperfect. A system that wants
to use multiple LSMs that use secmarks is constrained by the size
of the secmark. There is no rational way to fit multiple secids in a
secmark. While it would be possible to allow one LSM to use the secmark
and any others to be told it is unavailable, this has been deemed an
unacceptable limitation.
There is a lsm_prop structure available that contains security information
for any LSM that maintains it. The secmark cannot, unfortunately,
contain one. Instead, an x-array of lsm_prop structures is maintained,
and the index (secxa) is used in the secmark instead of the single LSM
restricted secid.
Uses of security_secctx_to_secid() have been changed to
security_secctx_to_lsmprop() in the netfilter and iptables code.
The security_secmark_relabel_packet() function has been updated to accept
an lsm_prop pointer rather than a secid.
To support multiple LSMs using a secmark it is necessary to re-evaluate
which lsm_prop structure represents the current security information
at each step where the secmark can be set. Smack sets the secmark for
every packet. Netfilter, used by SELinux, Smack and AppArmor, will set
the secmark on selected packets at a later time. If Smack and AppArmor
are active on a system Smack will set the secmark initially, and AppArmor
may reset it by netfilter rule.
https://github.com/cschaufler/lsm-stacking#secmark-xa-7.2-rc5-v1
Casey Schaufler (7):
net, smack: Create a function to set secmarks
LSM: Implement x array functions for secmarks
LSM: Two hooks for manipulating struct lsm_prop
SELinux: hooks for secctx_to_lsmprop and update_lsmprop
Smack: hooks for secctx_to_lsmprop and update_lsmprop
Apparmor: hooks for secctx_to_lsmprop and update_lsmprop
net, lsm: Change skb secmarks to x-array indexes
include/linux/lsm_hook_defs.h | 6 +-
include/linux/lsm_secxa.h | 22 ++++++
include/linux/security.h | 21 +++++-
net/netfilter/nfnetlink_queue.c | 12 ++-
net/netfilter/nft_meta.c | 16 ++--
net/netfilter/xt_CONNSECMARK.c | 3 +-
net/netfilter/xt_SECMARK.c | 15 ++--
security/Makefile | 1 +
security/apparmor/include/secid.h | 4 +
security/apparmor/lsm.c | 2 +
security/apparmor/net.c | 8 +-
security/apparmor/secid.c | 23 ++++++
security/lsm_secxa.c | 119 ++++++++++++++++++++++++++++++
security/security.c | 38 +++++++++-
security/selinux/hooks.c | 89 +++++++++++++++++++---
security/smack/smack_lsm.c | 46 +++++++++++-
security/smack/smack_netfilter.c | 9 ++-
17 files changed, 398 insertions(+), 36 deletions(-)
create mode 100644 include/linux/lsm_secxa.h
create mode 100644 security/lsm_secxa.c
--
2.54.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/7] net, smack: Create a function to set secmarks
2026-08-13 20:48 ` [PATCH 0/7] Change skb secmarks to x-array indexes Casey Schaufler
@ 2026-08-13 20:48 ` Casey Schaufler
2026-08-13 20:48 ` [PATCH 2/7] LSM: Implement x array functions for secmarks Casey Schaufler
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Casey Schaufler @ 2026-08-13 20:48 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 | 22 ++++++++++++++++++++++
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, 31 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..f4c732d26680
--- /dev/null
+++ b/include/linux/lsm_secxa.h
@@ -0,0 +1,22 @@
+/* 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_SECURITY
+
+#include <linux/security.h>
+#include <linux/skbuff.h>
+
+static inline void secxa_set_secmark(struct sk_buff *skb, u32 secxa)
+{
+ skb->secmark = secxa;
+}
+
+#endif /* CONFIG_SECURITY */
+
+#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] 8+ messages in thread
* [PATCH 2/7] LSM: Implement x array functions for secmarks
2026-08-13 20:48 ` [PATCH 0/7] Change skb secmarks to x-array indexes Casey Schaufler
2026-08-13 20:48 ` [PATCH 1/7] net, smack: Create a function to set secmarks Casey Schaufler
@ 2026-08-13 20:48 ` Casey Schaufler
2026-08-13 20:48 ` [PATCH 3/7] LSM: Two hooks for manipulating struct lsm_prop Casey Schaufler
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Casey Schaufler @ 2026-08-13 20:48 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 | 10 ++--
security/Makefile | 1 +
security/lsm_secxa.c | 107 ++++++++++++++++++++++++++++++++++++++
3 files changed, 113 insertions(+), 5 deletions(-)
create mode 100644 security/lsm_secxa.c
diff --git a/include/linux/lsm_secxa.h b/include/linux/lsm_secxa.h
index f4c732d26680..ffdc354b93fc 100644
--- a/include/linux/lsm_secxa.h
+++ b/include/linux/lsm_secxa.h
@@ -10,12 +10,12 @@
#ifdef CONFIG_SECURITY
#include <linux/security.h>
-#include <linux/skbuff.h>
-static inline void secxa_set_secmark(struct sk_buff *skb, u32 secxa)
-{
- skb->secmark = secxa;
-}
+struct sk_buff;
+
+int secxa_from_lsmprop(struct lsm_prop *prop);
+int secxa_get_lsmprop(struct lsm_prop **pro, u32 secxa);
+void secxa_set_secmark(struct sk_buff *skb, u32 secxa);
#endif /* CONFIG_SECURITY */
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..5b67d8218fd2
--- /dev/null
+++ b/security/lsm_secxa.c
@@ -0,0 +1,107 @@
+// 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);
+
+ 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
+ *
+ * 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)
+{
+ struct lsm_prop *lp;
+ unsigned long il;
+ unsigned int index = 0;
+ int rc;
+
+ xa_for_each(&secxa_xa, il, lp) {
+ if (!memcmp(prop, lp, sizeof(*prop)))
+ pr_info("%s found at index %lu\n", __func__, il);
+ if (!memcmp(prop, lp, sizeof(*prop)))
+ return il;
+ }
+
+ lp = kzalloc(sizeof(*lp), GFP_ATOMIC);
+ if (!lp)
+ return -ENOMEM;
+
+ rc = xa_alloc(&secxa_xa, &index, lp, xa_limit_32b, GFP_ATOMIC);
+ if (rc) {
+ kfree(lp);
+ return -EINVAL;
+ }
+ *lp = *prop;
+
+ return index;
+}
+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] 8+ messages in thread
* [PATCH 3/7] LSM: Two hooks for manipulating struct lsm_prop
2026-08-13 20:48 ` [PATCH 0/7] Change skb secmarks to x-array indexes Casey Schaufler
2026-08-13 20:48 ` [PATCH 1/7] net, smack: Create a function to set secmarks Casey Schaufler
2026-08-13 20:48 ` [PATCH 2/7] LSM: Implement x array functions for secmarks Casey Schaufler
@ 2026-08-13 20:48 ` Casey Schaufler
2026-08-13 20:48 ` [PATCH 4/7] SELinux: hooks for secctx_to_lsmprop and update_lsmprop Casey Schaufler
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Casey Schaufler @ 2026-08-13 20:48 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 | 17 +++++++++++++++++
security/security.c | 32 ++++++++++++++++++++++++++++++++
3 files changed, 53 insertions(+)
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 65c9609ec207..3666d821b8a1 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(int, -EOPNOTSUPP, 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, 0, 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..b209d681e79a 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);
+
+int 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,12 @@ static inline int security_lsmprop_to_secctx(struct lsm_prop *prop,
return -EOPNOTSUPP;
}
+static inline int security_update_lsmprop(struct lsm_prop *dest,
+ struct lsm_prop *src, int lsmid)
+{
+ return -EOPNOTSUPP;
+}
+
static inline int security_secctx_to_secid(const char *secdata,
u32 seclen,
u32 *secid)
@@ -1588,6 +1599,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..932a2eca28b3 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);
+int security_update_lsmprop(struct lsm_prop *dest, struct lsm_prop *src,
+ int lsmid)
+{
+ return call_int_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] 8+ messages in thread
* [PATCH 4/7] SELinux: hooks for secctx_to_lsmprop and update_lsmprop
2026-08-13 20:48 ` [PATCH 0/7] Change skb secmarks to x-array indexes Casey Schaufler
` (2 preceding siblings ...)
2026-08-13 20:48 ` [PATCH 3/7] LSM: Two hooks for manipulating struct lsm_prop Casey Schaufler
@ 2026-08-13 20:48 ` Casey Schaufler
2026-08-13 20:48 ` [PATCH 5/7] Smack: " Casey Schaufler
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Casey Schaufler @ 2026-08-13 20:48 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 | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8d6945edae7a..c05c05e71078 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6946,6 +6946,15 @@ static int selinux_ismaclabel(const char *name)
return (strcmp(name, XATTR_SELINUX_SUFFIX) == 0);
}
+static int 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;
+
+ return 0;
+}
+
static int selinux_secid_to_secctx(u32 secid, struct lsm_context *cp)
{
u32 seclen;
@@ -6964,6 +6973,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 +7710,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 +7829,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] 8+ messages in thread
* [PATCH 5/7] Smack: hooks for secctx_to_lsmprop and update_lsmprop
2026-08-13 20:48 ` [PATCH 0/7] Change skb secmarks to x-array indexes Casey Schaufler
` (3 preceding siblings ...)
2026-08-13 20:48 ` [PATCH 4/7] SELinux: hooks for secctx_to_lsmprop and update_lsmprop Casey Schaufler
@ 2026-08-13 20:48 ` Casey Schaufler
2026-08-13 20:48 ` [PATCH 6/7] Apparmor: " Casey Schaufler
2026-08-13 20:48 ` [PATCH 7/7] net, lsm: Change skb secmarks to x-array indexes Casey Schaufler
6 siblings, 0 replies; 8+ messages in thread
From: Casey Schaufler @ 2026-08-13 20:48 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 | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index ff115068c5c0..8e3ab61dfdd9 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -4909,6 +4909,40 @@ 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.
+ * Returns 0.
+ */
+static int 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;
+
+ return 0;
+}
+
/**
* smack_secctx_to_secid - return the secid for a smack label
* @secdata: smack label
@@ -5269,6 +5303,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] 8+ messages in thread
* [PATCH 6/7] Apparmor: hooks for secctx_to_lsmprop and update_lsmprop
2026-08-13 20:48 ` [PATCH 0/7] Change skb secmarks to x-array indexes Casey Schaufler
` (4 preceding siblings ...)
2026-08-13 20:48 ` [PATCH 5/7] Smack: " Casey Schaufler
@ 2026-08-13 20:48 ` Casey Schaufler
2026-08-13 20:48 ` [PATCH 7/7] net, lsm: Change skb secmarks to x-array indexes Casey Schaufler
6 siblings, 0 replies; 8+ messages in thread
From: Casey Schaufler @ 2026-08-13 20:48 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 | 23 +++++++++++++++++++++++
3 files changed, 29 insertions(+)
diff --git a/security/apparmor/include/secid.h b/security/apparmor/include/secid.h
index 6025d3849cf8..b290ae8f9b01 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);
+int 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..51f3e4ab053e 100644
--- a/security/apparmor/secid.c
+++ b/security/apparmor/secid.c
@@ -106,6 +106,29 @@ 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;
+}
+
+int 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;
+
+ return 0;
+}
+
void apparmor_release_secctx(struct lsm_context *cp)
{
if (cp->id == LSM_ID_APPARMOR) {
--
2.54.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 7/7] net, lsm: Change skb secmarks to x-array indexes
2026-08-13 20:48 ` [PATCH 0/7] Change skb secmarks to x-array indexes Casey Schaufler
` (5 preceding siblings ...)
2026-08-13 20:48 ` [PATCH 6/7] Apparmor: " Casey Schaufler
@ 2026-08-13 20:48 ` Casey Schaufler
6 siblings, 0 replies; 8+ messages in thread
From: Casey Schaufler @ 2026-08-13 20:48 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/security.h | 4 +-
net/netfilter/nfnetlink_queue.c | 12 +++++-
net/netfilter/nft_meta.c | 11 +++--
net/netfilter/xt_SECMARK.c | 12 ++++--
security/apparmor/net.c | 8 +++-
security/lsm_secxa.c | 18 ++++++--
security/security.c | 6 +--
security/selinux/hooks.c | 71 +++++++++++++++++++++++++++-----
security/smack/smack_lsm.c | 10 ++++-
security/smack/smack_netfilter.c | 8 ++--
11 files changed, 127 insertions(+), 35 deletions(-)
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 3666d821b8a1..7ba4547daded 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/security.h b/include/linux/security.h
index b209d681e79a..844fbef4a6a8 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1716,7 +1716,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);
@@ -1899,7 +1899,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..24535c45dab3 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -927,17 +927,20 @@ static const struct nla_policy nft_secmark_policy[NFTA_SECMARK_MAX + 1] = {
static int nft_secmark_compute_secid(struct nft_secmark *priv)
{
+ struct lsm_prop tmp_prop;
u32 tmp_secid = 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;
+ tmp_secid = secxa_from_lsmprop(&tmp_prop);
+ if (tmp_secid < 0)
+ return tmp_secid;
- err = security_secmark_relabel_packet(tmp_secid);
+ err = security_secmark_relabel_packet(&tmp_prop);
if (err)
return err;
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c
index ea67aa92ddc2..5a7b83c67430 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,20 @@ 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;
}
+ info->secid = secxa_from_lsmprop(&prop);
+
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 5b67d8218fd2..2015dab01bdf 100644
--- a/security/lsm_secxa.c
+++ b/security/lsm_secxa.c
@@ -71,8 +71,6 @@ int secxa_from_lsmprop(struct lsm_prop *prop)
int rc;
xa_for_each(&secxa_xa, il, lp) {
- if (!memcmp(prop, lp, sizeof(*prop)))
- pr_info("%s found at index %lu\n", __func__, il);
if (!memcmp(prop, lp, sizeof(*prop)))
return il;
}
@@ -101,7 +99,21 @@ 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;
+
+ 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);
+
+ skb->secmark = secxa_from_lsmprop(&prop);
}
EXPORT_SYMBOL(secxa_set_secmark);
diff --git a/security/security.c b/security/security.c
index 932a2eca28b3..059cf0a97d2c 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 c05c05e71078..55d7679f3403 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 8e3ab61dfdd9..38bd97c89179 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..5270b55eaacf 100644
--- a/security/smack/smack_netfilter.c
+++ b/security/smack/smack_netfilter.c
@@ -24,13 +24,15 @@ 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;
+ int secxa;
if (sk) {
ssp = smack_sock(sk);
- skp = ssp->smk_out;
- secxa_set_secmark(skb, skp->smk_secid);
+ prop.smack.skp = ssp->smk_out;
+ secxa = secxa_from_lsmprop(&prop);
+ secxa_set_secmark(skb, secxa);
}
return NF_ACCEPT;
--
2.54.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-08-13 20:59 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20260813204854.19211-1-casey.ref@schaufler-ca.com>
2026-08-13 20:48 ` [PATCH 0/7] Change skb secmarks to x-array indexes Casey Schaufler
2026-08-13 20:48 ` [PATCH 1/7] net, smack: Create a function to set secmarks Casey Schaufler
2026-08-13 20:48 ` [PATCH 2/7] LSM: Implement x array functions for secmarks Casey Schaufler
2026-08-13 20:48 ` [PATCH 3/7] LSM: Two hooks for manipulating struct lsm_prop Casey Schaufler
2026-08-13 20:48 ` [PATCH 4/7] SELinux: hooks for secctx_to_lsmprop and update_lsmprop Casey Schaufler
2026-08-13 20:48 ` [PATCH 5/7] Smack: " Casey Schaufler
2026-08-13 20:48 ` [PATCH 6/7] Apparmor: " Casey Schaufler
2026-08-13 20:48 ` [PATCH 7/7] net, lsm: Change skb secmarks to x-array indexes Casey Schaufler
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox