[PATCH 1/2] LSM: Exclusive secmark usage

Casey Schaufler posted 2 patches 4 months, 1 week ago
[PATCH 1/2] LSM: Exclusive secmark usage
Posted by Casey Schaufler 4 months, 1 week ago
The network secmark can only be used by one security module
at a time. Establish mechanism to identify to security modules
whether they have access to the secmark. SELinux already
incorparates mechanism, but it has to be added to Smack and
AppArmor.

Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
 include/linux/lsm_hooks.h        |  1 +
 security/apparmor/include/net.h  |  5 +++++
 security/apparmor/lsm.c          |  7 ++++---
 security/security.c              |  6 ++++++
 security/selinux/hooks.c         |  4 +++-
 security/smack/smack.h           |  5 +++++
 security/smack/smack_lsm.c       |  3 ++-
 security/smack/smack_netfilter.c | 10 ++++++++--
 8 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 090d1d3e19fe..69c1b509577a 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -116,6 +116,7 @@ struct lsm_blob_sizes {
 	int lbs_xattr_count; /* number of xattr slots in new_xattrs array */
 	int lbs_tun_dev;
 	int lbs_bdev;
+	bool lbs_secmark; /* expressed desire for secmark use */
 };
 
 /*
diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
index 0d0b0ce42723..1199918448a9 100644
--- a/security/apparmor/include/net.h
+++ b/security/apparmor/include/net.h
@@ -52,6 +52,11 @@ struct aa_sk_ctx {
 	struct aa_label __rcu *peer_lastupdate;	/* ptr cmp only, no deref */
 };
 
+static inline bool aa_secmark(void)
+{
+	return apparmor_blob_sizes.lbs_secmark;
+}
+
 static inline struct aa_sk_ctx *aa_sock(const struct sock *sk)
 {
 	return sk->sk_security + apparmor_blob_sizes.lbs_sock;
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 8e1cc229b41b..34eac7da80e6 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -1512,7 +1512,7 @@ static int apparmor_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
 	struct aa_sk_ctx *ctx = aa_sock(sk);
 	int error;
 
-	if (!skb->secmark)
+	if (!aa_secmark() || !skb->secmark)
 		return 0;
 
 	/*
@@ -1641,7 +1641,7 @@ static int apparmor_inet_conn_request(const struct sock *sk, struct sk_buff *skb
 	struct aa_sk_ctx *ctx = aa_sock(sk);
 	int error;
 
-	if (!skb->secmark)
+	if (!aa_secmark() || !skb->secmark)
 		return 0;
 
 	rcu_read_lock();
@@ -1661,6 +1661,7 @@ struct lsm_blob_sizes apparmor_blob_sizes __ro_after_init = {
 	.lbs_file = sizeof(struct aa_file_ctx),
 	.lbs_task = sizeof(struct aa_task_ctx),
 	.lbs_sock = sizeof(struct aa_sk_ctx),
+	.lbs_secmark = true,
 };
 
 static const struct lsm_id apparmor_lsmid = {
@@ -2360,7 +2361,7 @@ static unsigned int apparmor_ip_postroute(void *priv,
 	struct sock *sk;
 	int error;
 
-	if (!skb->secmark)
+	if (!aa_secmark() || !skb->secmark)
 		return NF_ACCEPT;
 
 	sk = skb_to_full_sk(skb);
diff --git a/security/security.c b/security/security.c
index ad163f06bf7a..e59e3d403de6 100644
--- a/security/security.c
+++ b/security/security.c
@@ -283,6 +283,12 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed)
 	lsm_set_blob_size(&needed->lbs_xattr_count,
 			  &blob_sizes.lbs_xattr_count);
 	lsm_set_blob_size(&needed->lbs_bdev, &blob_sizes.lbs_bdev);
+	if (needed->lbs_secmark) {
+		if (blob_sizes.lbs_secmark)
+			needed->lbs_secmark = false;
+		else
+			blob_sizes.lbs_secmark = true;
+	}
 }
 
 /* Prepare LSM for initialization. */
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index c95a5874bf7d..5b6db7d8effb 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -164,7 +164,8 @@ __setup("checkreqprot=", checkreqprot_setup);
  */
 static int selinux_secmark_enabled(void)
 {
-	return (selinux_policycap_alwaysnetwork() ||
+	return selinux_blob_sizes.lbs_secmark &&
+	       (selinux_policycap_alwaysnetwork() ||
 		atomic_read(&selinux_secmark_refcount));
 }
 
@@ -7183,6 +7184,7 @@ struct lsm_blob_sizes selinux_blob_sizes __ro_after_init = {
 	.lbs_xattr_count = SELINUX_INODE_INIT_XATTRS,
 	.lbs_tun_dev = sizeof(struct tun_security_struct),
 	.lbs_ib = sizeof(struct ib_security_struct),
+	.lbs_secmark = true,
 };
 
 #ifdef CONFIG_PERF_EVENTS
diff --git a/security/smack/smack.h b/security/smack/smack.h
index bf6a6ed3946c..89bf62ad60f1 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -383,6 +383,11 @@ static inline int smk_inode_transmutable(const struct inode *isp)
 	return (sip->smk_flags & SMK_INODE_TRANSMUTE) != 0;
 }
 
+static inline bool smack_secmark(void)
+{
+	return smack_blob_sizes.lbs_secmark;
+}
+
 /*
  * Present a pointer to the smack label entry in an inode blob.
  */
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index fc340a6f0dde..ee86818633c1 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -4102,7 +4102,7 @@ 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)
 {
-	if (skb == NULL || skb->secmark == 0)
+	if (!smack_secmark() || skb == NULL || skb->secmark == 0)
 		return NULL;
 
 	return smack_from_secid(skb->secmark);
@@ -5030,6 +5030,7 @@ struct lsm_blob_sizes smack_blob_sizes __ro_after_init = {
 	.lbs_sock = sizeof(struct socket_smack),
 	.lbs_superblock = sizeof(struct superblock_smack),
 	.lbs_xattr_count = SMACK_INODE_INIT_XATTRS,
+	.lbs_secmark = true,
 };
 
 static const struct lsm_id smack_lsmid = {
diff --git a/security/smack/smack_netfilter.c b/security/smack/smack_netfilter.c
index 8fd747b3653a..2e82051b3998 100644
--- a/security/smack/smack_netfilter.c
+++ b/security/smack/smack_netfilter.c
@@ -26,7 +26,7 @@ static unsigned int smack_ip_output(void *priv,
 	struct socket_smack *ssp;
 	struct smack_known *skp;
 
-	if (sk) {
+	if (smack_secmark() && sk) {
 		ssp = smack_sock(sk);
 		skp = ssp->smk_out;
 		skb->secmark = skp->smk_secid;
@@ -54,12 +54,18 @@ static const struct nf_hook_ops smack_nf_ops[] = {
 
 static int __net_init smack_nf_register(struct net *net)
 {
+	if (!smack_secmark())
+		return 0;
+
 	return nf_register_net_hooks(net, smack_nf_ops,
 				     ARRAY_SIZE(smack_nf_ops));
 }
 
 static void __net_exit smack_nf_unregister(struct net *net)
 {
+	if (!smack_secmark())
+		return;
+
 	nf_unregister_net_hooks(net, smack_nf_ops, ARRAY_SIZE(smack_nf_ops));
 }
 
@@ -70,7 +76,7 @@ static struct pernet_operations smack_net_ops = {
 
 static int __init smack_nf_ip_init(void)
 {
-	if (smack_enabled == 0)
+	if (smack_enabled == 0 || !smack_secmark())
 		return 0;
 
 	printk(KERN_DEBUG "Smack: Registering netfilter hooks\n");
-- 
2.51.0
Re: [PATCH 1/2] LSM: Exclusive secmark usage
Posted by Paul Moore 3 months, 3 weeks ago
On Wed, Oct 1, 2025 at 5:56 PM Casey Schaufler <casey@schaufler-ca.com> wrote:
>
> The network secmark can only be used by one security module
> at a time. Establish mechanism to identify to security modules
> whether they have access to the secmark. SELinux already
> incorparates mechanism, but it has to be added to Smack and
> AppArmor.
>
> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
> ---
>  include/linux/lsm_hooks.h        |  1 +
>  security/apparmor/include/net.h  |  5 +++++
>  security/apparmor/lsm.c          |  7 ++++---
>  security/security.c              |  6 ++++++
>  security/selinux/hooks.c         |  4 +++-
>  security/smack/smack.h           |  5 +++++
>  security/smack/smack_lsm.c       |  3 ++-
>  security/smack/smack_netfilter.c | 10 ++++++++--
>  8 files changed, 34 insertions(+), 7 deletions(-)

...

>  /* Prepare LSM for initialization. */
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index c95a5874bf7d..5b6db7d8effb 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -164,7 +164,8 @@ __setup("checkreqprot=", checkreqprot_setup);
>   */
>  static int selinux_secmark_enabled(void)
>  {
> -       return (selinux_policycap_alwaysnetwork() ||
> +       return selinux_blob_sizes.lbs_secmark &&
> +              (selinux_policycap_alwaysnetwork() ||
>                 atomic_read(&selinux_secmark_refcount));
>  }

This is an odd way to approach secmark enablement in SELinux, and not
something I think I want to see.  Ignoring the
selinux_policycap_alwaysnetwork "abomination" (a joke I think only
about four people in the world might understand), the
selinux_secmark_enabled() function is really there simply as a
performance optimization since the majority of SELinux users don't
utilize the per-packet access controls.  Using it as a mechanism to
effectively turn off SELinux's secmark functionality could result in a
confusing situation for users who are setting SELinux secmarks on
packets and not seeing the system's policy properly enforced.

-- 
paul-moore.com
Re: [PATCH 1/2] LSM: Exclusive secmark usage
Posted by Casey Schaufler 3 months ago
On 10/13/2025 2:57 PM, Paul Moore wrote:
> On Wed, Oct 1, 2025 at 5:56 PM Casey Schaufler <casey@schaufler-ca.com> wrote:
>> The network secmark can only be used by one security module
>> at a time. Establish mechanism to identify to security modules
>> whether they have access to the secmark. SELinux already
>> incorparates mechanism, but it has to be added to Smack and
>> AppArmor.
>>
>> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
>> ---
>>  include/linux/lsm_hooks.h        |  1 +
>>  security/apparmor/include/net.h  |  5 +++++
>>  security/apparmor/lsm.c          |  7 ++++---
>>  security/security.c              |  6 ++++++
>>  security/selinux/hooks.c         |  4 +++-
>>  security/smack/smack.h           |  5 +++++
>>  security/smack/smack_lsm.c       |  3 ++-
>>  security/smack/smack_netfilter.c | 10 ++++++++--
>>  8 files changed, 34 insertions(+), 7 deletions(-)
> ..
>
>>  /* Prepare LSM for initialization. */
>> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
>> index c95a5874bf7d..5b6db7d8effb 100644
>> --- a/security/selinux/hooks.c
>> +++ b/security/selinux/hooks.c
>> @@ -164,7 +164,8 @@ __setup("checkreqprot=", checkreqprot_setup);
>>   */
>>  static int selinux_secmark_enabled(void)
>>  {
>> -       return (selinux_policycap_alwaysnetwork() ||
>> +       return selinux_blob_sizes.lbs_secmark &&
>> +              (selinux_policycap_alwaysnetwork() ||
>>                 atomic_read(&selinux_secmark_refcount));
>>  }
> This is an odd way to approach secmark enablement in SELinux, and not
> something I think I want to see.  Ignoring the
> selinux_policycap_alwaysnetwork "abomination" (a joke I think only
> about four people in the world might understand), the
> selinux_secmark_enabled() function is really there simply as a
> performance optimization since the majority of SELinux users don't
> utilize the per-packet access controls.  Using it as a mechanism to
> effectively turn off SELinux's secmark functionality could result in a
> confusing situation for users who are setting SELinux secmarks on
> packets and not seeing the system's policy properly enforced.

One could argue that a user who creates a system that would have this
problem has configured it incorrectly. A system with Smack before SELinux
( https://lwn.net/Articles/645245/ ) would, by the "first LSM gets it"
rule, give the secmark to Smack. If the user wants SELinux to use secmarks
SELinux must precede Smack. The SELinux policy, as well as the Smack rule
set, are going to have to be correct for the configuration, as are any
netfilter rules. Yes, that's likely to make some sysadmin's heads explode.
Complex configurations are admittedly difficult to get right. When you
start with a system that isn't simple and add to it you can help but run
into situations that are baffling.

You can create a correctly behaving system with the "first LSM" behavior.
You can also create a system that goes completely wonky. Just as you want
a well trained developer creating your SELinux policy, you want someone
who knows what they're doing composing LSM stacks.

This is going to be an issue for other features, including audit rules and IMA. 

Re: [PATCH 1/2] LSM: Exclusive secmark usage
Posted by Stephen Smalley 4 months ago
On Wed, Oct 1, 2025 at 5:56 PM Casey Schaufler <casey@schaufler-ca.com> wrote:
>
> The network secmark can only be used by one security module
> at a time. Establish mechanism to identify to security modules

a mechanism to inform security modules?

> whether they have access to the secmark. SELinux already
> incorparates mechanism, but it has to be added to Smack and

incorporates

> AppArmor.
>
> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
> ---
>  include/linux/lsm_hooks.h        |  1 +
>  security/apparmor/include/net.h  |  5 +++++
>  security/apparmor/lsm.c          |  7 ++++---
>  security/security.c              |  6 ++++++
>  security/selinux/hooks.c         |  4 +++-
>  security/smack/smack.h           |  5 +++++
>  security/smack/smack_lsm.c       |  3 ++-
>  security/smack/smack_netfilter.c | 10 ++++++++--
>  8 files changed, 34 insertions(+), 7 deletions(-)
>

> diff --git a/security/security.c b/security/security.c
> index ad163f06bf7a..e59e3d403de6 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -283,6 +283,12 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed)
>         lsm_set_blob_size(&needed->lbs_xattr_count,
>                           &blob_sizes.lbs_xattr_count);
>         lsm_set_blob_size(&needed->lbs_bdev, &blob_sizes.lbs_bdev);
> +       if (needed->lbs_secmark) {
> +               if (blob_sizes.lbs_secmark)
> +                       needed->lbs_secmark = false;
> +               else
> +                       blob_sizes.lbs_secmark = true;
> +       }

So if I understand correctly, the first LSM to register with
lbs_secmark set wins.
Not sure that's a great idea - seemingly some LSMs may want to insist
that they get to use secmark regardless of registration order?
Re: [PATCH 1/2] LSM: Exclusive secmark usage
Posted by Casey Schaufler 4 months ago
On 10/9/2025 11:49 AM, Stephen Smalley wrote:
> On Wed, Oct 1, 2025 at 5:56 PM Casey Schaufler <casey@schaufler-ca.com> wrote:
>> The network secmark can only be used by one security module
>> at a time. Establish mechanism to identify to security modules
> a mechanism to inform security modules?
>
>> whether they have access to the secmark. SELinux already
>> incorparates mechanism, but it has to be added to Smack and
> incorporates
>
>> AppArmor.
>>
>> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
>> ---
>>  include/linux/lsm_hooks.h        |  1 +
>>  security/apparmor/include/net.h  |  5 +++++
>>  security/apparmor/lsm.c          |  7 ++++---
>>  security/security.c              |  6 ++++++
>>  security/selinux/hooks.c         |  4 +++-
>>  security/smack/smack.h           |  5 +++++
>>  security/smack/smack_lsm.c       |  3 ++-
>>  security/smack/smack_netfilter.c | 10 ++++++++--
>>  8 files changed, 34 insertions(+), 7 deletions(-)
>>
>> diff --git a/security/security.c b/security/security.c
>> index ad163f06bf7a..e59e3d403de6 100644
>> --- a/security/security.c
>> +++ b/security/security.c
>> @@ -283,6 +283,12 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed)
>>         lsm_set_blob_size(&needed->lbs_xattr_count,
>>                           &blob_sizes.lbs_xattr_count);
>>         lsm_set_blob_size(&needed->lbs_bdev, &blob_sizes.lbs_bdev);
>> +       if (needed->lbs_secmark) {
>> +               if (blob_sizes.lbs_secmark)
>> +                       needed->lbs_secmark = false;
>> +               else
>> +                       blob_sizes.lbs_secmark = true;
>> +       }
> So if I understand correctly, the first LSM to register with
> lbs_secmark set wins.
> Not sure that's a great idea - seemingly some LSMs may want to insist
> that they get to use secmark regardless of registration order?

But what if two LSMs insist on getting the secmark? The whole point
is to make it possible to use multiple LSMs that what the feature at
the same time. The limitation on a secmark being a u32 is a huge problem,
and Paul has battled with the netdev people over it for years.

Re: [PATCH 1/2] LSM: Exclusive secmark usage
Posted by Paul Moore 3 months, 3 weeks ago
On Fri, Oct 10, 2025 at 11:03 AM Casey Schaufler <casey@schaufler-ca.com> wrote:
> On 10/9/2025 11:49 AM, Stephen Smalley wrote:
> > On Wed, Oct 1, 2025 at 5:56 PM Casey Schaufler <casey@schaufler-ca.com> wrote:
> >> The network secmark can only be used by one security module
> >> at a time. Establish mechanism to identify to security modules
> > a mechanism to inform security modules?
> >
> >> whether they have access to the secmark. SELinux already
> >> incorparates mechanism, but it has to be added to Smack and
> > incorporates
> >
> >> AppArmor.
> >>
> >> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
> >> ---
> >>  include/linux/lsm_hooks.h        |  1 +
> >>  security/apparmor/include/net.h  |  5 +++++
> >>  security/apparmor/lsm.c          |  7 ++++---
> >>  security/security.c              |  6 ++++++
> >>  security/selinux/hooks.c         |  4 +++-
> >>  security/smack/smack.h           |  5 +++++
> >>  security/smack/smack_lsm.c       |  3 ++-
> >>  security/smack/smack_netfilter.c | 10 ++++++++--
> >>  8 files changed, 34 insertions(+), 7 deletions(-)
> >>
> >> diff --git a/security/security.c b/security/security.c
> >> index ad163f06bf7a..e59e3d403de6 100644
> >> --- a/security/security.c
> >> +++ b/security/security.c
> >> @@ -283,6 +283,12 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed)
> >>         lsm_set_blob_size(&needed->lbs_xattr_count,
> >>                           &blob_sizes.lbs_xattr_count);
> >>         lsm_set_blob_size(&needed->lbs_bdev, &blob_sizes.lbs_bdev);
> >> +       if (needed->lbs_secmark) {
> >> +               if (blob_sizes.lbs_secmark)
> >> +                       needed->lbs_secmark = false;
> >> +               else
> >> +                       blob_sizes.lbs_secmark = true;
> >> +       }
> >
> > So if I understand correctly, the first LSM to register with
> > lbs_secmark set wins.
> > Not sure that's a great idea - seemingly some LSMs may want to insist
> > that they get to use secmark regardless of registration order?
>
> But what if two LSMs insist on getting the secmark? The whole point
> is to make it possible to use multiple LSMs that what the feature at
> the same time.

My current thinking is that if two LSMs *insist* on access to the
secmark, one of them has to fail to load/initialize, even if that
means a panic on boot (we should flag that as an invalid config in
Kconfig).

Perhaps the solution is to have lbs_secmark as a tristate value: don't
use secmarks, would like access to secmarks, must have access to
secmarks.  Upon registration a LSM that requested "would like" could
check to see if they have been granted access and could adjust
accordingly.  A LSM that requested "must have" would fail to register
if the secmarks were already taken by a prior LSM.

> The limitation on a secmark being a u32 is a huge problem,
> and Paul has battled with the netdev people over it for years.

I suspect the only way forward at this point is to convert the secmark
field into an IDR* that we could use to point to a LSM security blob
that could store LSM specific structs for both secmarks and general
LSM state associated with a skb.  This would also allow us to do some
cool things in the forward path that we can't properly do now and
would make it much easier to handle a wider variety of packet level
access control scenarios.

It's on my todo list for <hand_waving>someday</hand_waving>, but if
somebody wanted to do it that would be awesome.  Just a word of
warning, this is not a quick task and it is probably only suited for
someone who already has a few netdev inflicted scars.

*I see that IDR is now deprecated in favor of XArray, I haven't looked
that closely at XArray but it looks workable too.

-- 
paul-moore.com
Re: [PATCH 1/2] LSM: Exclusive secmark usage
Posted by Casey Schaufler 3 months ago
On 10/13/2025 3:11 PM, Paul Moore wrote:
> On Fri, Oct 10, 2025 at 11:03 AM Casey Schaufler <casey@schaufler-ca.com> wrote:
>> On 10/9/2025 11:49 AM, Stephen Smalley wrote:
>>> On Wed, Oct 1, 2025 at 5:56 PM Casey Schaufler <casey@schaufler-ca.com> wrote:
>>>> The network secmark can only be used by one security module
>>>> at a time. Establish mechanism to identify to security modules
>>> a mechanism to inform security modules?
>>>
>>>> whether they have access to the secmark. SELinux already
>>>> incorparates mechanism, but it has to be added to Smack and
>>> incorporates
>>>
>>>> AppArmor.
>>>>
>>>> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
>>>> ---
>>>>  include/linux/lsm_hooks.h        |  1 +
>>>>  security/apparmor/include/net.h  |  5 +++++
>>>>  security/apparmor/lsm.c          |  7 ++++---
>>>>  security/security.c              |  6 ++++++
>>>>  security/selinux/hooks.c         |  4 +++-
>>>>  security/smack/smack.h           |  5 +++++
>>>>  security/smack/smack_lsm.c       |  3 ++-
>>>>  security/smack/smack_netfilter.c | 10 ++++++++--
>>>>  8 files changed, 34 insertions(+), 7 deletions(-)
>>>>
>>>> diff --git a/security/security.c b/security/security.c
>>>> index ad163f06bf7a..e59e3d403de6 100644
>>>> --- a/security/security.c
>>>> +++ b/security/security.c
>>>> @@ -283,6 +283,12 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed)
>>>>         lsm_set_blob_size(&needed->lbs_xattr_count,
>>>>                           &blob_sizes.lbs_xattr_count);
>>>>         lsm_set_blob_size(&needed->lbs_bdev, &blob_sizes.lbs_bdev);
>>>> +       if (needed->lbs_secmark) {
>>>> +               if (blob_sizes.lbs_secmark)
>>>> +                       needed->lbs_secmark = false;
>>>> +               else
>>>> +                       blob_sizes.lbs_secmark = true;
>>>> +       }
>>> So if I understand correctly, the first LSM to register with
>>> lbs_secmark set wins.
>>> Not sure that's a great idea - seemingly some LSMs may want to insist
>>> that they get to use secmark regardless of registration order?
>> But what if two LSMs insist on getting the secmark? The whole point
>> is to make it possible to use multiple LSMs that what the feature at
>> the same time.
> My current thinking is that if two LSMs *insist* on access to the
> secmark, one of them has to fail to load/initialize, even if that
> means a panic on boot (we should flag that as an invalid config in
> Kconfig).

That's sensible, but why should an LSM be allowed to insist on access
to the secmark? Best I can tell, SELinux rarely uses it in real life.
Smack currently always uses it, but that's fixed in this patch set.
I would be perplexed by a "dog in the manger" attitude on the part of
any maintainers. 

>
> Perhaps the solution is to have lbs_secmark as a tristate value: don't
> use secmarks, would like access to secmarks, must have access to
> secmarks.  Upon registration a LSM that requested "would like" could
> check to see if they have been granted access and could adjust
> accordingly.  A LSM that requested "must have" would fail to register
> if the secmarks were already taken by a prior LSM.

I would be unhappy if any existing LSM decided it "must have" secmarks.
I can imagine a LSM that really required the secmark, but it would have
a tough time getting accepted.

>> The limitation on a secmark being a u32 is a huge problem,
>> and Paul has battled with the netdev people over it for years.
> I suspect the only way forward at this point is to convert the secmark
> field into an IDR* that we could use to point to a LSM security blob
> that could store LSM specific structs for both secmarks and general
> LSM state associated with a skb.  This would also allow us to do some
> cool things in the forward path that we can't properly do now and
> would make it much easier to handle a wider variety of packet level
> access control scenarios.
>
> It's on my todo list for <hand_waving>someday</hand_waving>, but if
> somebody wanted to do it that would be awesome.  Just a word of
> warning, this is not a quick task and it is probably only suited for
> someone who already has a few netdev inflicted scars.

I expect to be dead, or at least suffering serious memory loss,
by the time that work can be done. :(


>
> *I see that IDR is now deprecated in favor of XArray, I haven't looked
> that closely at XArray but it looks workable too.
>