Re: [PATCH 0/3] NetLabel: add the remaining CIPSO tag types from the IETF draft

2006-11-29 Thread Casey Schaufler

--- [EMAIL PROTECTED] wrote:

> This patchset consists of three patches that add
> support for the remaining two
> tag types from the CIPSO draft specification, the
> enumerated and range tags.
> The most significant part about adding these two
> tags is that NetLabel now has
> the ability to represent more than 240 categories
> (limitation imposed by the
> current restricted bitmap tag).
> 
> In addition, the first patch in the set converts
> NetLabel's contiguous char
> string category bitmap stored in network friendly
> bit/byte order into a sparse
> bitmap stored in host friendly bit/byte order. 
> While this change was not
> required to support the new CIPSO tags, it should
> make life much easier as the
> old category bitmap would have proven problematic as
> the number of usable
> categories increases with the new tag types.  It
> also has a side effect of
> making the LSM specific code much less ugly.

Fabulous. Thank you.


Casey Schaufler
[EMAIL PROTECTED]
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/1] Allow LSM to use IP address/port number.

2007-07-21 Thread Casey Schaufler

--- Tetsuo Handa <[EMAIL PROTECTED]> wrote:

> 
> Hello.
> 
> Patrick McHardy wrote:
> > Quoting Tetsuo:
> > > > So, my approach is not using security context associated with a socket
> > > > but security context associated with a process.
> > Isn't the socket context derived from the process context?
> Not so regarding my case.
> 
> static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t
> priority)
> {
>   sk->sk_security = current->security;
>   return 0;
> }
> 
> will not help what I want to do.
> So, I'm not planning to use "sk->sk_security".

Before you go too far down this path please note that the quoted
code is bad* because back pointers from sockets to tasks can't be
reliable. See later versions for more reasonable behavior.

> I'm planning to use "current->security" at accept()/recvmsg() time.

The delivery of packets and the completion of these syscalls are
related but independent events. Be careful about the relationship
between the events and the placement of your checks.



* Stephen had good comments on the details on list earlier.

Casey Schaufler
[EMAIL PROTECTED]
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH net-2.6.25] Add packet filtering based on process's security context.

2008-01-22 Thread Casey Schaufler

--- Tetsuo Handa <[EMAIL PROTECTED]> wrote:

> ...
> 
> Currently, there is no way to directly map security context from incoming
> packet to user process. This is because the creator or owner of a socket is
> not always the receiver of an incoming packet. The userland process who
> receives the incoming packet is not known until a process calls
> sys_recvmsg().
> So, I want to add a LSM hook to give a security module a chance to control
> after the recipient of the incoming packet is known.

Do you have a real situation where two user processes with different
security contexts share a socket? How do you get into that situation,
and is it appropriate to have that situation in your security scheme?
Can this occur without using privilege?


Casey Schaufler
[EMAIL PROTECTED]
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 0/2] selinux: avoid nf hooks overhead when not needed

2016-04-06 Thread Casey Schaufler
On 4/6/2016 2:51 AM, Paolo Abeni wrote:
> Currently, selinux always registers iptables POSTROUTING hooks regarless of
> the running policy needs for any action to be performed by them.
>
> Even the socket_sock_rcv_skb() is always registered, but it can result in a 
> no-op
> depending on the current policy configuration.
>
> The above invocations in the kernel datapath are cause of measurable
> overhead in networking performance test.
>
> This patch series adds explicit notification for netlabel status change 
> (other relevant status change, like xfrm and secmark, are already notified to
> LSM) and use this information in selinux to register the above hooks only when
> the current status makes them relevant, deregistering them when no-op
>
> Avoiding the LSM hooks overhead, in netperf UDP_STREAM test with small 
> packets,
> gives about 5% performance improvement on rx and about 8% on tx.
>
> Paolo Abeni (2):
>   security: add hook for netlabel status change notification
>   selinux: implement support for dynamic net hook [de-]registration

Did you consider the fact that netlabel and the LSM socket
hooks are used by Smack as well as SELinux? Did you measure the
impact that your changes have on Smack? Does Smack even work
with your changes?

>
>  include/linux/lsm_hooks.h   |  6 
>  include/linux/security.h|  5 +++
>  net/netlabel/netlabel_cipso_v4.c|  8 +++--
>  net/netlabel/netlabel_unlabeled.c   |  5 ++-
>  security/security.c |  7 
>  security/selinux/hooks.c| 72 
> +++--
>  security/selinux/include/security.h |  1 +
>  security/selinux/ss/services.c  |  1 +
>  security/selinux/xfrm.c |  4 +++
>  9 files changed, 96 insertions(+), 13 deletions(-)
>



Re: [RFC PATCH 0/2] selinux: avoid nf hooks overhead when not needed

2016-04-06 Thread Casey Schaufler
On 4/6/2016 2:51 AM, Paolo Abeni wrote:
> Currently, selinux always registers iptables POSTROUTING hooks regarless of
> the running policy needs for any action to be performed by them.
>
> Even the socket_sock_rcv_skb() is always registered, but it can result in a 
> no-op
> depending on the current policy configuration.
>
> The above invocations in the kernel datapath are cause of measurable
> overhead in networking performance test.
>
> This patch series adds explicit notification for netlabel status change 
> (other relevant status change, like xfrm and secmark, are already notified to
> LSM) and use this information in selinux to register the above hooks only when
> the current status makes them relevant, deregistering them when no-op
>
> Avoiding the LSM hooks overhead, in netperf UDP_STREAM test with small 
> packets,
> gives about 5% performance improvement on rx and about 8% on tx.
>
> Paolo Abeni (2):
>   security: add hook for netlabel status change notification
>   selinux: implement support for dynamic net hook [de-]registration
>
>  include/linux/lsm_hooks.h   |  6 
>  include/linux/security.h|  5 +++
>  net/netlabel/netlabel_cipso_v4.c|  8 +++--
>  net/netlabel/netlabel_unlabeled.c   |  5 ++-
>  security/security.c |  7 
>  security/selinux/hooks.c| 72 
> +++--
>  security/selinux/include/security.h |  1 +
>  security/selinux/ss/services.c  |  1 +
>  security/selinux/xfrm.c |  4 +++
>  9 files changed, 96 insertions(+), 13 deletions(-)
>
Is there a patch 1/2?



Re: [RFC PATCH 2/2] selinux: implement support for dynamic net hook [de-]registration

2016-04-06 Thread Casey Schaufler
On 4/6/2016 2:51 AM, Paolo Abeni wrote:
> This patch leverage the netlbl_changed() hook to perform on demand
> registration and deregistration of the netfilter hooks and the
> socket_sock_rcv_skb hook.
>
> With default policy and empty netfilter/netlabel configuration, the
> above hooks are not registered and this allows avoiding nf_hook_slow
> in the xmit path and socket_sock_rcv_skb() in the rx path.

There is no reason to assume that there is a relationship between
a netlabel configuration and a netfilter configuration. Smack always
has a netlabel configuration. Security modules (e.g. AppArmor) may
well use netfilter without netlabel.

Please stop assuming that security == SELinux. 

>
> This gives measurable network performance improvement in both
> directions.

In the case where SELinux is enabled and netfilter is not.

> Signed-off-by: Paolo Abeni 
> ---
>  security/selinux/hooks.c| 72 
> +++--
>  security/selinux/include/security.h |  1 +
>  security/selinux/ss/services.c  |  1 +
>  security/selinux/xfrm.c |  4 +++
>  4 files changed, 68 insertions(+), 10 deletions(-)
>
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 912deee..a3baa69 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -4745,11 +4745,13 @@ static int selinux_secmark_relabel_packet(u32 sid)
>  static void selinux_secmark_refcount_inc(void)
>  {
>   atomic_inc(&selinux_secmark_refcount);
> + selinux_net_update();
>  }
>  
>  static void selinux_secmark_refcount_dec(void)
>  {
>   atomic_dec(&selinux_secmark_refcount);
> + selinux_net_update();
>  }
>  
>  static void selinux_req_classify_flow(const struct request_sock *req,
> @@ -4836,6 +4838,11 @@ static int selinux_tun_dev_open(void *security)
>   return 0;
>  }
>  
> +static void selinux_netlbl_changed(void)
> +{
> + selinux_net_update();
> +}
> +
>  static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
>  {
>   int err = 0;
> @@ -6091,7 +6098,6 @@ static struct security_hook_list selinux_hooks[] = {
>   LSM_HOOK_INIT(socket_getsockopt, selinux_socket_getsockopt),
>   LSM_HOOK_INIT(socket_setsockopt, selinux_socket_setsockopt),
>   LSM_HOOK_INIT(socket_shutdown, selinux_socket_shutdown),
> - LSM_HOOK_INIT(socket_sock_rcv_skb, selinux_socket_sock_rcv_skb),
>   LSM_HOOK_INIT(socket_getpeersec_stream,
>   selinux_socket_getpeersec_stream),
>   LSM_HOOK_INIT(socket_getpeersec_dgram, selinux_socket_getpeersec_dgram),
> @@ -6113,6 +6119,7 @@ static struct security_hook_list selinux_hooks[] = {
>   LSM_HOOK_INIT(tun_dev_attach_queue, selinux_tun_dev_attach_queue),
>   LSM_HOOK_INIT(tun_dev_attach, selinux_tun_dev_attach),
>   LSM_HOOK_INIT(tun_dev_open, selinux_tun_dev_open),
> + LSM_HOOK_INIT(netlbl_changed, selinux_netlbl_changed),
>  
>  #ifdef CONFIG_SECURITY_NETWORK_XFRM
>   LSM_HOOK_INIT(xfrm_policy_alloc_security, selinux_xfrm_policy_alloc),
> @@ -6145,6 +6152,11 @@ static struct security_hook_list selinux_hooks[] = {
>  #endif
>  };
>  
> +/* dynamically registered/unregisterd */
> +static struct security_hook_list selinux_sock_hooks[] = {
> + LSM_HOOK_INIT(socket_sock_rcv_skb, selinux_socket_sock_rcv_skb),
> +};
> +
>  static __init int selinux_init(void)
>  {
>   if (!security_module_enable("selinux")) {
> @@ -6240,7 +6252,9 @@ static struct nf_hook_ops selinux_nf_ops[] = {
>  #endif   /* IPV6 */
>  };
>  
> -static int __init selinux_nf_ip_init(void)
> +static bool nf_hooks_registered;
> +
> +static int selinux_nf_ip_init(void)
>  {
>   int err;
>  
> @@ -6253,25 +6267,21 @@ static int __init selinux_nf_ip_init(void)
>   if (err)
>   panic("SELinux: nf_register_hooks: error %d\n", err);
>  
> + nf_hooks_registered = true;
>   return 0;
>  }
>  
> -__initcall(selinux_nf_ip_init);
> -
> -#ifdef CONFIG_SECURITY_SELINUX_DISABLE
>  static void selinux_nf_ip_exit(void)
>  {
>   printk(KERN_DEBUG "SELinux:  Unregistering netfilter hooks\n");
>  
>   nf_unregister_hooks(selinux_nf_ops, ARRAY_SIZE(selinux_nf_ops));
> + nf_hooks_registered = false;
>  }
> -#endif
>  
>  #else /* CONFIG_NETFILTER */
>  
> -#ifdef CONFIG_SECURITY_SELINUX_DISABLE
>  #define selinux_nf_ip_exit()
> -#endif
>  
>  #endif /* CONFIG_NETFILTER */
>  
> @@ -6300,8 +6310,8 @@ int selinux_disable(void)
>   /* Try to destroy the avc node cache */
>   avc_disable();
>  
> - /* Unregister netfilter hooks. */
> - selinux_nf_ip_exit();
> + /* Unregister net hooks. */
> + selinux_net_update();
>  
>   /* Unregister selinuxfs. */
>   exit_sel_fs();
> @@ -6309,3 +6319,45 @@ int selinux_disable(void)
>   return 0;
>  }
>  #endif
> +
> +DEFINE_MUTEX(selinux_net_mutex);
> +
> +static bool nf_hooks_required(void)
> +{
> + return (selinux_secmark_enabled() || selinux_peerlbl_enabled() ||
> + !selinux_policycap_ne

Re: [RFC PATCH 0/2] selinux: avoid nf hooks overhead when not needed

2016-04-12 Thread Casey Schaufler
On 4/12/2016 1:52 AM, Paolo Abeni wrote:
> On Thu, 2016-04-07 at 14:55 -0400, Paul Moore wrote:
>> On Thursday, April 07, 2016 01:45:32 AM Florian Westphal wrote:
>>> Paul Moore  wrote:
 On Wed, Apr 6, 2016 at 6:14 PM, Florian Westphal  wrote:
> netfilter hooks are per namespace -- so there is hook unregister when
> netns is destroyed.
 Looking around, I see the global and per-namespace registration
 functions (nf_register_hook and nf_register_net_hook, respectively),
 but I'm looking to see if/how newly created namespace inherit
 netfilter hooks from the init network namespace ... if you can create
 a network namespace and dodge the SELinux hooks, that isn't a good
 thing from a SELinux point of view, although it might be a plus
 depending on where you view Paolo's original patches ;)
>>> Heh :-)
>>>
>>> If you use nf_register_net_hook, the hook is only registered in the
>>> namespace.
>>>
>>> If you use nf_register_hook, the hook is put on a global list and
>>> registed in all existing namespaces.
>>>
>>> New namespaces will have the hook added as well (see
>>> netfilter_net_init -> nf_register_hook_list in netfilter/core.c )
>>>
>>> Since nf_register_hook is used it should be impossible to get a netns
>>> that doesn't call these hooks.
>> Great, thanks.
>>  
> Do you think it makes sense to rework the patch to delay registering
> of the netfiler hooks until the system is in a state where they're
> needed, without the 'unregister' aspect?
 I would need to see the patch to say for certain, but in principle
 that seems perfectly reasonable and I think would satisfy both the
 netdev and SELinux camps - good suggestion.  My main goal is to drop
 the selinux_nf_ip_init() entirely so it can't be used as a ROP gadget.

 We might even be able to trim the secmark_active and peerlbl_active
 checks in the SELinux netfilter hooks (an earlier attempt at
 optimization; contrary to popular belief, I do care about SELinux
 performance), although that would mean that enabling the network
 access controls would be one way ... I guess you can disregard that
 last bit, I'm thinking aloud again.
>>> One way is fine I think.
>> Yes, just disregard my second paragraph above.
>>  
> Ideally this would even be per netns -- in perfect world we would
> be able to make it so that a new netns are created with an empty
> hook list.
 In general SELinux doesn't care about namespaces, for reasons that are
 sorta beyond the scope of this conversation, so I would like to stick
 to a all or nothing approach to enabling the SELinux netfilter hooks
 across namespaces.  Perhaps we can revisit this at a later time, but
 let's keep it simple right now.
>>> Okay, I'd prefer to stick to your recommendation anyway wrt. to selinux
>>> (Casey, I read your comment regarding smack. Noted, we don't want to
>>> break smack either...)
>>>
>>> I think that in this case the entire question is:
>>>
>>> In your experience, how likely is a config where selinux is enabled BUT the
>>> hooks are not needed (i.e., where we hit the
>>>
>>> if (!selinux_policycap_netpeer)
>>> return NF_ACCEPT;
>>>
>>> if (!secmark_active && !peerlbl_active)
>>>return NF_ACCEPT;
>>>
>>> tests inside the hooks)?  If such setups are uncommon we should just
>>> drop this idea or at least put it on the back burner until the more
>>> expensive netfilter hooks (conntrack, cough) are out of the way.
>> A few years ago I would have said that it is relatively uncommon for admins 
>> to 
>> enable the SELinux network access controls; it was typically just 
>> government/intelligence agencies who had very strict access control 
>> requirements and represented a small portion of SELinux users.  However, 
>> over 
>> the past few years I've been fielding more and more questions from 
>> admins/devs 
>> in the virtualization space who are interested in some of these 
>> capabilities; 
>> it isn't clear to me how many of these people are switching it on, but there 
>> is definitely more interest than I have seen in the past and the interested 
>> is 
>> centered around some rather common use cases.
>>
>> So, to summarize, I don't know ;)
>>
>> If you've got bigger sources of overhead, my opinion would be to go tackle 
>> those first.  Perhaps I can even find the time to work on the 
>> SELinux/netfilter stuff while you are off slaying the bigger dragons, no 
>> promises at the moment.
> Double checking if I got the above correctly.
>
> Will be ok if we post a v2 version of this series, removing the hooks
> de-registration bits, but preserving the selinux nf-hooks and
> socket_sock_rcv_skb() on-demand/delayed registration ?

Imagine that I have two security modules that control sockets.
The work I'm knee deep in will allow this. If adding hooks after
the init phase is allowed you have to face the possibility that
blob sizes (in this case sock->sk_security) may chan

Re: [RFC PATCH 0/2] selinux: avoid nf hooks overhead when not needed

2016-04-13 Thread Casey Schaufler
On 4/13/2016 4:57 AM, Paolo Abeni wrote:
> On Tue, 2016-04-12 at 06:57 -0700, Casey Schaufler wrote:
>> On 4/12/2016 1:52 AM, Paolo Abeni wrote:
>>> On Thu, 2016-04-07 at 14:55 -0400, Paul Moore wrote:
>>>> On Thursday, April 07, 2016 01:45:32 AM Florian Westphal wrote:
>>>>> Paul Moore  wrote:
>>>>>> On Wed, Apr 6, 2016 at 6:14 PM, Florian Westphal  wrote:
>>>>>>> netfilter hooks are per namespace -- so there is hook unregister when
>>>>>>> netns is destroyed.
>>>>>> Looking around, I see the global and per-namespace registration
>>>>>> functions (nf_register_hook and nf_register_net_hook, respectively),
>>>>>> but I'm looking to see if/how newly created namespace inherit
>>>>>> netfilter hooks from the init network namespace ... if you can create
>>>>>> a network namespace and dodge the SELinux hooks, that isn't a good
>>>>>> thing from a SELinux point of view, although it might be a plus
>>>>>> depending on where you view Paolo's original patches ;)
>>>>> Heh :-)
>>>>>
>>>>> If you use nf_register_net_hook, the hook is only registered in the
>>>>> namespace.
>>>>>
>>>>> If you use nf_register_hook, the hook is put on a global list and
>>>>> registed in all existing namespaces.
>>>>>
>>>>> New namespaces will have the hook added as well (see
>>>>> netfilter_net_init -> nf_register_hook_list in netfilter/core.c )
>>>>>
>>>>> Since nf_register_hook is used it should be impossible to get a netns
>>>>> that doesn't call these hooks.
>>>> Great, thanks.
>>>>  
>>>>>>> Do you think it makes sense to rework the patch to delay registering
>>>>>>> of the netfiler hooks until the system is in a state where they're
>>>>>>> needed, without the 'unregister' aspect?
>>>>>> I would need to see the patch to say for certain, but in principle
>>>>>> that seems perfectly reasonable and I think would satisfy both the
>>>>>> netdev and SELinux camps - good suggestion.  My main goal is to drop
>>>>>> the selinux_nf_ip_init() entirely so it can't be used as a ROP gadget.
>>>>>>
>>>>>> We might even be able to trim the secmark_active and peerlbl_active
>>>>>> checks in the SELinux netfilter hooks (an earlier attempt at
>>>>>> optimization; contrary to popular belief, I do care about SELinux
>>>>>> performance), although that would mean that enabling the network
>>>>>> access controls would be one way ... I guess you can disregard that
>>>>>> last bit, I'm thinking aloud again.
>>>>> One way is fine I think.
>>>> Yes, just disregard my second paragraph above.
>>>>  
>>>>>>> Ideally this would even be per netns -- in perfect world we would
>>>>>>> be able to make it so that a new netns are created with an empty
>>>>>>> hook list.
>>>>>> In general SELinux doesn't care about namespaces, for reasons that are
>>>>>> sorta beyond the scope of this conversation, so I would like to stick
>>>>>> to a all or nothing approach to enabling the SELinux netfilter hooks
>>>>>> across namespaces.  Perhaps we can revisit this at a later time, but
>>>>>> let's keep it simple right now.
>>>>> Okay, I'd prefer to stick to your recommendation anyway wrt. to selinux
>>>>> (Casey, I read your comment regarding smack. Noted, we don't want to
>>>>> break smack either...)
>>>>>
>>>>> I think that in this case the entire question is:
>>>>>
>>>>> In your experience, how likely is a config where selinux is enabled BUT 
>>>>> the
>>>>> hooks are not needed (i.e., where we hit the
>>>>>
>>>>> if (!selinux_policycap_netpeer)
>>>>> return NF_ACCEPT;
>>>>>
>>>>> if (!secmark_active && !peerlbl_active)
>>>>>return NF_ACCEPT;
>>>>>
>>>>> tests inside the hooks)?  If such setups are uncommon we should just
>>>>> drop this idea or at least put it on the back burner until the more
>>>>> expensive netfilter hooks (co

Re: [RFC PATCH 0/2] selinux: avoid nf hooks overhead when not needed

2016-04-15 Thread Casey Schaufler
On 4/15/2016 2:38 AM, Paolo Abeni wrote:
> On Thu, 2016-04-14 at 18:53 -0400, Paul Moore wrote:
>> On Tue, Apr 12, 2016 at 4:52 AM, Paolo Abeni  wrote:
>>> Will be ok if we post a v2 version of this series, removing the hooks
>>> de-registration bits, but preserving the selinux nf-hooks and
>>> socket_sock_rcv_skb() on-demand/delayed registration ? Will that fit
>>> with the post-init read only memory usage that you are planning ?
>> The work Florian and and I were talking about would be limited just to
>> the netfilter hooks, the LSM hooks, e.g. socket_sock_rcv_skb() and
>> friends, would remain as they are today.  What what we discussing was
>> defaulting to not registering the netfilter hooks until it became
>> necessary due to a labeled networking configuration or the
>> always_check_network policy capability; the registration of the
>> netfilter hooks would be permanent, you could not unregister the hooks
>> at that point, you would need to reboot.  Does that make sense?
> Yes, AFAIC it makes sense. I'll try to follow this route for an eventual
> v2.
>
>> As far as Casey's concerns, I don't think the work we are talking
>> about for the v2 patchset would have any effect on the socket/sock
>> security blobs as you really can't manage those adequately from the
>> netfilter hooks; you most likely will reference them and perhaps even
>> update the data within, but not allocate or free the blobs.  Besides,
>> even in some weird case you were alloc/free'ing security blobs in the
>> netfilter hooks, we can deal with that on a per-LSM basis if/when the
>> full fledged stacking patches are merged; everything we are talking
>> about is a hidden implementation detail so changing it in the future
>> shouldn't be a problem.
> Casey, are you ok with the above?

Yes. My concern is with the security module hooks. Altering
the netfilter hooks is a separate issue, and I don't have
trouble with that.

I also would not expect to see an LSM doing blob allocation
during socket delivery, but hey, it *is* networking code,
and stranger things happen all the time.

> Thank you,
>
> Paolo
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe 
> linux-security-module" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>



Re: [RFC PATCH 00/17] CALIPSO implementation

2015-12-22 Thread Casey Schaufler
On 12/22/2015 3:46 AM, Huw Davies wrote:
> This patch series implements RFC 5570 - Common Architecture Label IPv6
> Security Option (CALIPSO).  Its goal is to set MLS sensitivity labels
> on IPv6 packets using a hop-by-hop option.  CALIPSO very similar to
> its IPv4 cousin CIPSO and much of this series is based on that code.

There's a one line change to the Smack code in 15/17 due to
a change in the api, but I assume that there has been no
attempt to verify that this works with Smack. It's not 100%
clear that this won't break a Smack kernel, but I haven't
tried it.

You'll need to provide sufficient information (or code!) so
that security modules other than SELinux can use this. If
you look at how Smack uses netlabel for IPv4 you will see
that it differs substantially from the way SELinux uses it.

Thank you for tackling RFC 5570. The lack of something like
this has put IPv6 at a real disadvantage.

>
> Most of this series involves adding support to NetLabel and adding a
> CALIPSO module within IPv6, and as such is fairly self-contained.
> There are however a few places where I've needed to add things to the
> core networking stack, so I'd be particularly interested in hearing
> comments about these:
>
> [PATCH 08/17] ipv6: Add ipv6_renew_options_kern() that accepts a kernel mem 
> pointer.
>   Hopefully not too controversial - adds a kernel memory version of
>   ipv6_renew_options()
>
> [PATCH 12/17] ipv6: Allow request socks to contain IPv6 options.
>   We need a way to set the IPv6 options on request sockets, just like
>   we do for IPv4.  This is so that the LSM can ensure the SYN-ACK is
>   correctly labelled.
>
> The series is based off v4.4-rc6.
>
> Thoughts about these and any of the other patches are most welcome.
>
> If anybody actually wants to play with this, then you'll need some patches
> to netlabel-tools that are currently available on the 'calipso' branch at:
> https://github.com/hdmdavies/netlabel_tools.git
>
> Thanks to Paul Moore for his guidance in getting this far.
>
> Huw.
> ___
> Selinux mailing list
> seli...@tycho.nsa.gov
> To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
> To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
>

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [bisected] Re: [bug] networking broke, ssh: connect to port 22: Protocol error

2008-02-06 Thread Casey Schaufler

--- Ingo Molnar <[EMAIL PROTECTED]> wrote:

> 
> * Ingo Molnar <[EMAIL PROTECTED]> wrote:
> 
> > yeah, although various other upstream breakages prevented real long 
> > randconfig series in the past 2-3 days. I'd say it's either in this 
> > pull from your tree:
> 
> ok, i have bisected it down but the result made no sense, so i 
> double-checked it and noticed that the .config mutated during the test.
> 
> the diff below is the diff between the 'good' and 'bad' .config, with 
> this notable detail:
> 
>  @@ -2336,7 +2350,7 @@ CONFIG_SECURITY_NETWORK=y
>   CONFIG_SECURITY_CAPABILITIES=y
>   # CONFIG_SECURITY_FILE_CAPABILITIES is not set
>   # CONFIG_SECURITY_ROOTPLUG is not set
>  -# CONFIG_SECURITY_SMACK is not set
>  +CONFIG_SECURITY_SMACK=y
>   CONFIG_XOR_BLOCKS=m
>   CONFIG_ASYNC_CORE=m
>   CONFIG_ASYNC_MEMCPY=m
> 
> so i disabled CONFIG_SECURITY_SMACK, and viola, just 2 hours of hard 
> work later networking works on my testbox again :-/
> 
> And we have this 1 day old commit:
> 
>   commit e114e473771c848c3cfec05f0123e70f1cdbdc99
>   Author: Casey Schaufler <[EMAIL PROTECTED]>
>   Date:   Mon Feb 4 22:29:50 2008 -0800
> 
>   Smack: Simplified Mandatory Access Control Kernel
> 
> that adds SMACK.
> 
> So unlike some other security modules like SELINUX, enabling SMACK 
> breaks un-aware userspace and breaks TCP networking?
> 
> I dont think that's expected behavior - and i'd definitely like to 
> enable SMACK in automated tests to check for regressions, etc.

As Stephen mentions later, Smack uses CIPSO. sshd does not like
any IP options because of traceroute, and must be built with that
check disabled with the current Smack version. I have been looking
at using unlabeled packets for the "ambient" label, it appears that
doing so would make life simpler. I will get right on it.

Application behavior in the presence of IP options isn't
always what I think it ought to be.


Casey Schaufler
[EMAIL PROTECTED]
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] (02/06/08 Linus git) Smack unlabeled outgoing ambient packets

2008-02-07 Thread Casey Schaufler

From: Casey Schaufler <[EMAIL PROTECTED]>

Smack uses CIPSO labeling, but allows for unlabeled packets
by specifying an "ambient" label that is applied to incoming
unlabeled packets. Because the other end of the connection
may dislike IP options, and ssh is one know application that
behaves thus, it is prudent to respond in kind. This patch
changes the network labeling behavior such that an outgoing
packet that would be given a CIPSO label that matches the
ambient label is left unlabeled.

Signed-off-by: Casey Schaufler <[EMAIL PROTECTED]>

---

security/smack/smack_lsm.c |9 +
1 file changed, 9 insertions(+)

diff -uprN -X linux-2.6.25-g0206-base//Documentation/dontdiff 
linux-2.6.25-g0206-base/security/smack/smack_lsm.c 
linux-2.6.25-g0206/security/smack/smack_lsm.c
--- linux-2.6.25-g0206-base/security/smack/smack_lsm.c  2008-02-06 
16:01:43.0 -0800
+++ linux-2.6.25-g0206/security/smack/smack_lsm.c   2008-02-06 
18:39:55.0 -0800
@@ -1276,6 +1276,12 @@ static void smack_to_secattr(char *smack
 * Convert the outbound smack value (smk_out) to a
 * secattr and attach it to the socket.
 *
+ * If the label is the ambient label do not set the secattr.
+ * Thus, all ambient packets are unlabeled and all unlabeled
+ * packets are ambient. This permits unlabeled responces to
+ * unlabeled requests without knowing on a per-packet basis
+ * if the packet was labeled ambient or was unlabeled.
+ *
 * Returns 0 on success or an error code
 */
static int smack_netlabel(struct sock *sk)
@@ -1284,6 +1290,9 @@ static int smack_netlabel(struct sock *s
struct netlbl_lsm_secattr secattr;
int rc = 0;

+   if (strncmp(ssp->smk_out, smack_net_ambient, SMK_MAXLEN) == 0)
+   return 0;
+
netlbl_secattr_init(&secattr);
smack_to_secattr(ssp->smk_out, &secattr);
if (secattr.flags != NETLBL_SECATTR_NONE)

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [RFC] Smack: unlabeled outgoing ambient packets - v2

2008-02-11 Thread Casey Schaufler

From: Casey Schaufler <[EMAIL PROTECTED]>

Smack uses CIPSO labeling, but allows for unlabeled packets
by specifying an "ambient" label that is applied to incoming
unlabeled packets. Because the other end of the connection
may dislike IP options, and ssh is one know application that
behaves thus, it is prudent to respond in kind. This patch
changes the network labeling behavior such that an outgoing
packet that would be given a CIPSO label that matches the
ambient label is left unlabeled. An "unlbl" domain is added
and the netlabel defaulting mechanism invoked rather than
assuming that everything is CIPSO. Locking has been added
around changes to the ambient label as the mechanisms used
to do so are more involved.

Signed-off-by: Casey Schaufler <[EMAIL PROTECTED]>

---

This patch differs significantly from the previous version.
I think that I am using the netlbl interfaces more appropriately,
Paul, please let me know if there's a better approach.

It's inconvenient that netlbl_sock_setattr frees the domain passed.
I see that it makes sense for SELinux with the way SELinux treats
secctx's, but Smack is more careful about memory usage and I have
to do what I consider a gratuitous kalloc because of this behavior.
Would you be open to a patch to change this if it included the SELinux
changes?

Thank you.

security/smack/smack_lsm.c |   20 ++--
security/smack/smackfs.c   |   54 +--
2 files changed, 49 insertions(+), 25 deletions(-)

diff -uprN -X linux-2.6.25-g0210-base//Documentation/dontdiff 
linux-2.6.25-g0210-base/security/smack/smackfs.c 
linux-2.6.25-g0210/security/smack/smackfs.c
--- linux-2.6.25-g0210-base/security/smack/smackfs.c2008-02-10 
19:30:47.0 -0800
+++ linux-2.6.25-g0210/security/smack/smackfs.c 2008-02-11 07:14:54.0 
-0800
@@ -45,6 +45,7 @@ enum smk_inos {
 */
static DEFINE_MUTEX(smack_list_lock);
static DEFINE_MUTEX(smack_cipso_lock);
+static DEFINE_MUTEX(smack_ambient_lock);

/*
 * This is the "ambient" label for network traffic.
@@ -363,6 +364,27 @@ void smk_cipso_doi(void)
   __func__, __LINE__, rc);
}

+/**
+ * smk_unlbl_ambient - initialize the unlabeled domain
+ */
+void smk_unlbl_ambient(char *oldambient)
+{
+   int rc;
+   struct netlbl_audit audit_info;
+
+   if (oldambient != NULL) {
+   rc = netlbl_cfg_map_del(oldambient, &audit_info);
+   if (rc != 0)
+   printk(KERN_WARNING "%s:%d remove rc = %d\n",
+  __func__, __LINE__, rc);
+   }
+
+   rc = netlbl_cfg_unlbl_add_map(smack_net_ambient, &audit_info);
+   if (rc != 0)
+   printk(KERN_WARNING "%s:%d add rc = %d\n",
+  __func__, __LINE__, rc);
+}
+
/*
 * Seq_file read operations for /smack/cipso
 */
@@ -709,7 +731,6 @@ static ssize_t smk_read_ambient(struct f
size_t cn, loff_t *ppos)
{
ssize_t rc;
-   char out[SMK_LABELLEN];
int asize;

if (*ppos != 0)
@@ -717,23 +738,18 @@ static ssize_t smk_read_ambient(struct f
/*
 * Being careful to avoid a problem in the case where
 * smack_net_ambient gets changed in midstream.
-* Since smack_net_ambient is always set with a value
-* from the label list, including initially, and those
-* never get freed, the worst case is that the pointer
-* gets changed just after this strncpy, in which case
-* the value passed up is incorrect. Locking around
-* smack_net_ambient wouldn't be any better than this
-* copy scheme as by the time the caller got to look
-* at the ambient value it would have cleared the lock
-* and been changed.
 */
-   strncpy(out, smack_net_ambient, SMK_LABELLEN);
-   asize = strlen(out) + 1;
+   mutex_lock(&smack_ambient_lock);

-   if (cn < asize)
-   return -EINVAL;
+   asize = strlen(smack_net_ambient) + 1;

-   rc = simple_read_from_buffer(buf, cn, ppos, out, asize);
+   if (cn >= asize)
+   rc = simple_read_from_buffer(buf, cn, ppos,
+smack_net_ambient, asize);
+   else
+   rc = -EINVAL;
+
+   mutex_unlock(&smack_ambient_lock);

return rc;
}
@@ -751,6 +767,7 @@ static ssize_t smk_write_ambient(struct 
 size_t count, loff_t *ppos)

{
char in[SMK_LABELLEN];
+   char *oldambient;
char *smack;

if (!capable(CAP_MAC_ADMIN))
@@ -766,7 +783,13 @@ static ssize_t smk_write_ambient(struct 
	if (smack == NULL)

return -EINVAL;

+   mutex_lock(&smack_ambient_lock);
+
+   oldambient = smack_net_ambient;
smack_net_ambient = smack;
+   smk_unlbl_ambient(oldambient);
+
+   mutex_unlock(&smack_ambient_lock);

  

[PATCH] [RFC] Smack: unlabeled outgoing ambient packets - v2

2008-02-11 Thread Casey Schaufler

From: Casey Schaufler <[EMAIL PROTECTED]>

Smack uses CIPSO labeling, but allows for unlabeled packets
by specifying an "ambient" label that is applied to incoming
unlabeled packets. Because the other end of the connection
may dislike IP options, and ssh is one know application that
behaves thus, it is prudent to respond in kind. This patch
changes the network labeling behavior such that an outgoing
packet that would be given a CIPSO label that matches the
ambient label is left unlabeled. An "unlbl" domain is added
and the netlabel defaulting mechanism invoked rather than
assuming that everything is CIPSO. Locking has been added
around changes to the ambient label as the mechanisms used
to do so are more involved.

Signed-off-by: Casey Schaufler <[EMAIL PROTECTED]>

---

This patch differs significantly from the previous version.
I think that I am using the netlbl interfaces more appropriately,
Paul, please let me know if there's a better approach.

It's inconvenient that netlbl_sock_setattr frees the domain passed.
I see that it makes sense for SELinux with the way SELinux treats
secctx's, but Smack is more careful about memory usage and I have
to do what I consider a gratuitous kalloc because of this behavior.
Would you be open to a patch to change this if it included the SELinux
changes?

Thank you.

security/smack/smack_lsm.c |   20 ++--
security/smack/smackfs.c   |   54 +--
2 files changed, 49 insertions(+), 25 deletions(-)

diff -uprN -X linux-2.6.25-g0210-base//Documentation/dontdiff 
linux-2.6.25-g0210-base/security/smack/smackfs.c 
linux-2.6.25-g0210/security/smack/smackfs.c
--- linux-2.6.25-g0210-base/security/smack/smackfs.c2008-02-10 
19:30:47.0 -0800
+++ linux-2.6.25-g0210/security/smack/smackfs.c 2008-02-11 07:14:54.0 
-0800
@@ -45,6 +45,7 @@ enum smk_inos {
 */
static DEFINE_MUTEX(smack_list_lock);
static DEFINE_MUTEX(smack_cipso_lock);
+static DEFINE_MUTEX(smack_ambient_lock);

/*
 * This is the "ambient" label for network traffic.
@@ -363,6 +364,27 @@ void smk_cipso_doi(void)
   __func__, __LINE__, rc);
}

+/**
+ * smk_unlbl_ambient - initialize the unlabeled domain
+ */
+void smk_unlbl_ambient(char *oldambient)
+{
+   int rc;
+   struct netlbl_audit audit_info;
+
+   if (oldambient != NULL) {
+   rc = netlbl_cfg_map_del(oldambient, &audit_info);
+   if (rc != 0)
+   printk(KERN_WARNING "%s:%d remove rc = %d\n",
+  __func__, __LINE__, rc);
+   }
+
+   rc = netlbl_cfg_unlbl_add_map(smack_net_ambient, &audit_info);
+   if (rc != 0)
+   printk(KERN_WARNING "%s:%d add rc = %d\n",
+  __func__, __LINE__, rc);
+}
+
/*
 * Seq_file read operations for /smack/cipso
 */
@@ -709,7 +731,6 @@ static ssize_t smk_read_ambient(struct f
size_t cn, loff_t *ppos)
{
ssize_t rc;
-   char out[SMK_LABELLEN];
int asize;

if (*ppos != 0)
@@ -717,23 +738,18 @@ static ssize_t smk_read_ambient(struct f
/*
 * Being careful to avoid a problem in the case where
 * smack_net_ambient gets changed in midstream.
-* Since smack_net_ambient is always set with a value
-* from the label list, including initially, and those
-* never get freed, the worst case is that the pointer
-* gets changed just after this strncpy, in which case
-* the value passed up is incorrect. Locking around
-* smack_net_ambient wouldn't be any better than this
-* copy scheme as by the time the caller got to look
-* at the ambient value it would have cleared the lock
-* and been changed.
 */
-   strncpy(out, smack_net_ambient, SMK_LABELLEN);
-   asize = strlen(out) + 1;
+   mutex_lock(&smack_ambient_lock);

-   if (cn < asize)
-   return -EINVAL;
+   asize = strlen(smack_net_ambient) + 1;

-   rc = simple_read_from_buffer(buf, cn, ppos, out, asize);
+   if (cn >= asize)
+   rc = simple_read_from_buffer(buf, cn, ppos,
+smack_net_ambient, asize);
+   else
+   rc = -EINVAL;
+
+   mutex_unlock(&smack_ambient_lock);

return rc;
}
@@ -751,6 +767,7 @@ static ssize_t smk_write_ambient(struct 
 size_t count, loff_t *ppos)

{
char in[SMK_LABELLEN];
+   char *oldambient;
char *smack;

if (!capable(CAP_MAC_ADMIN))
@@ -766,7 +783,13 @@ static ssize_t smk_write_ambient(struct 
	if (smack == NULL)

return -EINVAL;

+   mutex_lock(&smack_ambient_lock);
+
+   oldambient = smack_net_ambient;
smack_net_ambient = smack;
+   smk_unlbl_ambient(oldambient);
+
+   mutex_unlock(&smack_ambient_lock);

  

[PATCH] (02/14/08 Linus git) Smack unlabeled outgoing ambient packets - v3

2008-02-15 Thread Casey Schaufler

From: Casey Schaufler <[EMAIL PROTECTED]>

Smack uses CIPSO labeling, but allows for unlabeled packets
by specifying an "ambient" label that is applied to incoming
unlabeled packets. Because the other end of the connection
may dislike IP options, and ssh is one know application that
behaves thus, it is prudent to respond in kind. This patch
changes the network labeling behavior such that an outgoing
packet that would be given a CIPSO label that matches the
ambient label is left unlabeled. An "unlbl" domain is added
and the netlabel defaulting mechanism invoked rather than
assuming that everything is CIPSO. Locking has been added
around changes to the ambient label as the mechanisms used
to do so are more involved.

Cleaned up some issues noted in review.
Make smk_cipso_doi() static.
Create a hook for the new security_secctx_to_secid()
using existing underlying code.
Fill in audit data for netlbl domain calls.
Collapse unnecessary multiple assignments.

Signed-off-by: Casey Schaufler <[EMAIL PROTECTED]>

---

security/smack/smack_lsm.c |   43 
security/smack/smackfs.c   |   61 ++-
2 files changed, 81 insertions(+), 23 deletions(-)

diff -uprN -X linux-2.6.25-g0214-base/Documentation/dontdiff 
linux-2.6.25-g0214-base/security/smack/smackfs.c 
linux-2.6.25-g0214/security/smack/smackfs.c
--- linux-2.6.25-g0214-base/security/smack/smackfs.c2008-02-14 
15:37:13.0 -0800
+++ linux-2.6.25-g0214/security/smack/smackfs.c 2008-02-14 15:42:26.0 
-0800
@@ -24,6 +24,7 @@
#include 
#include 
#include 
+#include 
#include "smack.h"

/*
@@ -45,6 +46,7 @@ enum smk_inos {
 */
static DEFINE_MUTEX(smack_list_lock);
static DEFINE_MUTEX(smack_cipso_lock);
+static DEFINE_MUTEX(smack_ambient_lock);

/*
 * This is the "ambient" label for network traffic.
@@ -342,6 +344,9 @@ void smk_cipso_doi(void)
struct cipso_v4_doi *doip;
struct netlbl_audit audit_info;

+   audit_info.loginuid = audit_get_loginuid(current);
+   audit_info.secid = smack_to_secid(current->security);
+
rc = netlbl_cfg_map_del(NULL, &audit_info);
if (rc != 0)
printk(KERN_WARNING "%s:%d remove rc = %d\n",
@@ -363,6 +368,30 @@ void smk_cipso_doi(void)
   __func__, __LINE__, rc);
}

+/**
+ * smk_unlbl_ambient - initialize the unlabeled domain
+ */
+void smk_unlbl_ambient(char *oldambient)
+{
+   int rc;
+   struct netlbl_audit audit_info;
+
+   audit_info.loginuid = audit_get_loginuid(current);
+   audit_info.secid = smack_to_secid(current->security);
+
+   if (oldambient != NULL) {
+   rc = netlbl_cfg_map_del(oldambient, &audit_info);
+   if (rc != 0)
+   printk(KERN_WARNING "%s:%d remove rc = %d\n",
+  __func__, __LINE__, rc);
+   }
+
+   rc = netlbl_cfg_unlbl_add_map(smack_net_ambient, &audit_info);
+   if (rc != 0)
+   printk(KERN_WARNING "%s:%d add rc = %d\n",
+  __func__, __LINE__, rc);
+}
+
/*
 * Seq_file read operations for /smack/cipso
 */
@@ -709,7 +738,6 @@ static ssize_t smk_read_ambient(struct f
size_t cn, loff_t *ppos)
{
ssize_t rc;
-   char out[SMK_LABELLEN];
int asize;

if (*ppos != 0)
@@ -717,23 +745,18 @@ static ssize_t smk_read_ambient(struct f
/*
 * Being careful to avoid a problem in the case where
 * smack_net_ambient gets changed in midstream.
-* Since smack_net_ambient is always set with a value
-* from the label list, including initially, and those
-* never get freed, the worst case is that the pointer
-* gets changed just after this strncpy, in which case
-* the value passed up is incorrect. Locking around
-* smack_net_ambient wouldn't be any better than this
-* copy scheme as by the time the caller got to look
-* at the ambient value it would have cleared the lock
-* and been changed.
 */
-   strncpy(out, smack_net_ambient, SMK_LABELLEN);
-   asize = strlen(out) + 1;
+   mutex_lock(&smack_ambient_lock);

-   if (cn < asize)
-   return -EINVAL;
+   asize = strlen(smack_net_ambient) + 1;
+
+   if (cn >= asize)
+   rc = simple_read_from_buffer(buf, cn, ppos,
+smack_net_ambient, asize);
+   else
+   rc = -EINVAL;

-   rc = simple_read_from_buffer(buf, cn, ppos, out, asize);
+   mutex_unlock(&smack_ambient_lock);

return rc;
}
@@ -751,6 +774,7 @@ static ssize_t smk_write_ambient(struct 
 size_t count, loff_t *ppos)

{
char in[SMK_LABELLEN];
+   char *oldambient;
char *smack;

if (!capable(CAP_MAC_ADMIN))
@@ -766,7 +790,

Re: [PATCH] (02/14/08 Linus git) Smack unlabeled outgoing ambient packets - v3

2008-02-15 Thread Casey Schaufler

--- Paul Moore <[EMAIL PROTECTED]> wrote:

> On Friday 15 February 2008 12:38:49 am Casey Schaufler wrote:
> > From: Casey Schaufler <[EMAIL PROTECTED]>
> >
> > Smack uses CIPSO labeling, but allows for unlabeled packets
> > by specifying an "ambient" label that is applied to incoming
> > unlabeled packets. Because the other end of the connection
> > may dislike IP options, and ssh is one know application that
> > behaves thus, it is prudent to respond in kind. This patch
> > changes the network labeling behavior such that an outgoing
> > packet that would be given a CIPSO label that matches the
> > ambient label is left unlabeled. An "unlbl" domain is added
> > and the netlabel defaulting mechanism invoked rather than
> > assuming that everything is CIPSO. Locking has been added
> > around changes to the ambient label as the mechanisms used
> > to do so are more involved.
> >
> > Cleaned up some issues noted in review.
> > Make smk_cipso_doi() static.
> > Create a hook for the new security_secctx_to_secid()
> > using existing underlying code.
> > Fill in audit data for netlbl domain calls.
> > Collapse unnecessary multiple assignments.
> >
> > Signed-off-by: Casey Schaufler <[EMAIL PROTECTED]>
> 
> Hi Casey,
> 
> Thanks for the update, it's much improved.  I'd ack it except for one 
> last thing which popped up in this revision ... (and don't worry, it's 
> kinda my fault - not yours) ...
> 
> > @@ -1282,15 +1281,21 @@ static int smack_netlabel(struct sock *s
> >  {
> > struct socket_smack *ssp;
> > struct netlbl_lsm_secattr secattr;
> > -   int rc = 0;
> > +   int rc;
> >
> > ssp = sk->sk_security;
> > netlbl_secattr_init(&secattr);
> > smack_to_secattr(ssp->smk_out, &secattr);
> > -   if (secattr.flags != NETLBL_SECATTR_NONE)
> > -   rc = netlbl_sock_setattr(sk, &secattr);
> > -
> > +   rc = netlbl_sock_setattr(sk, &secattr);
> > netlbl_secattr_destroy(&secattr);
> > +
> > +   /*
> > +* A return of -ENOENT from netlbl_sock_setattr
> > +* indicates that the "domain" was not found, but that's
> > +* not an issue because of the defaulting behavior.
> > +*/
> > +   if (rc == -ENOENT)
> > +   rc = 0;
> > return rc;
> >  }
> 
> ... you shouldn't fix-up the return value from netlbl_sock_setattr().  
> It only returns an error when there really is an error, if there are no 
> matching domain mappings and the default catches the "domain" then the 
> function will return 0 (assuming no other failures).
> 
> The fact that you ran into this problem isn't your fault, it's mine, but 
> thankfully for both of us Pavel Emelyanov found this bug and fixed 
> it[1].  It hasn't hit Linus' tree yet but it's in the net-2.6 tree.  If 
> you can't wait for it to hit Linus' tree you can always apply the fix 
> by hand, it's pretty minor.
> 
> Sorry about that.
> 
>
[1]http://git.kernel.org/?p=linux/kernel/git/davem/net-2.6.git;a=commit;h=4c3a0a254e5d706d3fe01bf42261534858d05586

Yerk. I can put that fix into my tree, but my patch without
the "correction" makes sockets behave very badly. I can't have
people using it without Pavel's fix. Any notion on the plans to
get that in?

Thank you.


Casey Schaufler
[EMAIL PROTECTED]
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] (02/14/08 Linus git) Smack unlabeled outgoing ambient packets - v3

2008-02-15 Thread Casey Schaufler

--- Paul Moore <[EMAIL PROTECTED]> wrote:


> > Yerk. I can put that fix into my tree, but my patch without
> > the "correction" makes sockets behave very badly. I can't have
> > people using it without Pavel's fix. Any notion on the plans to
> > get that in?
> 
> FYI, it looks like Linus just tagged -rc2 and it does have the fix you 
> need.

Thank you. Verification in progress.


Casey Schaufler
[EMAIL PROTECTED]
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] (02/15/08 Linus git) Smack unlabeled outgoing ambient packets - v4

2008-02-15 Thread Casey Schaufler

From: Casey Schaufler <[EMAIL PROTECTED]>

Smack uses CIPSO labeling, but allows for unlabeled packets
by specifying an "ambient" label that is applied to incoming
unlabeled packets. Because the other end of the connection
may dislike IP options, and ssh is one know application that
behaves thus, it is prudent to respond in kind. This patch
changes the network labeling behavior such that an outgoing
packet that would be given a CIPSO label that matches the
ambient label is left unlabeled. An "unlbl" domain is added
and the netlabel defaulting mechanism invoked rather than
assuming that everything is CIPSO. Locking has been added
around changes to the ambient label as the mechanisms used
to do so are more involved.

Cleaned up some issues noted in review.
Make smk_cipso_doi() static.
Create a hook for the new security_secctx_to_secid()
using existing underlying code.
Fill in audit data for netlbl domain calls.
Collapse unnecessary multiple assignments.

Signed-off-by: Casey Schaufler <[EMAIL PROTECTED]>

---

security/smack/smack_lsm.c |   36 
security/smack/smackfs.c   |   61 ++-
2 files changed, 74 insertions(+), 23 deletions(-)

diff -uprN -X linux-2.6.25-g0215-base//Documentation/dontdiff 
linux-2.6.25-g0215-base/security/smack/smackfs.c 
linux-2.6.25-g0215/security/smack/smackfs.c
--- linux-2.6.25-g0215-base/security/smack/smackfs.c2008-02-15 
14:25:37.0 -0800
+++ linux-2.6.25-g0215/security/smack/smackfs.c 2008-02-15 14:30:36.0 
-0800
@@ -24,6 +24,7 @@
#include 
#include 
#include 
+#include 
#include "smack.h"

/*
@@ -45,6 +46,7 @@ enum smk_inos {
 */
static DEFINE_MUTEX(smack_list_lock);
static DEFINE_MUTEX(smack_cipso_lock);
+static DEFINE_MUTEX(smack_ambient_lock);

/*
 * This is the "ambient" label for network traffic.
@@ -342,6 +344,9 @@ void smk_cipso_doi(void)
struct cipso_v4_doi *doip;
struct netlbl_audit audit_info;

+   audit_info.loginuid = audit_get_loginuid(current);
+   audit_info.secid = smack_to_secid(current->security);
+
rc = netlbl_cfg_map_del(NULL, &audit_info);
if (rc != 0)
printk(KERN_WARNING "%s:%d remove rc = %d\n",
@@ -363,6 +368,30 @@ void smk_cipso_doi(void)
   __func__, __LINE__, rc);
}

+/**
+ * smk_unlbl_ambient - initialize the unlabeled domain
+ */
+void smk_unlbl_ambient(char *oldambient)
+{
+   int rc;
+   struct netlbl_audit audit_info;
+
+   audit_info.loginuid = audit_get_loginuid(current);
+   audit_info.secid = smack_to_secid(current->security);
+
+   if (oldambient != NULL) {
+   rc = netlbl_cfg_map_del(oldambient, &audit_info);
+   if (rc != 0)
+   printk(KERN_WARNING "%s:%d remove rc = %d\n",
+  __func__, __LINE__, rc);
+   }
+
+   rc = netlbl_cfg_unlbl_add_map(smack_net_ambient, &audit_info);
+   if (rc != 0)
+   printk(KERN_WARNING "%s:%d add rc = %d\n",
+  __func__, __LINE__, rc);
+}
+
/*
 * Seq_file read operations for /smack/cipso
 */
@@ -709,7 +738,6 @@ static ssize_t smk_read_ambient(struct f
size_t cn, loff_t *ppos)
{
ssize_t rc;
-   char out[SMK_LABELLEN];
int asize;

if (*ppos != 0)
@@ -717,23 +745,18 @@ static ssize_t smk_read_ambient(struct f
/*
 * Being careful to avoid a problem in the case where
 * smack_net_ambient gets changed in midstream.
-* Since smack_net_ambient is always set with a value
-* from the label list, including initially, and those
-* never get freed, the worst case is that the pointer
-* gets changed just after this strncpy, in which case
-* the value passed up is incorrect. Locking around
-* smack_net_ambient wouldn't be any better than this
-* copy scheme as by the time the caller got to look
-* at the ambient value it would have cleared the lock
-* and been changed.
 */
-   strncpy(out, smack_net_ambient, SMK_LABELLEN);
-   asize = strlen(out) + 1;
+   mutex_lock(&smack_ambient_lock);

-   if (cn < asize)
-   return -EINVAL;
+   asize = strlen(smack_net_ambient) + 1;
+
+   if (cn >= asize)
+   rc = simple_read_from_buffer(buf, cn, ppos,
+smack_net_ambient, asize);
+   else
+   rc = -EINVAL;

-   rc = simple_read_from_buffer(buf, cn, ppos, out, asize);
+   mutex_unlock(&smack_ambient_lock);

return rc;
}
@@ -751,6 +774,7 @@ static ssize_t smk_write_ambient(struct 
 size_t count, loff_t *ppos)

{
char in[SMK_LABELLEN];
+   char *oldambient;
char *smack;

if (!capable(CAP_MAC_ADMIN))
@@ -766,7 +790,

Re: [PATCH] (02/15/08 Linus git) Smack unlabeled outgoing ambient packets - v4

2008-02-15 Thread Casey Schaufler

--- Paul Moore <[EMAIL PROTECTED]> wrote:

> On Friday 15 February 2008 6:24:25 pm Casey Schaufler wrote:
> > From: Casey Schaufler <[EMAIL PROTECTED]>
> >
> > Smack uses CIPSO labeling, but allows for unlabeled packets
> > by specifying an "ambient" label that is applied to incoming
> > unlabeled packets. Because the other end of the connection
> > may dislike IP options, and ssh is one know application that
> > behaves thus, it is prudent to respond in kind. This patch
> > changes the network labeling behavior such that an outgoing
> > packet that would be given a CIPSO label that matches the
> > ambient label is left unlabeled. An "unlbl" domain is added
> > and the netlabel defaulting mechanism invoked rather than
> > assuming that everything is CIPSO. Locking has been added
> > around changes to the ambient label as the mechanisms used
> > to do so are more involved.
> >
> > Cleaned up some issues noted in review.
> > Make smk_cipso_doi() static.
> > Create a hook for the new security_secctx_to_secid()
> > using existing underlying code.
> > Fill in audit data for netlbl domain calls.
> > Collapse unnecessary multiple assignments.
> >
> > Signed-off-by: Casey Schaufler <[EMAIL PROTECTED]>
> 
> Looks good to me, thanks for making those changes.
> 
> Acked-by: Paul Moore <[EMAIL PROTECTED]>

Thank you for the insights.


Casey Schaufler
[EMAIL PROTECTED]
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH ghak32 V2 01/13] audit: add container id

2018-04-18 Thread Casey Schaufler
On 4/18/2018 4:47 PM, Paul Moore wrote:
> On Fri, Mar 16, 2018 at 5:00 AM, Richard Guy Briggs  wrote:
>> Implement the proc fs write to set the audit container ID of a process,
>> emitting an AUDIT_CONTAINER record to document the event.
>> ...
>>
>> diff --git a/include/linux/sched.h b/include/linux/sched.h
>> index d258826..1b82191 100644
>> --- a/include/linux/sched.h
>> +++ b/include/linux/sched.h
>> @@ -796,6 +796,7 @@ struct task_struct {
>>  #ifdef CONFIG_AUDITSYSCALL
>> kuid_t  loginuid;
>> unsigned intsessionid;
>> +   u64 containerid;
> This one line addition to the task_struct scares me the most of
> anything in this patchset.  Why?  It's a field named "containerid" in
> a perhaps one of the most widely used core kernel structures; the
> possibilities for abuse are endless, and it's foolish to think we
> would ever be able to adequately police this.

If we can get the LSM infrastructure managed task blobs from 
module stacking in ahead of this we could create a trivial security
module to manage this. It's not as if there aren't all sorts of
interactions between security modules and the audit system already.




Re: [RFC PATCH ghak32 V2 01/13] audit: add container id

2018-04-18 Thread Casey Schaufler
On 4/18/2018 5:46 PM, Paul Moore wrote:
> On Wed, Apr 18, 2018 at 8:41 PM, Casey Schaufler  
> wrote:
>> On 4/18/2018 4:47 PM, Paul Moore wrote:
>>> On Fri, Mar 16, 2018 at 5:00 AM, Richard Guy Briggs  wrote:
>>>> Implement the proc fs write to set the audit container ID of a process,
>>>> emitting an AUDIT_CONTAINER record to document the event.
>>>> ...
>>>>
>>>> diff --git a/include/linux/sched.h b/include/linux/sched.h
>>>> index d258826..1b82191 100644
>>>> --- a/include/linux/sched.h
>>>> +++ b/include/linux/sched.h
>>>> @@ -796,6 +796,7 @@ struct task_struct {
>>>>  #ifdef CONFIG_AUDITSYSCALL
>>>> kuid_t  loginuid;
>>>> unsigned intsessionid;
>>>> +   u64 containerid;
>>> This one line addition to the task_struct scares me the most of
>>> anything in this patchset.  Why?  It's a field named "containerid" in
>>> a perhaps one of the most widely used core kernel structures; the
>>> possibilities for abuse are endless, and it's foolish to think we
>>> would ever be able to adequately police this.
>> If we can get the LSM infrastructure managed task blobs from
>> module stacking in ahead of this we could create a trivial security
>> module to manage this. It's not as if there aren't all sorts of
>> interactions between security modules and the audit system already.
> While yes, there are plenty of interactions between the two, it is
> possible to use audit without the LSMs and I would like to preserve
> that.  

Fair enough.

> Further, I don't want to entangle two very complicated code
> changes or make the audit container ID effort dependent on LSM
> stacking.

Also fair, although the use case for container audit IDs is
already pulling in audit, namespaces (yeah, I know it's not
necessary for a container to use namespaces) security modules
(stacked and/or namespaced), cgroups and who knows what else.

> You're a good salesman Casey, but you're not that good ;)

I have to keep the skills sharpened somehow!

OK, I'll grant that this isn't a great fit.



Re: [PATCH 0/3] Introduce LSM-hook for socketpair(2)

2018-04-23 Thread Casey Schaufler
On 4/23/2018 6:30 AM, David Herrmann wrote:
> Hi
>
> This series adds a new LSM hook for the socketpair(2) syscall. The idea
> is to allow SO_PEERSEC to be called on AF_UNIX sockets created via
> socketpair(2), and return the same information as if you emulated
> socketpair(2) via a temporary listener socket. Right now SO_PEERSEC
> will return the unlabeled credentials for a socketpair, rather than the
> actual credentials of the creating process.
>
> ...
>
> This series only adds SELinux backends, since that is what we need for
> RHEL. I will gladly extend the other LSMs if needed.

I would be very happy to see a proposed patch for Smack. It shouldn't
be much different from the SELinux version, with the exception that it
will use pointers to smk_known structures instead of secids. It would be
a big help, as someone just threw a whole new species of scorpion into
this pit.

>
> Thanks
> David
>
> [1] https://github.com/bus1/dbus-broker/blob/master/src/util/test-peersec.c
> [2] https://www.spinics.net/lists/selinux/msg22674.html
>
> David Herrmann (3):
>   security: add hook for socketpair(AF_UNIX, ...)
>   net/unix: hook unix_socketpair() into LSM
>   selinux: provide unix_stream_socketpair callback
>
>  include/linux/lsm_hooks.h |  8 
>  include/linux/security.h  |  7 +++
>  net/unix/af_unix.c|  5 +
>  security/security.c   |  6 ++
>  security/selinux/hooks.c  | 14 ++
>  5 files changed, 40 insertions(+)
>



Re: RFC(v2): Audit Kernel Container IDs

2017-12-09 Thread Casey Schaufler
On 12/9/2017 2:20 AM, Micka�l Sala�n wrote:
> On 12/10/2017 18:33, Casey Schaufler wrote:
>> On 10/12/2017 7:14 AM, Richard Guy Briggs wrote:
>>> Containers are a userspace concept.  The kernel knows nothing of them.
>>>
>>> The Linux audit system needs a way to be able to track the container
>>> provenance of events and actions.  Audit needs the kernel's help to do
>>> this.
>>>
>>> Since the concept of a container is entirely a userspace concept, a
>>> registration from the userspace container orchestration system initiates
>>> this.  This will define a point in time and a set of resources
>>> associated with a particular container with an audit container ID.
>>>
>>> The registration is a pseudo filesystem (proc, since PID tree already
>>> exists) write of a u8[16] UUID representing the container ID to a file
>>> representing a process that will become the first process in a new
>>> container.  This write might place restrictions on mount namespaces
>>> required to define a container, or at least careful checking of
>>> namespaces in the kernel to verify permissions of the orchestrator so it
>>> can't change its own container ID.  A bind mount of nsfs may be
>>> necessary in the container orchestrator's mntNS.
>>> Note: Use a 128-bit scalar rather than a string to make compares faster
>>> and simpler.
>>>
>>> Require a new CAP_CONTAINER_ADMIN to be able to carry out the
>>> registration.
>> Hang on. If containers are a user space concept, how can
>> you want CAP_CONTAINER_ANYTHING? If there's not such thing as
>> a container, how can you be asking for a capability to manage
>> them?
>>
>>>   At that time, record the target container's user-supplied
>>> container identifier along with the target container's first process
>>> (which may become the target container's "init" process) process ID
>>> (referenced from the initial PID namespace), all namespace IDs (in the
>>> form of a nsfs device number and inode number tuple) in a new auxilliary
>>> record AUDIT_CONTAINER with a qualifying op=$action field.
> Here is an idea to avoid privilege problems or the need for a new
> capability: make it automatic. What makes a container a container seems
> to be the use of at least a namespace.

You might think so, but I am assured that you can have a container
without using namespaces. Intel's "Clear Containers", which use
virtualization technology, are one example. I have considered creating
"Smack Containers" using mandatory access control technology, more
to press the point that "containers" is a marketing concept, not
technology.

>  What about automatically create
> and assign an ID to a process when it enters a namespace different than
> one of its parent process? This delegates the (permission)
> responsibility to the use of namespaces (e.g. /proc/sys/user/max_* limit).

That gets ugly when you have a container that uses user, filesystem,
network and whatever else namespaces. If all containers used the same
set of namespaces I think this would be a fine idea, but they don't.

> One interesting side effect of this approach would be to be able to
> identify which processes are in the same set of namespaces, even if not
> spawn from the container but entered after its creation (i.e. using
> setns), by creating container IDs as a (deterministic) checksum from the
> /proc/self/ns/* IDs.
>
> Since the concern is to identify a container, I think the ability to
> audit the switch from one container ID to another is enough. I don't
> think we need nested IDs.

Because a container doesn't have to use namespaces to be a container
you still need a mechanism for a process to declare that it is in fact
in a container, and to identify the container.

>
> As a side note, you may want to take a look at the Linux-VServer's XID.
>
> Regards,
>  Micka�l
>



Re: RFC(v2): Audit Kernel Container IDs

2017-12-11 Thread Casey Schaufler
On 12/11/2017 8:30 AM, Eric Paris wrote:
> On Sat, 2017-12-09 at 10:28 -0800, Casey Schaufler wrote:
>> Because a container doesn't have to use namespaces to be a container
>> you still need a mechanism for a process to declare that it is in
>> fact
>> in a container, and to identify the container.
> I like the idea but I'm still tossing it around in my head (and
> thinking about Casey's statement too). Lets say we have a 'docker-like' 
> container with pid=100  netns=X,userns=Y,mountns=Z. If I'm on the host
> in all init namespaces and I run
>   nsenter -t 100 -n ip link set eth0 promisc on
> How should this be logged? Did this command run in it's own 'container'
> unrelated to the 'docker-like' container?

Jose Bollo's PTAGS ( https://gitlab.com/jobol/ptags ) would be
prefect. Any time you declare something to be a container or
enter a namespace you slap a tag on it. Identifying nested
containers would be easy, you'd have multiple tags.

PTAGS unfortunately needs module stacking, but how hard could that be?


> -Eric



Re: [PATCH bpf-next v8 05/11] seccomp,landlock: Enforce Landlock programs per process hierarchy

2018-02-27 Thread Casey Schaufler
On 2/27/2018 8:39 AM, Andy Lutomirski wrote:
> On Tue, Feb 27, 2018 at 5:32 AM, Alexei Starovoitov
>  wrote:
>> [ Snip ]
> An earlier version of the patch set used the seccomp filter chain.
> Mickaël, what exactly was wrong with that approach other than that the
> seccomp() syscall was awkward for you to use?  You could add a
> seccomp_add_landlock_rule() syscall if you needed to.
>
> As a side comment, why is this an LSM at all, let alone a non-stacking
> LSM?  It would make a lot more sense to me to make Landlock depend on
> having LSMs configured in but to call the landlock hooks directly from
> the security_xyz() hooks.

Please, no. It is my serious intention to have at least the
infrastructure blob management in within a release or two, and
I think that's all Landlock needs. The security_xyz() hooks are
sufficiently hackish as it is without unnecessarily adding more
special cases.




Re: [PATCH bpf-next v8 05/11] seccomp,landlock: Enforce Landlock programs per process hierarchy

2018-02-27 Thread Casey Schaufler
On 2/27/2018 9:36 AM, Andy Lutomirski wrote:
> On Tue, Feb 27, 2018 at 5:30 PM, Casey Schaufler  
> wrote:
>> On 2/27/2018 8:39 AM, Andy Lutomirski wrote:
>>> On Tue, Feb 27, 2018 at 5:32 AM, Alexei Starovoitov
>>>  wrote:
>>>> [ Snip ]
>>> An earlier version of the patch set used the seccomp filter chain.
>>> Mickaël, what exactly was wrong with that approach other than that the
>>> seccomp() syscall was awkward for you to use?  You could add a
>>> seccomp_add_landlock_rule() syscall if you needed to.
>>>
>>> As a side comment, why is this an LSM at all, let alone a non-stacking
>>> LSM?  It would make a lot more sense to me to make Landlock depend on
>>> having LSMs configured in but to call the landlock hooks directly from
>>> the security_xyz() hooks.
>> Please, no. It is my serious intention to have at least the
>> infrastructure blob management in within a release or two, and
>> I think that's all Landlock needs. The security_xyz() hooks are
>> sufficiently hackish as it is without unnecessarily adding more
>> special cases.
>>
>>
> What do you mean by "infrastructure blob management"?

Today each security module manages their own module specific data,
for example inode->i_security and file->f_security. This prevents
having two security modules that have inode or file data from being
used at the same time, because they both need to manage those fields.
Moving the management of the module specific data (aka "blobs") from
the security modules to the module infrastructure will allow those
modules to coexist. Restrictions apply, of course, but I don't think
that Landlock uses any of the facilities that would have issues.



Re: [PATCH v3 1/4] security: Add support for SCTP security hooks

2017-12-22 Thread Casey Schaufler
On 12/22/2017 5:05 AM, Marcelo Ricardo Leitner wrote:
> From: Richard Haines 
>
> The SCTP security hooks are explained in:
> Documentation/security/LSM-sctp.rst
>
> Signed-off-by: Richard Haines 
> Acked-by: Marcelo Ricardo Leitner 
> ---
>  Documentation/security/LSM-sctp.rst | 194 
> 
>  include/linux/lsm_hooks.h   |  35 +++
>  include/linux/security.h|  25 +
>  security/security.c |  22 
>  4 files changed, 276 insertions(+)
>  create mode 100644 Documentation/security/LSM-sctp.rst
>
> diff --git a/Documentation/security/LSM-sctp.rst 
> b/Documentation/security/LSM-sctp.rst
> new file mode 100644
> index 
> ..61373672ce9f63bbd52d953500f44cdf3427c3f0
> --- /dev/null
> +++ b/Documentation/security/LSM-sctp.rst
> @@ -0,0 +1,194 @@
> +SCTP LSM Support
> +
> +
> +For security module support, three sctp specific hooks have been 
> implemented::
> +
> +security_sctp_assoc_request()
> +security_sctp_bind_connect()
> +security_sctp_sk_clone()
> +
> +Also the following security hook has been utilised::
> +
> +security_inet_conn_established()
> +
> +The usage of these hooks are described below with the SELinux implementation
> +described in ``Documentation/security/SELinux-sctp.rst``
> +
> +
> +security_sctp_assoc_request()
> +-
> +This new hook passes the ``@ep`` and ``@chunk->skb`` (the association INIT
> +packet) to the security module. Returns 0 on success, error on failure.
> +::
> +
> +@ep - pointer to sctp endpoint structure.
> +@skb - pointer to skbuff of association packet.
> +
> +The security module performs the following operations:
> + IF this is the first association on ``@ep->base.sk``, then set the peer
> + sid to that in ``@skb``. This will ensure there is only one peer sid
> + assigned to ``@ep->base.sk`` that may support multiple associations.
> +
> + ELSE validate the ``@ep->base.sk peer_sid`` against the ``@skb peer 
> sid``
> + to determine whether the association should be allowed or denied.
> +
> + Set the sctp ``@ep sid`` to socket's sid (from ``ep->base.sk``) with
> + MLS portion taken from ``@skb peer sid``. This will be used by SCTP
> + TCP style sockets and peeled off connections as they cause a new socket
> + to be generated.
> +
> + If IP security options are configured (CIPSO/CALIPSO), then the ip
> + options are set on the socket.

Please! Basing the documentation for the infrastructure behavior
on a specific security module implementation makes it *really rough*
to adopt it to a different module. It makes it doubly difficult to
define how it will work with multiple modules. Take the SELinux specifics
out of the documentation for the hooks. Describe the general intention,
not how SELinux uses it.

> +
> +
> +security_sctp_bind_connect()
> +-
> +This new hook passes one or more ipv4/ipv6 addresses to the security module
> +for validation based on the ``@optname`` that will result in either a bind or
> +connect service as shown in the permission check tables below.
> +Returns 0 on success, error on failure.
> +::
> +
> +@sk  - Pointer to sock structure.
> +@optname - Name of the option to validate.
> +@address - One or more ipv4 / ipv6 addresses.
> +@addrlen - The total length of address(s). This is calculated on each
> +   ipv4 or ipv6 address using sizeof(struct sockaddr_in) or
> +   sizeof(struct sockaddr_in6).
> +
> +  --
> +  | BIND Type Checks   |
> +  |   @optname | @address contains |
> +  ||---|
> +  | SCTP_SOCKOPT_BINDX_ADD | One or more ipv4 / ipv6 addresses |
> +  | SCTP_PRIMARY_ADDR  | Single ipv4 or ipv6 address   |
> +  | SCTP_SET_PEER_PRIMARY_ADDR | Single ipv4 or ipv6 address   |
> +  --
> +
> +  --
> +  |   CONNECT Type Checks  |
> +  |   @optname | @address contains |
> +  ||---|
> +  | SCTP_SOCKOPT_CONNECTX  | One or more ipv4 / ipv6 addresses |
> +  | SCTP_PARAM_ADD_IP  | One or more ipv4 / ipv6 addresses |
> +  | SCTP_SENDMSG_CONNECT   | Single ipv4 or ipv6 address   |
> +  | SCTP_PARAM_SET_PRIMARY | Single ipv4 or ipv6 address   |
> +  --
> +
> +A summary of the ``@optname`` entries is as follows::
> +
> +SCTP_SOCKOPT_BINDX_ADD - Allows additional bind addresses to be
> +   

Re: RFC(V3): Audit Kernel Container IDs

2018-02-03 Thread Casey Schaufler
On 2/2/2018 3:24 PM, Paul Moore wrote:
> On Fri, Feb 2, 2018 at 5:19 PM, Simo Sorce  wrote:
>> On Fri, 2018-02-02 at 16:24 -0500, Paul Moore wrote:
>>> On Wed, Jan 10, 2018 at 2:00 AM, Richard Guy Briggs  wrote:
 On 2018-01-09 11:18, Simo Sorce wrote:
> On Tue, 2018-01-09 at 07:16 -0500, Richard Guy Briggs wrote:
> ..
>
 Paul, can you justify this somewhat larger inconvenience for some
 relatively minor convenience on our part?
>>> Done in direct response to Simo.
>> Sorry but your response sounds more like waving away then addressing
>> them, the excuse being: we can't please everyone, so we are going to
>> please no one.
> I obviously disagree with the take on my comments but you're free to
> your opinion.
>
> I believe saying we are pleasing no one isn't really fair now is it?
> Is there any type of audit container ID now?  How would you go about
> associating audit events with containers now? (spoiler alert: it ain't
> pretty, and there are gaps I don't believe you can cover)  This
> proposal provides a mechanism to do this in a way that isn't tied to
> any one particular concept of a container and is manageable inside the
> kernel.
>
> If you have a need to track audit events for containers, I find it
> extremely hard to believe that you are not at least partially pleased
> by the solutions presented here.  It may not be everything on your
> wishlist, but when did you ever get *everything* on your wishlist?

I am going to back Paul 100% on this point. The container
community's emphatic position that containers are strictly
a user-space construct makes it impossible for the kernel
to provide any data more sophisticated than an integer, and
any processing based on that data cleverer than a check
for equality.


>>> But to be clear Richard, we've talked about this a few times, it's not
>>> a "minor convenience" on our part, it's a pretty big convenience once
>>> we starting having to route audit events and make decisions based on
>>> the audit container ID information.  Audit performance is less than
>>> awesome now, I'm working hard to not make it worse.
>> Sounds like a security vs performance trade off to me.

Without the kernel having a "container" policy to work with there
is no "security" it can possibly enforce.

> Welcome to software development.  It's generally a pretty terrible
> hobby and/or occupation, but we make up for it with long hours and
> endless frustration.
>
 u64 vs u128 is easy for us to
 accomodate in terms of scalar comparisons.  It doubles the information
 in every container id field we print in audit records.
>>> ... and slows down audit container ID checks.
>> Are you saying a cmp on a u128 is slower than a comparison on a u64 and
>> this is something that will be noticeable ?
> Do you have a 128 bit system?  I don't.  I've got a bunch of 64 bit
> systems, and a couple of 32 bit systems too.  People that use audit
> have a tendency to really hammer on it, to the point that we get
> performance complaints on a not infrequent basis.  I don't know the
> exact number of times we are going to need to check the audit
> container ID, but it's reasonable to think that we'll expose it as a
> filter-able field which adds a few checks, we'll use it for record
> routing so that's a few more, and if we're running multiple audit
> daemons we will probably want to include LSM checks which could result
> in a few more audit container ID checks.  If it was one comparison I
> wouldn't be too worried about it, but the point I'm trying to make is
> that we don't know what the implementation is going to look like yet
> and I suspect this ID is going to be leveraged in several places in
> the audit subsystem and I would much rather start small to save
> headaches later.
>
> We can always expand the ID to a larger integer at a later date, but
> we can't make it smaller.
>
 A c36 is a bigger step.
>>> Yeah, we're not doing that, no way.
>> Ok, I can see your point though I do not agree with it.
>>
>> I can see why you do not want to have arbitrary length strings, but a
>> u128 sounded like a reasonable compromise to me as it has enough room
>> to be able to have unique cluster-wide IDs which a u64 definitely makes
>> a lot harder to provide w/o tight coordination.
> I originally wanted it to be a 32-bit integer, but Richard managed to
> talk me into 64-bits, that was my compromise :)
>
> As I said earlier, if you are doing container auditing you're going to
> need coordination with the orchestrator, regardless of the audit
> container ID size.
>



Re: [PATCH v2 4/4] smack: provide socketpair callback

2018-05-04 Thread Casey Schaufler
On 5/4/2018 7:28 AM, David Herrmann wrote:
> From: Tom Gundersen 
>
> Make sure to implement the new socketpair callback so the SO_PEERSEC
> call on socketpair(2)s will return correct information.
>
> Signed-off-by: Tom Gundersen 
> Signed-off-by: David Herrmann 

This doesn't look like it will cause any problems.
I've only been able to test it in a general way. I
haven't created specific tests, but it passes the
usual Smack use cases.

Acked-by: Casey Schaufler 

> ---
>  security/smack/smack_lsm.c | 22 ++
>  1 file changed, 22 insertions(+)
>
> diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
> index 0b414836bebd..dcb976f98df2 100644
> --- a/security/smack/smack_lsm.c
> +++ b/security/smack/smack_lsm.c
> @@ -2842,6 +2842,27 @@ static int smack_socket_post_create(struct socket 
> *sock, int family,
>   return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
>  }
>  
> +/**
> + * smack_socket_socketpair - create socket pair
> + * @socka: one socket
> + * @sockb: another socket
> + *
> + * Cross reference the peer labels for SO_PEERSEC
> + *
> + * Returns 0 on success, and error code otherwise
> + */
> +static int smack_socket_socketpair(struct socket *socka,
> +struct socket *sockb)
> +{
> + struct socket_smack *asp = socka->sk->sk_security;
> + struct socket_smack *bsp = sockb->sk->sk_security;
> +
> + asp->smk_packet = bsp->smk_out;
> + bsp->smk_packet = asp->smk_out;
> +
> + return 0;
> +}
> +
>  #ifdef SMACK_IPV6_PORT_LABELING
>  /**
>   * smack_socket_bind - record port binding information.
> @@ -4724,6 +4745,7 @@ static struct security_hook_list smack_hooks[] 
> __lsm_ro_after_init = {
>   LSM_HOOK_INIT(unix_may_send, smack_unix_may_send),
>  
>   LSM_HOOK_INIT(socket_post_create, smack_socket_post_create),
> + LSM_HOOK_INIT(socket_socketpair, smack_socket_socketpair),
>  #ifdef SMACK_IPV6_PORT_LABELING
>   LSM_HOOK_INIT(socket_bind, smack_socket_bind),
>  #endif



Network hang after c3f1010b30f7fc611139cfb702a8685741aa6827 with CIPSO & Smack

2016-07-05 Thread Casey Schaufler
I have encountered a system hang with my Smack
networking tests that bisects to the change below.
I can't say that I have any idea why the change
would impact the Smack processing, but there appears
to be some serious packet processing going on. The
Smack code is using CIPSO on the loopback interface.
The test is supposed to verify that labels can be
set on the packets using CIPSO. Unlabeled packets
do not appear to be impacted. I do not know if SELinux
is affected, and if not, why not. Smack and SELinux
use CIPSO differently.


c3f1010b30f7fc611139cfb702a8685741aa6827

commit c3f1010b30f7fc611139cfb702a8685741aa6827
Merge: ca4aa97 0b922b7
Author: David S. Miller 
Date:   Wed May 11 19:31:40 2016 -0400

Merge branch 'vrf-pktinfo'

David Ahern says:


net: vrf: Fixup PKTINFO to return enslaved device index

Applications such as OSPF and BFD need the original ingress device not
the VRF device; the latter can be derived from the former. To that end
move the packet intercept from an rx handler that is invoked by
__netif_receive_skb_core to the ipv4 and ipv6 receive processing.

IPv6 already saves the skb_iif to the control buffer in ipv6_rcv. Since
the skb->dev has not been switched the cb has the enslaved device. Make
the same happen for IPv4 by adding the skb_iif to inet_skb_parm and set
it in ipv4 code after clearing the skb control buffer similar to IPv6.
From there the pktinfo can just pull it from cb with the PKTINFO_SKB_CB
cast.


Signed-off-by: David S. Miller 





Re: Network hang after c3f1010b30f7fc611139cfb702a8685741aa6827 with CIPSO & Smack

2016-07-05 Thread Casey Schaufler
On 7/5/2016 5:49 PM, David Ahern wrote:
> On 7/5/16 5:38 PM, Casey Schaufler wrote:
>> I have encountered a system hang with my Smack
>> networking tests that bisects to the change below.
>> I can't say that I have any idea why the change
>> would impact the Smack processing, but there appears
>> to be some serious packet processing going on. The
>> Smack code is using CIPSO on the loopback interface.
>> The test is supposed to verify that labels can be
>> set on the packets using CIPSO. Unlabeled packets
>> do not appear to be impacted. I do not know if SELinux
>> is affected, and if not, why not. Smack and SELinux
>> use CIPSO differently.
>
> What are the commands to repeat the test?
>
There is a tar file attached with the tests.
Put the etc/smack/user file into /etc/smack/user.
In the tools-2012 directory run make to build
the tools. The test in question is called
testnetworking.sh and needs to be run as root.
You will need to configure Smack in the kernel,
of course.



smack-tests.tar
Description: Binary data


Re: Network hang after c3f1010b30f7fc611139cfb702a8685741aa6827 with CIPSO & Smack

2016-07-06 Thread Casey Schaufler
On 7/6/2016 5:50 AM, Paul Moore wrote:
> On Tue, Jul 5, 2016 at 8:38 PM, Casey Schaufler  
> wrote:
>> I have encountered a system hang with my Smack
>> networking tests that bisects to the change below.
>> I can't say that I have any idea why the change
>> would impact the Smack processing, but there appears
>> to be some serious packet processing going on. The
>> Smack code is using CIPSO on the loopback interface.
>> The test is supposed to verify that labels can be
>> set on the packets using CIPSO. Unlabeled packets
>> do not appear to be impacted. I do not know if SELinux
>> is affected, and if not, why not. Smack and SELinux
>> use CIPSO differently.
> For the past several months I've been running the SELinux testsuite on
> a weekly basis against Linus' kernel plus the SELinux and audit
> development trees and I haven't noticed any problems that haven't
> already been reported.  While not exhaustive, the testsuite does
> exercise the NetLabel/CIPSO code.  I'll see if I can take a closer
> look at the Smack code, but do you rely on the inet_skb_param values
> in Smack?  We did have a similar problem in the NetLabel core code
> that we fixed with 04f81f0154e4bf002be6f4d85668ce1257efa4d9; it's
> possible there is a similar problem in code that we just aren't
> exercising with SELinux at the moment.

I reported that problem, and that problem was fixed.

I'm looking at the Linus tree and see no structure inet_skb_param.

> * https://github.com/SELinuxProject/selinux-testsuite
> * https://copr.fedorainfracloud.org/coprs/pcmoore/kernel-secnext
>
>> commit c3f1010b30f7fc611139cfb702a8685741aa6827
>> Merge: ca4aa97 0b922b7
>> Author: David S. Miller 
>> Date:   Wed May 11 19:31:40 2016 -0400
>>
>> Merge branch 'vrf-pktinfo'
>>
>> David Ahern says:
>>
>> 
>> net: vrf: Fixup PKTINFO to return enslaved device index
>>
>> Applications such as OSPF and BFD need the original ingress device not
>> the VRF device; the latter can be derived from the former. To that end
>> move the packet intercept from an rx handler that is invoked by
>> __netif_receive_skb_core to the ipv4 and ipv6 receive processing.
>>
>> IPv6 already saves the skb_iif to the control buffer in ipv6_rcv. Since
>> the skb->dev has not been switched the cb has the enslaved device. Make
>> the same happen for IPv4 by adding the skb_iif to inet_skb_parm and set
>> it in ipv4 code after clearing the skb control buffer similar to IPv6.
>> From there the pktinfo can just pull it from cb with the PKTINFO_SKB_CB
>> cast.
>> 
>>
>> Signed-off-by: David S. Miller 



Re: Network hang after c3f1010b30f7fc611139cfb702a8685741aa6827 with CIPSO & Smack

2016-07-06 Thread Casey Schaufler
On 7/6/2016 7:03 AM, Paul Moore wrote:
> On Wed, Jul 6, 2016 at 8:50 AM, Paul Moore  wrote:
>> On Tue, Jul 5, 2016 at 8:38 PM, Casey Schaufler  
>> wrote:
>>> I have encountered a system hang with my Smack
>>> networking tests that bisects to the change below.
>>> I can't say that I have any idea why the change
>>> would impact the Smack processing, but there appears
>>> to be some serious packet processing going on. The
>>> Smack code is using CIPSO on the loopback interface.
>>> The test is supposed to verify that labels can be
>>> set on the packets using CIPSO. Unlabeled packets
>>> do not appear to be impacted. I do not know if SELinux
>>> is affected, and if not, why not. Smack and SELinux
>>> use CIPSO differently.
>> For the past several months I've been running the SELinux testsuite on
>> a weekly basis against Linus' kernel plus the SELinux and audit
>> development trees and I haven't noticed any problems that haven't
>> already been reported.  While not exhaustive, the testsuite does
>> exercise the NetLabel/CIPSO code.  I'll see if I can take a closer
>> look at the Smack code, but do you rely on the inet_skb_param values
>> in Smack?  We did have a similar problem in the NetLabel core code
>> that we fixed with 04f81f0154e4bf002be6f4d85668ce1257efa4d9; it's
>> possible there is a similar problem in code that we just aren't
>> exercising with SELinux at the moment.
>>
>> * https://github.com/SELinuxProject/selinux-testsuite
>> * https://copr.fedorainfracloud.org/coprs/pcmoore/kernel-secnext
> I just ran some additional SELinux/NetLabel tests on 4.7-rc6
> (+selinux#next +audit#next) and everything worked as expected.  This
> is looking more and more like a Smack specific bug.

That would not surprise me at all. Smack uses CIPSO more
extensively than SELinux.

>   I took a quick
> look at the NetLabel/CIPSO code as well as some of the Smack code and
> nothing jumped out at me as obviously wrong, but it has been years
> since I've looked at the Smack code in any detail.
>
> I'm happy to help debug, but I think it might be more helpful if you
> take a closer look at the Smack code first.

That was where my long weekend was spent. Except for a trivial
change in the signal delivery code, there haven't been changes
in Smack recently.

That's why I took the bisect route to try to find the problem.

I am perfectly willing to accept that there's something that
I'm doing wrong (I often do things wrong). In this case, it's
got to be something that I've been getting away with for quite
some time.



Re: Network hang after c3f1010b30f7fc611139cfb702a8685741aa6827 with CIPSO & Smack

2016-07-06 Thread Casey Schaufler
On 7/6/2016 9:28 AM, David Ahern wrote:
> On 7/5/16 6:31 PM, Casey Schaufler wrote:
>> On 7/5/2016 5:49 PM, David Ahern wrote:
>>> On 7/5/16 5:38 PM, Casey Schaufler wrote:
>>>> I have encountered a system hang with my Smack
>>>> networking tests that bisects to the change below.
>>>> I can't say that I have any idea why the change
>>>> would impact the Smack processing, but there appears
>>>> to be some serious packet processing going on. The
>>>> Smack code is using CIPSO on the loopback interface.
>>>> The test is supposed to verify that labels can be
>>>> set on the packets using CIPSO. Unlabeled packets
>>>> do not appear to be impacted. I do not know if SELinux
>>>> is affected, and if not, why not. Smack and SELinux
>>>> use CIPSO differently.
>>>
>>> What are the commands to repeat the test?
>>>
>> There is a tar file attached with the tests.
>> Put the etc/smack/user file into /etc/smack/user.
>> In the tools-2012 directory run make to build
>> the tools. The test in question is called
>> testnetworking.sh and needs to be run as root.
>> You will need to configure Smack in the kernel,
>> of course.
>>
>
> I understand Paul's point and glad to see the changes are not causing issues 
> with his SELinux testing.
>
> I have tried to reproduce the lockup you are seeing but not successful. I am 
> using a jessie based VM with latest net-next kernel.
>
> root@kenny-jessie3:~/smack/tools-2012# zcat /proc/config.gz | grep SMACK
> CONFIG_SECURITY_SMACK=y
> CONFIG_SECURITY_SMACK_BRINGUP=y
> CONFIG_SECURITY_SMACK_NETFILTER=y
> # CONFIG_DEFAULT_SECURITY_SMACK is not set

CONFIG_DEFAULT_SECURITY_SMACK needs to be set.

>
> root@kenny-jessie3:~/smack/tools-2012# bash -x ./testnetworking.sh
> 
>
> Send me your kernel config. Perhaps I do not have some config enabled.
>



Re: Network hang after c3f1010b30f7fc611139cfb702a8685741aa6827 with CIPSO & Smack

2016-07-06 Thread Casey Schaufler
On 7/6/2016 10:40 AM, David Ahern wrote:
> On 7/6/16 10:24 AM, Casey Schaufler wrote:
>> On 7/6/2016 9:28 AM, David Ahern wrote:
>>> On 7/5/16 6:31 PM, Casey Schaufler wrote:
>>>> On 7/5/2016 5:49 PM, David Ahern wrote:
>>>>> On 7/5/16 5:38 PM, Casey Schaufler wrote:
>>>>>> I have encountered a system hang with my Smack
>>>>>> networking tests that bisects to the change below.
>>>>>> I can't say that I have any idea why the change
>>>>>> would impact the Smack processing, but there appears
>>>>>> to be some serious packet processing going on. The
>>>>>> Smack code is using CIPSO on the loopback interface.
>>>>>> The test is supposed to verify that labels can be
>>>>>> set on the packets using CIPSO. Unlabeled packets
>>>>>> do not appear to be impacted. I do not know if SELinux
>>>>>> is affected, and if not, why not. Smack and SELinux
>>>>>> use CIPSO differently.
>>>>>
>>>>> What are the commands to repeat the test?
>>>>>
>>>> There is a tar file attached with the tests.
>>>> Put the etc/smack/user file into /etc/smack/user.
>>>> In the tools-2012 directory run make to build
>>>> the tools. The test in question is called
>>>> testnetworking.sh and needs to be run as root.
>>>> You will need to configure Smack in the kernel,
>>>> of course.
>>>>
>>>
>>> I understand Paul's point and glad to see the changes are not causing 
>>> issues with his SELinux testing.
>>>
>>> I have tried to reproduce the lockup you are seeing but not successful. I 
>>> am using a jessie based VM with latest net-next kernel.
>>>
>>> root@kenny-jessie3:~/smack/tools-2012# zcat /proc/config.gz | grep SMACK
>>> CONFIG_SECURITY_SMACK=y
>>> CONFIG_SECURITY_SMACK_BRINGUP=y
>>> CONFIG_SECURITY_SMACK_NETFILTER=y
>>> # CONFIG_DEFAULT_SECURITY_SMACK is not set
>>
>> CONFIG_DEFAULT_SECURITY_SMACK needs to be set.
>
> ok. That caused more interesting output but still no hang after all of the 
> snap-crackle-and-pops.
>
I find the test occasionally passes without hanging, but will
hang the system if repeated. I am running on Ubuntu and Fedora,
both with systemd, which may be a contributing factor. I run
under qemu, and am based on Linus' tree.



Re: Network hang after c3f1010b30f7fc611139cfb702a8685741aa6827 with CIPSO & Smack

2016-07-06 Thread Casey Schaufler
On 7/6/2016 11:43 AM, David Ahern wrote:
> On 7/6/16 11:01 AM, Casey Schaufler wrote:
>> I find the test occasionally passes without hanging, but will
>> hang the system if repeated. I am running on Ubuntu and Fedora,
>> both with systemd, which may be a contributing factor. I run
>> under qemu, and am based on Linus' tree.
>>
>
> With this:
>
> for n in $(seq 1 10); do
> bash -x ./testnetworking.sh
> sleep 10
> done
>
> I do get the VM to loop where I can not kill the test. dmesg has this splat:
>
> [ 3576.504715] general protection fault:  [#21] SMP
> [ 3576.505322] Modules linked in: 8021q garp mrp stp llc
> [ 3576.506007] CPU: 3 PID: 2938 Comm: killall Tainted: G  D 4.7.0-rc5+ #20
> [ 3576.506881] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 
> 1.7.5-20140531_083030-gandalf 04/01/2014
> [ 3576.508048] task: 8800b4e72340 ti: 880138a48000 task.ti: 
> 880138a48000
> [ 3576.508894] RIP: 0010:[]  [] 
> next_tgid+0x53/0x99
> [ 3576.509803] RSP: 0018:880138a4bde8  EFLAGS: 00010206
> [ 3576.510410] RAX: 4100646e4100608e RBX: 07f2 RCX: 
> 8800b98c9bb0
> [ 3576.511218] RDX: 4100646e4100608e RSI: 03e0 RDI: 
> 8800b98c9b80
> [ 3576.512024] RBP: 880138a4be10 R08: 0032 R09: 
> 
> [ 3576.512833] R10:  R11: 0200 R12: 
> 07e5
> [ 3576.513647] R13: 8800b98c9b80 R14: 81a27900 R15: 
> 07e4
> [ 3576.514453] FS:  7fc084469700() GS:88013fd8() 
> knlGS:
> [ 3576.515361] CS:  0010 DS:  ES:  CR0: 80050033
> [ 3576.516009] CR2: 01947000 CR3: b5449000 CR4: 
> 000406e0
> [ 3576.516818] Stack:
> [ 3576.517057]  07e5  880138a4bee0 
> 8800b982a140
> [ 3576.517963]  81a27900 880138a4be68 81187090 
> 8800b1d9d300
> [ 3576.518857]  003032303201 880138a4bee0 880138a4bee0 
> 
> [ 3576.519754] Call Trace:
> [ 3576.520044]  [] proc_pid_readdir+0xd4/0x18b
> [ 3576.520697]  [] proc_root_readdir+0x35/0x3a
> [ 3576.521352]  [] iterate_dir+0xac/0x148
> [ 3576.521966]  [] ? __fget_light+0x27/0x48
> [ 3576.522587]  [] SyS_getdents+0x8a/0xdc
> [ 3576.523189]  [] ? fillonedir+0xc7/0xc7
> [ 3576.523794]  [] entry_SYSCALL_64_fastpath+0x1a/0xa4
> [ 3576.524524]  [] ? entry_SYSCALL_64_fastpath+0x1a/0xa4
> [ 3576.525276] Code: d6 aa ed ff 48 85 c0 49 89 c5 74 40 4c 89 f6 48 89 c7 e8 
> 8b a2 ed ff 31 f6 4c 89 ef 89 c3 e8 15 a2 ed ff 48 85 c0 48 89 c2 74 17 <48> 
> 8b 80 78 05 00 00 48 8b 80 c8 00 00 00 48 39 82 f0 03 00 00
> [ 3576.528359] RIP  [] next_tgid+0x53/0x99
> [ 3576.528991]  RSP 
> [ 3576.529452] ---[ end trace a6f0cb9bfb70d9e6 ]---
>
> And then I can no longer run commands:
>
> root@kenny-jessie3:~# top -d1
> Segmentation fault
>
My thought is that there's a locking issue on a resource
somewhere in the TCP stack, and that a freed but still in
use buffer is getting into the filesystem code somehow.



Re: Network hang after c3f1010b30f7fc611139cfb702a8685741aa6827 with CIPSO & Smack

2016-07-19 Thread Casey Schaufler
On 7/6/2016 11:56 AM, Casey Schaufler wrote:
> On 7/6/2016 11:43 AM, David Ahern wrote:
>> On 7/6/16 11:01 AM, Casey Schaufler wrote:
>>> I find the test occasionally passes without hanging, but will
>>> hang the system if repeated. I am running on Ubuntu and Fedora,
>>> both with systemd, which may be a contributing factor. I run
>>> under qemu, and am based on Linus' tree.
>>>
>> With this:
>>
>> for n in $(seq 1 10); do
>> bash -x ./testnetworking.sh
>> sleep 10
>> done
>>
>> I do get the VM to loop where I can not kill the test. dmesg has this splat:
>>
>> [ 3576.504715] general protection fault:  [#21] SMP
>> [ 3576.505322] Modules linked in: 8021q garp mrp stp llc
>> [ 3576.506007] CPU: 3 PID: 2938 Comm: killall Tainted: G  D 4.7.0-rc5+ 
>> #20
>> [ 3576.506881] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 
>> 1.7.5-20140531_083030-gandalf 04/01/2014
>> [ 3576.508048] task: 8800b4e72340 ti: 880138a48000 task.ti: 
>> 880138a48000
>> [ 3576.508894] RIP: 0010:[]  [] 
>> next_tgid+0x53/0x99
>> [ 3576.509803] RSP: 0018:880138a4bde8  EFLAGS: 00010206
>> [ 3576.510410] RAX: 4100646e4100608e RBX: 07f2 RCX: 
>> 8800b98c9bb0
>> [ 3576.511218] RDX: 4100646e4100608e RSI: 03e0 RDI: 
>> 8800b98c9b80
>> [ 3576.512024] RBP: 880138a4be10 R08: 0032 R09: 
>> 
>> [ 3576.512833] R10:  R11: 0200 R12: 
>> 07e5
>> [ 3576.513647] R13: 8800b98c9b80 R14: 81a27900 R15: 
>> 07e4
>> [ 3576.514453] FS:  7fc084469700() GS:88013fd8() 
>> knlGS:
>> [ 3576.515361] CS:  0010 DS:  ES:  CR0: 80050033
>> [ 3576.516009] CR2: 01947000 CR3: b5449000 CR4: 
>> 000406e0
>> [ 3576.516818] Stack:
>> [ 3576.517057]  07e5  880138a4bee0 
>> 8800b982a140
>> [ 3576.517963]  81a27900 880138a4be68 81187090 
>> 8800b1d9d300
>> [ 3576.518857]  003032303201 880138a4bee0 880138a4bee0 
>> 
>> [ 3576.519754] Call Trace:
>> [ 3576.520044]  [] proc_pid_readdir+0xd4/0x18b
>> [ 3576.520697]  [] proc_root_readdir+0x35/0x3a
>> [ 3576.521352]  [] iterate_dir+0xac/0x148
>> [ 3576.521966]  [] ? __fget_light+0x27/0x48
>> [ 3576.522587]  [] SyS_getdents+0x8a/0xdc
>> [ 3576.523189]  [] ? fillonedir+0xc7/0xc7
>> [ 3576.523794]  [] entry_SYSCALL_64_fastpath+0x1a/0xa4
>> [ 3576.524524]  [] ? entry_SYSCALL_64_fastpath+0x1a/0xa4
>> [ 3576.525276] Code: d6 aa ed ff 48 85 c0 49 89 c5 74 40 4c 89 f6 48 89 c7 
>> e8 8b a2 ed ff 31 f6 4c 89 ef 89 c3 e8 15 a2 ed ff 48 85 c0 48 89 c2 74 17 
>> <48> 8b 80 78 05 00 00 48 8b 80 c8 00 00 00 48 39 82 f0 03 00 00
>> [ 3576.528359] RIP  [] next_tgid+0x53/0x99
>> [ 3576.528991]  RSP 
>> [ 3576.529452] ---[ end trace a6f0cb9bfb70d9e6 ]---
>>
>> And then I can no longer run commands:
>>
>> root@kenny-jessie3:~# top -d1
>> Segmentation fault
>>
> My thought is that there's a locking issue on a resource
> somewhere in the TCP stack, and that a freed but still in
> use buffer is getting into the filesystem code somehow.

Digging into this further I have determined that the
circumstances leading to this issue are somewhat complex.
The good news is that there seems to be a very limited
circumstances under which the problem manifests.

I have a socket, and change the Smack attributes on the
socket (security_inode_setsecurity) before connecting to
a server. The connect succeeds. The client sends a packet,
also successfully. The response is received. Now here's
where it gets interesting. I instrumented the code to print
the Smack attributes on the socket both before and after
the Smack access check. Before the check is made the Smack
data reflects the initial values from when the socket was
created. After the check, they reflect the explicit change
made earlier. The check reports failure based on the initial
values. As a result, an attempt to notify the caller that
the action failed is made (netlbl_skbuff_err) which results
in a call to icmp_send that frees already freed memory.

If the Smack attributes in the sk_security blob are not
explicitly set the problem does not occur. I have the same
result if I change the Smack attributes within the socket
security blob as I do if I replace the security blob.



Re: Network hang after c3f1010b30f7fc611139cfb702a8685741aa6827 with CIPSO & Smack

2016-07-21 Thread Casey Schaufler
On 7/20/2016 1:13 PM, Paul Moore wrote:
> On Tue, Jul 19, 2016 at 7:37 PM, Casey Schaufler  
> wrote:
>> Digging into this further I have determined that the
>> circumstances leading to this issue are somewhat complex.
>> The good news is that there seems to be a very limited
>> circumstances under which the problem manifests.
>>
>> I have a socket, and change the Smack attributes on the
>> socket (security_inode_setsecurity) before connecting to
>> a server.
> This is a minty fresh, disconnected socket, yes?
>
>> The connect succeeds. The client sends a packet,
>> also successfully. The response is received. Now here's
>> where it gets interesting. I instrumented the code to print
>> the Smack attributes on the socket both before and after
>> the Smack access check.
> I'm assuming that when you say "access check" you are talking about
> the smk_access() call in smack_socket_sock_rcv_skb(), yes?

I have been able to track this down to my careless
use of netlbl_skbuff_err(). Because the socket started
life as unlabeled, and changed to labeled, calling
netlbl_skbuff_err() resulted in multiple frees of some
netlabel data under some circumstances. I don't know
why it worked before, but the code certainly shouldn't
have been making that call. I have a patch in final test.

>
> (as a totally unrelated side note, you really went nuts on the cpp
> conditionals in there, was there a sale on #ifdefs that I missed? )

I can't say that I'm happy about how that code ended up.
I hope to do a clean up in association with switching away
from CIPSO to secmark for local access controls. That's something
I have to do for Extreme Security Module Stacking.

>
>> Before the check is made the Smack
>> data reflects the initial values from when the socket was
>> created. After the check, they reflect the explicit change
>> made earlier.
> It has been too long since I looked at how Smack handled network
> packets, I assume this is not the intended behavior?
>
>> The check reports failure based on the initial
>> values. As a result, an attempt to notify the caller that
>> the action failed is made (netlbl_skbuff_err) which results
>> in a call to icmp_send that frees already freed memory.
> What memory is being double freed?  The original skb?  I don't believe
> netlbl_skbuff_err(), cipso_v4_error(), or icmp_send() frees the
> original skb ... or rather it shouldn't, perhaps I'm missing
> something.
>
> I'm not arguing, you saw what you saw, I'm just trying to understand
> and make sense of it.  Can you elaborate on what you saw, using very
> small words, and concrete descriptions (I'm much more stupider than
> everyone here so you have to make it easy for me to understand)?
>
>> If the Smack attributes in the sk_security blob are not
>> explicitly set the problem does not occur. I have the same
>> result if I change the Smack attributes within the socket
>> security blob as I do if I replace the security blob.



Re: RFC(v2): Audit Kernel Container IDs

2017-10-12 Thread Casey Schaufler
On 10/12/2017 7:14 AM, Richard Guy Briggs wrote:
> Containers are a userspace concept.  The kernel knows nothing of them.
>
> The Linux audit system needs a way to be able to track the container
> provenance of events and actions.  Audit needs the kernel's help to do
> this.
>
> Since the concept of a container is entirely a userspace concept, a
> registration from the userspace container orchestration system initiates
> this.  This will define a point in time and a set of resources
> associated with a particular container with an audit container ID.
>
> The registration is a pseudo filesystem (proc, since PID tree already
> exists) write of a u8[16] UUID representing the container ID to a file
> representing a process that will become the first process in a new
> container.  This write might place restrictions on mount namespaces
> required to define a container, or at least careful checking of
> namespaces in the kernel to verify permissions of the orchestrator so it
> can't change its own container ID.  A bind mount of nsfs may be
> necessary in the container orchestrator's mntNS.
> Note: Use a 128-bit scalar rather than a string to make compares faster
> and simpler.
>
> Require a new CAP_CONTAINER_ADMIN to be able to carry out the
> registration.

Hang on. If containers are a user space concept, how can
you want CAP_CONTAINER_ANYTHING? If there's not such thing as
a container, how can you be asking for a capability to manage
them?

>   At that time, record the target container's user-supplied
> container identifier along with the target container's first process
> (which may become the target container's "init" process) process ID
> (referenced from the initial PID namespace), all namespace IDs (in the
> form of a nsfs device number and inode number tuple) in a new auxilliary
> record AUDIT_CONTAINER with a qualifying op=$action field.
>
> Issue a new auxilliary record AUDIT_CONTAINER_INFO for each valid
> container ID present on an auditable action or event.
>
> Forked and cloned processes inherit their parent's container ID,
> referenced in the process' task_struct.
>
> Mimic setns(2) and return an error if the process has already initiated
> threading or forked since this registration should happen before the
> process execution is started by the orchestrator and hence should not
> yet have any threads or children.  If this is deemed overly restrictive,
> switch all threads and children to the new containerID.
>
> Trust the orchestrator to judiciously use and restrict CAP_CONTAINER_ADMIN.
>
> Log the creation of every namespace, inheriting/adding its spawning
> process' containerID(s), if applicable.  Include the spawning and
> spawned namespace IDs (device and inode number tuples).
> [AUDIT_NS_CREATE, AUDIT_NS_DESTROY] [clone(2), unshare(2), setns(2)]
> Note: At this point it appears only network namespaces may need to track
> container IDs apart from processes since incoming packets may cause an
> auditable event before being associated with a process.
>
> Log the destruction of every namespace when it is no longer used by any
> process, include the namespace IDs (device and inode number tuples).
> [AUDIT_NS_DESTROY] [process exit, unshare(2), setns(2)]
>
> Issue a new auxilliary record AUDIT_NS_CHANGE listing (opt: op=$action)
> the parent and child namespace IDs for any changes to a process'
> namespaces. [setns(2)]
> Note: It may be possible to combine AUDIT_NS_* record formats and
> distinguish them with an op=$action field depending on the fields
> required for each message type.
>
> When a container ceases to exist because the last process in that
> container has exited and hence the last namespace has been destroyed and
> its refcount dropping to zero, log the fact.
> (This latter is likely needed for certification accountability.)  A
> container object may need a list of processes and/or namespaces.
>
> A namespace cannot directly migrate from one container to another but
> could be assigned to a newly spawned container.  A namespace can be
> moved from one container to another indirectly by having that namespace
> used in a second process in another container and then ending all the
> processes in the first container.
>
> (v2)
> - switch from u64 to u128 UUID
> - switch from "signal" and "trigger" to "register"
> - restrict registration to single process or force all threads and children 
> into same container
>
> - RGB
>
> --
> Richard Guy Briggs 
> Sr. S/W Engineer, Kernel Security, Base Operating Systems
> Remote, Ottawa, Red Hat Canada
> IRC: rgb, SunRaycer
> Voice: +1.647.777.2635, Internal: (81) 32635
>
> --
> Linux-audit mailing list
> linux-au...@redhat.com
> https://www.redhat.com/mailman/listinfo/linux-audit
>



Re: [BUG] kernel stack corruption during/after Netlabel error

2017-11-29 Thread Casey Schaufler
On 11/29/2017 2:26 AM, James Morris wrote:
> I'm seeing a kernel stack corruption bug (detected via gcc) when running 
> the SELinux testsuite on a 4.15-rc1 kernel, in the 2nd inet_socket test:
>
> https://github.com/SELinuxProject/selinux-testsuite/blob/master/tests/inet_socket/test
>
>   # Verify that unauthorized client cannot communicate with the server.
>   $result = system
>   "runcon -t test_inet_bad_client_t -- $basedir/client stream 127.0.0.1 65535 
> 2>&1";
>
> This correctlly causes an access control error in the Netlabel code, and 
> the bug seems to be triggered during the ICMP send:
>
> ..
>
> This is mostly reliable, and I'm only seeing it on bare metal (not in a 
> virtualbox vm).
>
> The SELinux skb parse error at the start only sometimes appears, and 
> looking at the code, I suspect some kind of memory corruption being the 
> cause at that point (basic packet header checks).
>
> I bisected the bug down to the following change:
>
> commit bffa72cf7f9df842f0016ba03586039296b4caaf
> Author: Eric Dumazet 
> Date:   Tue Sep 19 05:14:24 2017 -0700
>
> net: sk_buff rbnode reorg
> ...
>
>
> Anyone else able to reproduce this, or have any ideas on what's happening?

I have also bisected a problem to this change. I do not have a trace
because the problem manifests as a hard system hang without a trace
being presented. The issue arises when Smack attempts to relabel a TCP
socket using netlbl_sock_setattr().

I see that there is a proposed fix later in the thread, but I don't see
the patch. Could you send it to me, so I can try it on my problem?

Thank you.

>
>
>
> - James



Re: [BUG] kernel stack corruption during/after Netlabel error

2017-11-29 Thread Casey Schaufler

On 11/29/2017 4:31 PM, James Morris wrote:
> On Wed, 29 Nov 2017, Casey Schaufler wrote:
>
>> I see that there is a proposed fix later in the thread, but I don't see
>> the patch. Could you send it to me, so I can try it on my problem?
> Forwarded off-list.

The patch does fix the problem I was seeing in Smack.

>
> Interestingly, I didn't see the KASAN output email from Stephen here.
>
>



Re: [BUG] kernel stack corruption during/after Netlabel error

2017-11-30 Thread Casey Schaufler
On 11/30/2017 2:50 AM, Eric Dumazet wrote:
> On Wed, 2017-11-29 at 19:16 -0800, Casey Schaufler wrote:
>> On 11/29/2017 4:31 PM, James Morris wrote:
>>> On Wed, 29 Nov 2017, Casey Schaufler wrote:
>>>
>>>> I see that there is a proposed fix later in the thread, but I
>>>> don't see
>>>> the patch. Could you send it to me, so I can try it on my
>>>> problem?
>>> Forwarded off-list.
>> The patch does fix the problem I was seeing in Smack.
> Can you guys test the following more complete patch ?

Building now. I should have results soon.

>
> It should cover IPv4 and IPv6, and also the corner cases.
>
> ( Note that I squashed ipv6 fix in https://patchwork.ozlabs.org/patch/8
> 42844/ that I spotted while cooking this patch )
>
> diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
> index 
> c6bc0c4d19c624888b0d0b5a4246c7183edf63f5..77ea45da0fe9c746907a312989658af3ad3b198d
>  100644
> --- a/net/ipv4/tcp_ipv4.c
> +++ b/net/ipv4/tcp_ipv4.c
> @@ -1591,6 +1591,34 @@ int tcp_filter(struct sock *sk, struct sk_buff *skb)
>  }
>  EXPORT_SYMBOL(tcp_filter);
>  
> +static void tcp_v4_restore_cb(struct sk_buff *skb)
> +{
> + memmove(IPCB(skb), &TCP_SKB_CB(skb)->header.h4,
> + sizeof(struct inet_skb_parm));
> +}
> +
> +static void tcp_v4_fill_cb(struct sk_buff *skb, const struct iphdr *iph,
> +const struct tcphdr *th)
> +{
> + /* This is tricky : We move IPCB at its correct location into 
> TCP_SKB_CB()
> +  * barrier() makes sure compiler wont play fool^Waliasing games.
> +  */
> + memmove(&TCP_SKB_CB(skb)->header.h4, IPCB(skb),
> + sizeof(struct inet_skb_parm));
> + barrier();
> +
> + TCP_SKB_CB(skb)->seq = ntohl(th->seq);
> + TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
> + skb->len - th->doff * 4);
> + TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
> + TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th);
> + TCP_SKB_CB(skb)->tcp_tw_isn = 0;
> + TCP_SKB_CB(skb)->ip_dsfield = ipv4_get_dsfield(iph);
> + TCP_SKB_CB(skb)->sacked  = 0;
> + TCP_SKB_CB(skb)->has_rxtstamp =
> + skb->tstamp || skb_hwtstamps(skb)->hwtstamp;
> +}
> +
>  /*
>   *   From tcp_input.c
>   */
> @@ -1631,24 +1659,6 @@ int tcp_v4_rcv(struct sk_buff *skb)
>  
>   th = (const struct tcphdr *)skb->data;
>   iph = ip_hdr(skb);
> - /* This is tricky : We move IPCB at its correct location into 
> TCP_SKB_CB()
> -  * barrier() makes sure compiler wont play fool^Waliasing games.
> -  */
> - memmove(&TCP_SKB_CB(skb)->header.h4, IPCB(skb),
> - sizeof(struct inet_skb_parm));
> - barrier();
> -
> - TCP_SKB_CB(skb)->seq = ntohl(th->seq);
> - TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
> - skb->len - th->doff * 4);
> - TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
> - TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th);
> - TCP_SKB_CB(skb)->tcp_tw_isn = 0;
> - TCP_SKB_CB(skb)->ip_dsfield = ipv4_get_dsfield(iph);
> - TCP_SKB_CB(skb)->sacked  = 0;
> - TCP_SKB_CB(skb)->has_rxtstamp =
> - skb->tstamp || skb_hwtstamps(skb)->hwtstamp;
> -
>  lookup:
>   sk = __inet_lookup_skb(&tcp_hashinfo, skb, __tcp_hdrlen(th), th->source,
>  th->dest, sdif, &refcounted);
> @@ -1679,14 +1689,19 @@ int tcp_v4_rcv(struct sk_buff *skb)
>   sock_hold(sk);
>   refcounted = true;
>   nsk = NULL;
> - if (!tcp_filter(sk, skb))
> + if (!tcp_filter(sk, skb)) {
> + th = (const struct tcphdr *)skb->data;
> + iph = ip_hdr(skb);
> + tcp_v4_fill_cb(skb, iph, th);
>   nsk = tcp_check_req(sk, skb, req, false);
> + }
>   if (!nsk) {
>   reqsk_put(req);
>   goto discard_and_relse;
>   }
>   if (nsk == sk) {
>   reqsk_put(req);
> + tcp_v4_restore_cb(skb);
>   } else if (tcp_child_process(sk, nsk, skb)) {
>   tcp_v4_send_reset(nsk, skb);
>   goto discard_and_relse;
> @@ -1712,6 +1727,7 @@ int tcp_v4_rcv(struct sk_buff *skb)
>   goto discard_and_relse;
>   th = (const struct tcphdr *)skb->data;
>

Re: [BUG] kernel stack corruption during/after Netlabel error

2017-11-30 Thread Casey Schaufler
On 11/30/2017 2:50 AM, Eric Dumazet wrote:
> On Wed, 2017-11-29 at 19:16 -0800, Casey Schaufler wrote:
>> On 11/29/2017 4:31 PM, James Morris wrote:
>>> On Wed, 29 Nov 2017, Casey Schaufler wrote:
>>>
>>>> I see that there is a proposed fix later in the thread, but I
>>>> don't see
>>>> the patch. Could you send it to me, so I can try it on my
>>>> problem?
>>> Forwarded off-list.
>> The patch does fix the problem I was seeing in Smack.
> Can you guys test the following more complete patch ?

My tests are passing. Thank you.

Tested-by: Casey Schaufler 

>
> It should cover IPv4 and IPv6, and also the corner cases.
>
> ( Note that I squashed ipv6 fix in https://patchwork.ozlabs.org/patch/8
> 42844/ that I spotted while cooking this patch )
>
> diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
> index 
> c6bc0c4d19c624888b0d0b5a4246c7183edf63f5..77ea45da0fe9c746907a312989658af3ad3b198d
>  100644
> --- a/net/ipv4/tcp_ipv4.c
> +++ b/net/ipv4/tcp_ipv4.c
> @@ -1591,6 +1591,34 @@ int tcp_filter(struct sock *sk, struct sk_buff *skb)
>  }
>  EXPORT_SYMBOL(tcp_filter);
>  
> +static void tcp_v4_restore_cb(struct sk_buff *skb)
> +{
> + memmove(IPCB(skb), &TCP_SKB_CB(skb)->header.h4,
> + sizeof(struct inet_skb_parm));
> +}
> +
> +static void tcp_v4_fill_cb(struct sk_buff *skb, const struct iphdr *iph,
> +const struct tcphdr *th)
> +{
> + /* This is tricky : We move IPCB at its correct location into 
> TCP_SKB_CB()
> +  * barrier() makes sure compiler wont play fool^Waliasing games.
> +  */
> + memmove(&TCP_SKB_CB(skb)->header.h4, IPCB(skb),
> + sizeof(struct inet_skb_parm));
> + barrier();
> +
> + TCP_SKB_CB(skb)->seq = ntohl(th->seq);
> + TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
> + skb->len - th->doff * 4);
> + TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
> + TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th);
> + TCP_SKB_CB(skb)->tcp_tw_isn = 0;
> + TCP_SKB_CB(skb)->ip_dsfield = ipv4_get_dsfield(iph);
> + TCP_SKB_CB(skb)->sacked  = 0;
> + TCP_SKB_CB(skb)->has_rxtstamp =
> + skb->tstamp || skb_hwtstamps(skb)->hwtstamp;
> +}
> +
>  /*
>   *   From tcp_input.c
>   */
> @@ -1631,24 +1659,6 @@ int tcp_v4_rcv(struct sk_buff *skb)
>  
>   th = (const struct tcphdr *)skb->data;
>   iph = ip_hdr(skb);
> - /* This is tricky : We move IPCB at its correct location into 
> TCP_SKB_CB()
> -  * barrier() makes sure compiler wont play fool^Waliasing games.
> -  */
> - memmove(&TCP_SKB_CB(skb)->header.h4, IPCB(skb),
> - sizeof(struct inet_skb_parm));
> - barrier();
> -
> - TCP_SKB_CB(skb)->seq = ntohl(th->seq);
> - TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
> - skb->len - th->doff * 4);
> - TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
> - TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th);
> - TCP_SKB_CB(skb)->tcp_tw_isn = 0;
> - TCP_SKB_CB(skb)->ip_dsfield = ipv4_get_dsfield(iph);
> - TCP_SKB_CB(skb)->sacked  = 0;
> - TCP_SKB_CB(skb)->has_rxtstamp =
> - skb->tstamp || skb_hwtstamps(skb)->hwtstamp;
> -
>  lookup:
>   sk = __inet_lookup_skb(&tcp_hashinfo, skb, __tcp_hdrlen(th), th->source,
>  th->dest, sdif, &refcounted);
> @@ -1679,14 +1689,19 @@ int tcp_v4_rcv(struct sk_buff *skb)
>   sock_hold(sk);
>   refcounted = true;
>   nsk = NULL;
> - if (!tcp_filter(sk, skb))
> + if (!tcp_filter(sk, skb)) {
> + th = (const struct tcphdr *)skb->data;
> + iph = ip_hdr(skb);
> + tcp_v4_fill_cb(skb, iph, th);
>   nsk = tcp_check_req(sk, skb, req, false);
> + }
>   if (!nsk) {
>   reqsk_put(req);
>   goto discard_and_relse;
>   }
>   if (nsk == sk) {
>   reqsk_put(req);
> + tcp_v4_restore_cb(skb);
>   } else if (tcp_child_process(sk, nsk, skb)) {
>   tcp_v4_send_reset(nsk, skb);
>   goto discard_and_relse;
> @@ -1712,6 +1727,7 @@ int tcp_v4_rcv(struct sk_buff *skb)
>   goto discard_and_relse;
>   th = (c

Re: [BUG] kernel stack corruption during/after Netlabel error

2017-11-30 Thread Casey Schaufler
On 11/30/2017 9:57 AM, Eric Dumazet wrote:
> On Thu, 2017-11-30 at 10:30 -0700, David Ahern wrote:
>> On 11/30/17 8:44 AM, David Ahern wrote:
>>> On 11/30/17 3:50 AM, Eric Dumazet wrote:
 @@ -1631,24 +1659,6 @@ int tcp_v4_rcv(struct sk_buff *skb)
  
    th = (const struct tcphdr *)skb->data;
    iph = ip_hdr(skb);
 -  /* This is tricky : We move IPCB at its correct location
 into TCP_SKB_CB()
 -   * barrier() makes sure compiler wont play
 fool^Waliasing games.
 -   */
 -  memmove(&TCP_SKB_CB(skb)->header.h4, IPCB(skb),
 -  sizeof(struct inet_skb_parm));
 -  barrier();
 -
 -  TCP_SKB_CB(skb)->seq = ntohl(th->seq);
 -  TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th-
> syn + th->fin +
 -  skb->len - th->doff * 4);
 -  TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
 -  TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th);
 -  TCP_SKB_CB(skb)->tcp_tw_isn = 0;
 -  TCP_SKB_CB(skb)->ip_dsfield = ipv4_get_dsfield(iph);
 -  TCP_SKB_CB(skb)->sacked  = 0;
 -  TCP_SKB_CB(skb)->has_rxtstamp =
 -  skb->tstamp || skb_hwtstamps(skb)-
> hwtstamp;
 -
  lookup:
    sk = __inet_lookup_skb(&tcp_hashinfo, skb,
 __tcp_hdrlen(th), th->source,
       th->dest, sdif, &refcounted);
>>> I believe moving the above is going to affect lookups with VRF. Let
>>> me
>>> take a look before this gets committed.
>>>
>> Eric:
>>
>> Can you add this to the patch? Fixes socket lookups with VRF which
>> stashes a flag in the cb.

I've done my testing and it works both ways for Smack.


>>
>> Thanks,
>>
>> diff --git a/include/net/tcp.h b/include/net/tcp.h
>> index 4e09398009c1..6c020015d556 100644
>> --- a/include/net/tcp.h
>> +++ b/include/net/tcp.h
>> @@ -849,7 +849,7 @@ static inline bool inet_exact_dif_match(struct
>> net
>> *net, struct sk_buff *skb)
>>  {
>>  #if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
>> if (!net->ipv4.sysctl_tcp_l3mdev_accept &&
>> -   skb && ipv4_l3mdev_skb(TCP_SKB_CB(skb)->header.h4.flags))
>> +   skb && ipv4_l3mdev_skb(IPCB(skb)->flags))
>> return true;
>>  #endif
>> return false;
>
> I wonder if this should not be in a separate patch ?
>
> Bug was added in 971f10eca186cab238c49daa91f703c5a001b0b1 ("tcp: better
> TCP_SKB_CB layout to reduce cache line misses")  in linux 3.18
>
> While VRF was added later.
>
> If you agree, I will prepare a patch series, with different Fixes tag
> so that David can decide which path needs to be backported into each
> stable version.
>
> Thanks.
>
>



Re: RFC(v2): Audit Kernel Container IDs

2017-10-16 Thread Casey Schaufler
On 10/16/2017 5:33 PM, Richard Guy Briggs wrote:
> On 2017-10-12 16:33, Casey Schaufler wrote:
>> On 10/12/2017 7:14 AM, Richard Guy Briggs wrote:
>>> Containers are a userspace concept.  The kernel knows nothing of them.
>>>
>>> The Linux audit system needs a way to be able to track the container
>>> provenance of events and actions.  Audit needs the kernel's help to do
>>> this.
>>>
>>> Since the concept of a container is entirely a userspace concept, a
>>> registration from the userspace container orchestration system initiates
>>> this.  This will define a point in time and a set of resources
>>> associated with a particular container with an audit container ID.
>>>
>>> The registration is a pseudo filesystem (proc, since PID tree already
>>> exists) write of a u8[16] UUID representing the container ID to a file
>>> representing a process that will become the first process in a new
>>> container.  This write might place restrictions on mount namespaces
>>> required to define a container, or at least careful checking of
>>> namespaces in the kernel to verify permissions of the orchestrator so it
>>> can't change its own container ID.  A bind mount of nsfs may be
>>> necessary in the container orchestrator's mntNS.
>>> Note: Use a 128-bit scalar rather than a string to make compares faster
>>> and simpler.
>>>
>>> Require a new CAP_CONTAINER_ADMIN to be able to carry out the
>>> registration.
>> Hang on. If containers are a user space concept, how can
>> you want CAP_CONTAINER_ANYTHING? If there's not such thing as
>> a container, how can you be asking for a capability to manage
>> them?
> There is such a thing, but the kernel doesn't know about it yet.

Then how can it be the kernel's place to control access to a
container resource, that is, the containerID.

>   This
> same situation exists for loginuid and sessionid which are userspace
> concepts that the kernel tracks for the convenience of userspace.

Ah, no. Loginuid identifies a user, which is a kernel concept in
that a user is defined by the uid. The session ID has well defined
kernel semantics. You're trying to say that the containerID is an
opaque value that is meaningless to the kernel, but you still want
the kernel to protect it. How can the kernel know if it is protecting
it correctly?

>   As
> for its name, I'm not particularly picky, so if you don't like
> CAP_CONTAINER_* then I'm fine with CAP_AUDIT_CONTAINERID.  It really
> needs to be distinct from CAP_AUDIT_WRITE and CAP_AUDIT_CONTROL since we
> don't want to give the ability to set a containerID to any process that
> is able to do audit logging (such as vsftpd) and similarly we don't want
> to give the orchestrator the ability to control the setup of the audit
> daemon.

Sorry, but what aspect of the kernel security policy is this
capability supposed to protect? That's what capabilities are
for, not the undefined support of undefined user-space behavior.

If it's audit behavior, you want CAP_AUDIT_CONTROL. If it's
more than audit behavior you have to define what system security
policy you're dealing with in order to pick the right capability.

We get this request pretty regularly. "I need my own capability
because I have a niche thing that isn't part of the system security
policy but that is important!" Fit the containerID into the
system security policy, and if that results in using CAP_SYS_ADMIN,
oh well.

>>>   At that time, record the target container's user-supplied
>>> container identifier along with the target container's first process
>>> (which may become the target container's "init" process) process ID
>>> (referenced from the initial PID namespace), all namespace IDs (in the
>>> form of a nsfs device number and inode number tuple) in a new auxilliary
>>> record AUDIT_CONTAINER with a qualifying op=$action field.
>>>
>>> Issue a new auxilliary record AUDIT_CONTAINER_INFO for each valid
>>> container ID present on an auditable action or event.
>>>
>>> Forked and cloned processes inherit their parent's container ID,
>>> referenced in the process' task_struct.
>>>
>>> Mimic setns(2) and return an error if the process has already initiated
>>> threading or forked since this registration should happen before the
>>> process execution is started by the orchestrator and hence should not
>>> yet have any threads or children.  If this is deemed overly restrictive,
>>> switch all threads and children to the new c

Re: RFC(v2): Audit Kernel Container IDs

2017-10-17 Thread Casey Schaufler
On 10/17/2017 5:31 AM, Simo Sorce wrote:
> On Mon, 2017-10-16 at 21:42 -0400, Steve Grubb wrote:
>> On Monday, October 16, 2017 8:33:40 PM EDT Richard Guy Briggs wrote:
>>> There is such a thing, but the kernel doesn't know about it
>>> yet.  This same situation exists for loginuid and sessionid which
>>> are userspace concepts that the kernel tracks for the convenience
>>> of userspace.  As for its name, I'm not particularly picky, so if
>>> you don't like CAP_CONTAINER_* then I'm fine with
>>> CAP_AUDIT_CONTAINERID.  It really needs to be distinct from
>>> CAP_AUDIT_WRITE and CAP_AUDIT_CONTROL since we don't want to give
>>> the ability to set a containerID to any process that is able to do
>>> audit logging (such as vsftpd) and similarly we don't want to give
>>> the orchestrator the ability to control the setup of the audit
>>> daemon.
>> A long time ago, we were debating what should guard against rouge
>> processes from setting the loginuid. Casey argued that the ability to
>> set the loginuid means they have the ability to control the audit
>> trail. That means that it should be guarded by CAP_AUDIT_CONTROL. I
>> think the same logic applies today. 
> The difference is that with loginuid you needed to give processes able
> to audit also the ability to change it. You do not want to tie the
> ability to change container ids to the ability to audit. You want to be
> able to do audit stuff (within the container) without allowing it to
> change the container id.

Without a *kernel* policy on containerIDs you can't say what
security policy is being exempted. Without that you can't say what
capability is (or isn't) appropriate. You need a reason to have
a capability check that makes sense in the context of the kernel
security policy. Since we don't know what a container is in the
kernel, that's pretty hard. We don't create "fuzzy" capabilities
based on the trendy application behavior of the moment. If the
behavior is not related it audit, there's no reason for it, and
if it is, CAP_AUDIT_CONTROL works just fine. If this doesn't work
in your application security model I suggest that is where you
need to make changes.


> Of course if we made container id a write-once property maybe there is
> no need for controls at all, but I'm pretty sure there will be
> situations where write-once may not be usable in practice.
>
>> The ability to arbitrarily set a container ID means the process has
>> the ability to indirectly control the audit trail.
> The container Id can be used also for authorization purposes (by other
> processes on the host), not just audit, I think this is why a separate
> control has been proposed.
>
> Simo.
>



Re: RFC(v2): Audit Kernel Container IDs

2017-10-17 Thread Casey Schaufler
On 10/17/2017 8:28 AM, Simo Sorce wrote:
> On Tue, 2017-10-17 at 07:59 -0700, Casey Schaufler wrote:
>> On 10/17/2017 5:31 AM, Simo Sorce wrote:
>>> On Mon, 2017-10-16 at 21:42 -0400, Steve Grubb wrote:
>>>> On Monday, October 16, 2017 8:33:40 PM EDT Richard Guy Briggs
>>>> wrote:
>>>>> There is such a thing, but the kernel doesn't know about it
>>>>> yet.  This same situation exists for loginuid and sessionid
>>>>> which
>>>>> are userspace concepts that the kernel tracks for the
>>>>> convenience
>>>>> of userspace.  As for its name, I'm not particularly picky, so
>>>>> if
>>>>> you don't like CAP_CONTAINER_* then I'm fine with
>>>>> CAP_AUDIT_CONTAINERID.  It really needs to be distinct from
>>>>> CAP_AUDIT_WRITE and CAP_AUDIT_CONTROL since we don't want to
>>>>> give
>>>>> the ability to set a containerID to any process that is able to
>>>>> do
>>>>> audit logging (such as vsftpd) and similarly we don't want to
>>>>> give
>>>>> the orchestrator the ability to control the setup of the audit
>>>>> daemon.
>>>> A long time ago, we were debating what should guard against rouge
>>>> processes from setting the loginuid. Casey argued that the
>>>> ability to
>>>> set the loginuid means they have the ability to control the audit
>>>> trail. That means that it should be guarded by CAP_AUDIT_CONTROL.
>>>> I
>>>> think the same logic applies today. 
>>> The difference is that with loginuid you needed to give processes
>>> able
>>> to audit also the ability to change it. You do not want to tie the
>>> ability to change container ids to the ability to audit. You want
>>> to be
>>> able to do audit stuff (within the container) without allowing it
>>> to
>>> change the container id.
>> Without a *kernel* policy on containerIDs you can't say what
>> security policy is being exempted.
> The policy has been basically stated earlier.

No. The expected user space behavior has been stated.

> A way to track a set of processes from a specific point in time
> forward. The name used is "container id", but it could be anything.

Then you want Jose Bollo's PTAGS. It's insane to add yet another
arbitrary ID to the task for a special purpose. Add a general tagging
mechanism instead. We could add a gazillion new id's, each with it's
own capability if we head down this road.

> This marker is mostly used by user space to track process hierarchies
> without races, these processes can be very privileged, and must not be
> allowed to change the marker themselves when granted the current common
> capabilities.

Let's be clear. What happens in user space stays in user space.
The kernel does not give a fig about user space policy. There has
to be a kernel policy involved that a capability can exempt.

> Is this a good enough description ? If not can you clarify your
> expectations ?

The kernel enforces kernel policy. Capabilities provide a mechanism
to mark a process as exempt from some aspect of kernel policy. If
you don't have a kernel policy, you don't get a capability. Clear?

>
>>  Without that you can't say what capability is (or isn't)
>> appropriate.
> See if the above is sufficient please.
>
>> You need a reason to have a capability check that makes sense in the
>> context of the kernel security policy.
> I think the proposal had a reason, we may debate on whether that reason
> is good enough.
>
>> Since we don't know what a container is in the kernel,
> Please do not fixate on the word container.
>
>>  that's pretty hard. We don't create "fuzzy" capabilities
>> based on the trendy application behavior of the moment. If the
>> behavior is not related it audit, there's no reason for it, and
>> if it is, CAP_AUDIT_CONTROL works just fine. If this doesn't work
>> in your application security model I suggest that is where you
>> need to make changes.
> The authors of the proposal came to the conclusion that kernel
> assistance is needed. It would be nice to discuss the merits of it.
> If you do not understand why the request has been made it would be more
> useful to ask specific questions to understand what and why is the ask.

I understand pretty darn well.

> Pushing back is fine, if you have understood the problem and have valid
> arguments against a kernel level solution (and possibly suggestions for
> a working user space solution), otherwise you are not adding value to
> the discussion.

The presumption is that the request is reasonable. Adding a capability
in support of an undefined behavior is unreasonable. Based on the discussion,
CAP_AUDIT_CONTROL is completely rational. I understand that it would be
difficult to support your application privilege model. I would like to look
into helping out with that, but have too many burning knives in the air
just now.

>
> Simo.
>



Re: RFC(v2): Audit Kernel Container IDs

2017-10-17 Thread Casey Schaufler
On 10/17/2017 8:44 AM, James Bottomley wrote:
> On Tue, 2017-10-17 at 11:28 -0400, Simo Sorce wrote:
>>> Without a *kernel* policy on containerIDs you can't say what
>>> security policy is being exempted.
>> The policy has been basically stated earlier.
>>
>> A way to track a set of processes from a specific point in time
>> forward. The name used is "container id", but it could be anything.
>> This marker is mostly used by user space to track process hierarchies
>> without races, these processes can be very privileged, and must not
>> be allowed to change the marker themselves when granted the current
>> common capabilities.
>>
>> Is this a good enough description ? If not can you clarify your
>> expectations ?
> I think you mean you want to be able to apply a label to a process
> which is inherited across forks.

That would be PTAGS. I agree that such a general mechanism
could be very useful for a variety of purposes, not just
containers. I do not agree that a single integer (e.g. a
containerID) warrants more than trivial mechanism.

> The label should only be susceptible
> to modification by something possessing a capability (which one TBD).

I think that the reason we're going to have crying and gnashing
of teeth is that whatever capability is used. There will always be
an issue of the capability granted being less specific than the
application security model would like.

And no, we're not going down the 330 capabilities road. It's been
done in the UNIX world. Application security models hate that
just as much as they hate the coarser granularity.

> The idea is that processes spawned into a container would be labelled
> by the container orchestration system.  It's unclear what should happen
> to processes using nsenter after the fact, but policy for that should
> be up to the orchestration system.

I'm fine with that. The user space policy can be anything y'all like.

> The label will be used as a tag for audit information.

Deep breath ...

Which *is* a kernel security policy mechanism. Since the "label"
is part of the audit information that the kernel is guaranteeing
changing it would be covered by CAP_AUDIT_CONTROL. If the kernel
does not use the "label" for any other purpose this is the only
capability that makes sense for it.

> I think you were missing label inheritance above.
>
> The security implications are that anything that can change the label
> could also hide itself and its doings from the audit system and thus
> would be used as a means to evade detection.  

Yes. This is a consequence of the capability granularity. There is
no way we can make the capability granularity sufficiently fine to
prevent this. No one wants the 330 capabilities that Data General
had in their secure UNIX system. 

> I actually think this
> means the label should be write once (once you've set it, you can't
> change it) and orchestration systems should begin as unlabelled
> processes allowing them to do arbitrary forks.
>
> For nested containers, I actually think the label should be
> hierarchical, so you can add a label for the new nested container but
> it still also contains its parents label as well.

You can't support this reasonably with a single containerID.
You want PTAGS for this. I know that there is resistance to
requiring anything beyond what's in the base kernel (and for
good reasons) for containers. Especially something that is
pending future work. But let's not jam something into the base
kernel that isn't really going to address the issue.

> James



Re: RFC(v2): Audit Kernel Container IDs

2017-10-19 Thread Casey Schaufler
On 10/18/2017 5:05 PM, Richard Guy Briggs wrote:
> On 2017-10-17 01:10, Casey Schaufler wrote:
>> On 10/16/2017 5:33 PM, Richard Guy Briggs wrote:
>>> On 2017-10-12 16:33, Casey Schaufler wrote:
>>>> On 10/12/2017 7:14 AM, Richard Guy Briggs wrote:
>>>>> Containers are a userspace concept.  The kernel knows nothing of them.
>>>>>
>>>>> The Linux audit system needs a way to be able to track the container
>>>>> provenance of events and actions.  Audit needs the kernel's help to do
>>>>> this.
>>>>>
>>>>> Since the concept of a container is entirely a userspace concept, a
>>>>> registration from the userspace container orchestration system initiates
>>>>> this.  This will define a point in time and a set of resources
>>>>> associated with a particular container with an audit container ID.
>>>>>
>>>>> The registration is a pseudo filesystem (proc, since PID tree already
>>>>> exists) write of a u8[16] UUID representing the container ID to a file
>>>>> representing a process that will become the first process in a new
>>>>> container.  This write might place restrictions on mount namespaces
>>>>> required to define a container, or at least careful checking of
>>>>> namespaces in the kernel to verify permissions of the orchestrator so it
>>>>> can't change its own container ID.  A bind mount of nsfs may be
>>>>> necessary in the container orchestrator's mntNS.
>>>>> Note: Use a 128-bit scalar rather than a string to make compares faster
>>>>> and simpler.
>>>>>
>>>>> Require a new CAP_CONTAINER_ADMIN to be able to carry out the
>>>>> registration.
>>>> Hang on. If containers are a user space concept, how can
>>>> you want CAP_CONTAINER_ANYTHING? If there's not such thing as
>>>> a container, how can you be asking for a capability to manage
>>>> them?
>>> There is such a thing, but the kernel doesn't know about it yet.
>> Then how can it be the kernel's place to control access to a
>> container resource, that is, the containerID.
> Ok, let me try to address your objections.
>
> The kernel can know enough that if it is already set to not allow it to
> be set again.  Or if the user doesn't have permission to set it that the
> user be denied this action.  How is this different from loginuid and
> sessionid?
>>>   This
>>> same situation exists for loginuid and sessionid which are userspace
>>> concepts that the kernel tracks for the convenience of userspace.
>> Ah, no. Loginuid identifies a user, which is a kernel concept in
>> that a user is defined by the uid.
> This simple explanation doesn't help me.  What makes that a kernel
> concept?  The fact that it is stored and compared in more than one
> place?
>
>> The session ID has well defined kernel semantics. You're trying to say
>> that the containerID is an opaque value that is meaningless to the
>> kernel, but you still want the kernel to protect it. How can the
>> kernel know if it is protecting it correctly?
> How so?  A userspace process triggers this.  Does the kernel know what
> these values mean?  Does it do anything with them other than report
> them or allow audit to filter them?  It is given some instructions on
> how to treat it.
>
> This is what we're trying to do with the containerID.
>
>>>   As
>>> for its name, I'm not particularly picky, so if you don't like
>>> CAP_CONTAINER_* then I'm fine with CAP_AUDIT_CONTAINERID.  It really
>>> needs to be distinct from CAP_AUDIT_WRITE and CAP_AUDIT_CONTROL since we
>>> don't want to give the ability to set a containerID to any process that
>>> is able to do audit logging (such as vsftpd) and similarly we don't want
>>> to give the orchestrator the ability to control the setup of the audit
>>> daemon.
>> Sorry, but what aspect of the kernel security policy is this
>> capability supposed to protect? That's what capabilities are
>> for, not the undefined support of undefined user-space behavior.
> Similarly, loginuids and sessionIDs are only used for audit tracking and
> filtering.

Tell me again why you're not reusing either of these?

>
>> If it's audit behavior, you want CAP_AUDIT_CONTROL. If it's
>> more than audit behavior you have to define what system security
>> policy you're dealing with in order to pick the right capability.

Re: Permissions for eBPF objects

2017-08-25 Thread Casey Schaufler
Adding the LSM list to the thread.

On 8/25/2017 11:01 AM, Jeffrey Vander Stoep via Selinux wrote:
> I’d like to get your thoughts on adding LSM permission checks on BPF objects.

Aside from the use of these objects requiring privilege,
what sort of controls do you think might be reasonable?
Who "owns" these objects? Can you have a coherent system
if one entity changes maps and another changes programs?
Why would "finer granularity" be better?

While I understand the issues with CAP_SYS_ADMIN being
uncomfortably general I am not the advocate of fine
grained controls that many of my peers and betters are.
Would the increased complexity add value? How?

> By default, the ability to create and use eBPF maps/programs requires
> CAP_SYS_ADMIN [1]. Alternatively, all processes can be granted access
> to bpf() functions. This seems like poor granularity. [2]

You could put mode bits on your maps, programs, functions.
Do you otherwise treat these as objects, or are the more
like process state?


> Like files and sockets, eBPF maps and programs can be passed between
> processes by FD and have a number of functions that map cleanly to
> permissions.
>
> Let me know what you think. Are there simpler alternative approaches
> that we haven’t considered?
>
> Thanks!
> Jeff
>
> [1] http://man7.org/linux/man-pages/man2/bpf.2.html NOTES section
> [2] We are considering eBPF for network filtering by netd. Giving netd
> CAP_SYS_ADMIN would considerably increase netd’s privileges.
> Alternatively allowing all processes permission to use bpf() goes
> against the principle of least privilege exposing a lot of kernel
> attack surface to processes that do not actually need it.

Just thinking out loud here, but if there is ownership on your
"objects" (objects have names, owners and access controls)
you could let the owner decide who gets to use them, just like
you do with user-space programs. This is kind of iffy for
programs that execute in the kernel, but you're already putting
a lot of trust in the eBPF implementation.

The big thing you need to do is define a security model, with
a list of subjects, objects and accesses. Once you have that
coming up with a basic access control policy is a matter of
creating something Linux-ish. The security modules will follow
on with their own interpretations of how to make it even better
in due course.



Re: [PATCH net-next v6 04/11] landlock: Add LSM hooks related to filesystem

2017-04-18 Thread Casey Schaufler
On 4/18/2017 3:44 PM, Mickaël Salaün wrote:
> On 19/04/2017 00:17, Kees Cook wrote:
>> On Tue, Mar 28, 2017 at 4:46 PM, Mickaël Salaün  wrote:
>>> Handle 33 filesystem-related LSM hooks for the Landlock filesystem
>>> event: LANDLOCK_SUBTYPE_EVENT_FS.
>>>
>>> A Landlock event wrap LSM hooks for similar kernel object types (e.g.
>>> struct file, struct path...). Multiple LSM hooks can trigger the same
>>> Landlock event.
>>>
>>> Landlock handle nine coarse-grained actions: read, write, execute, new,
>>> get, remove, ioctl, lock and fcntl. Each of them abstract LSM hook
>>> access control in a way that can be extended in the future.
>>>
>>> The Landlock LSM hook registration is done after other LSM to only run
>>> actions from user-space, via eBPF programs, if the access was granted by
>>> major (privileged) LSMs.
>>>
>>> Changes since v5:
>>> * split hooks.[ch] into hooks.[ch] and hooks_fs.[ch]
>>> * add more documentation
>>> * cosmetic fixes
>>>
>>> Changes since v4:
>>> * add LSM hook abstraction called Landlock event
>>>   * use the compiler type checking to verify hooks use by an event
>>>   * handle all filesystem related LSM hooks (e.g. file_permission,
>>> mmap_file, sb_mount...)
>>> * register BPF programs for Landlock just after LSM hooks registration
>>> * move hooks registration after other LSMs
>>> * add failsafes to check if a hook is not used by the kernel
>>> * allow partial raw value access form the context (needed for programs
>>>   generated by LLVM)
>>>
>>> Changes since v3:
>>> * split commit
>>> * add hooks dealing with struct inode and struct path pointers:
>>>   inode_permission and inode_getattr
>>> * add abstraction over eBPF helper arguments thanks to wrapping structs
>>>
>>> Signed-off-by: Mickaël Salaün 
>>> Cc: Alexei Starovoitov 
>>> Cc: Andy Lutomirski 
>>> Cc: Daniel Borkmann 
>>> Cc: David S. Miller 
>>> Cc: James Morris 
>>> Cc: Kees Cook 
>>> Cc: Serge E. Hallyn 
>>> ---
>>>  include/linux/lsm_hooks.h|   5 +
>>>  security/landlock/Makefile   |   4 +-
>>>  security/landlock/hooks.c| 115 +
>>>  security/landlock/hooks.h| 177 ++
>>>  security/landlock/hooks_fs.c | 563 
>>> +++
>>>  security/landlock/hooks_fs.h |  19 ++
>>>  security/landlock/init.c |  13 +
>>>  security/security.c  |   7 +-
>>>  8 files changed, 901 insertions(+), 2 deletions(-)
>>>  create mode 100644 security/landlock/hooks.c
>>>  create mode 100644 security/landlock/hooks.h
>>>  create mode 100644 security/landlock/hooks_fs.c
>>>  create mode 100644 security/landlock/hooks_fs.h
>>>
>>> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
>>> index e29d4c62a3c8..884289166a0e 100644
>>> --- a/include/linux/lsm_hooks.h
>>> +++ b/include/linux/lsm_hooks.h
>>> @@ -1920,5 +1920,10 @@ void __init loadpin_add_hooks(void);
>>>  #else
>>>  static inline void loadpin_add_hooks(void) { };
>>>  #endif
>>> +#ifdef CONFIG_SECURITY_LANDLOCK
>>> +extern void __init landlock_add_hooks(void);
>>> +#else
>>> +static inline void __init landlock_add_hooks(void) { }
>>> +#endif /* CONFIG_SECURITY_LANDLOCK */
>>>
>>>  #endif /* ! __LINUX_LSM_HOOKS_H */
>>> diff --git a/security/landlock/Makefile b/security/landlock/Makefile
>>> index 7205f9a7a2ee..c0db504a6335 100644
>>> --- a/security/landlock/Makefile
>>> +++ b/security/landlock/Makefile
>>> @@ -1,3 +1,5 @@
>>> +ccflags-$(CONFIG_SECURITY_LANDLOCK) += -Werror=unused-function
>> Why is this needed? If it can't be avoided, a comment should exist
>> here explaining why.
> This is useful to catch defined but unused hooks: error out if a
> HOOK_NEW_FS(foo) is not used with a HOOK_INIT_FS(foo) in the struct
> security_hook_list landlock_hooks.
>
>>> [...]
>>> @@ -127,3 +132,11 @@ static struct bpf_prog_type_list bpf_landlock_type 
>>> __ro_after_init = {
>>> .ops = &bpf_landlock_ops,
>>> .type = BPF_PROG_TYPE_LANDLOCK,
>>>  };
>>> +
>>> +void __init landlock_add_hooks(void)
>>> +{
>>> +   pr_info("landlock: Version %u", LANDLOCK_VERSION);
>>> +   landlock_add_hooks_fs();
>>> +   security_add_hooks(NULL, 0, "landlock");
>>> +   bpf_register_prog_type(&bpf_landlock_type);
>> I'm confused by the separation of hook registration here. The call to
>> security_add_hooks is with count=0 is especially weird. Why isn't this
>> just a single call with security_add_hooks(landlock_hooks,
>> ARRAY_SIZE(landlock_hooks), "landlock")?
> Yes, this is ugly with the new security_add_hooks() with three arguments
> but I wanted to split the hooks definition in multiple files.

Why? I'll buy a good argument, but there are dangers in
allowing multiple calls to security_add_hooks(). 

>
> The current security_add_hooks() use lsm_append(lsm, &lsm_names) which
> is not exported. Unfortunately, calling multiple security_add_hooks()
> with the same LSM name would register multiple names for the same LSM…
> Is it OK if I modify this function to not add duplicated entries?

It may s

Re: [kernel-hardening] Re: [PATCH net-next v6 04/11] landlock: Add LSM hooks related to filesystem

2017-04-19 Thread Casey Schaufler
On 4/19/2017 3:03 PM, Mickaël Salaün wrote:
> On 19/04/2017 01:40, Kees Cook wrote:
>> On Tue, Apr 18, 2017 at 4:16 PM, Casey Schaufler  
>> wrote:
>>> On 4/18/2017 3:44 PM, Mickaël Salaün wrote:
>>>> On 19/04/2017 00:17, Kees Cook wrote:
>>>>> On Tue, Mar 28, 2017 at 4:46 PM, Mickaël Salaün  wrote:
>>>>>> +void __init landlock_add_hooks(void)
>>>>>> +{
>>>>>> +   pr_info("landlock: Version %u", LANDLOCK_VERSION);
>>>>>> +   landlock_add_hooks_fs();
>>>>>> +   security_add_hooks(NULL, 0, "landlock");
>>>>>> +   bpf_register_prog_type(&bpf_landlock_type);
>>>>> I'm confused by the separation of hook registration here. The call to
>>>>> security_add_hooks is with count=0 is especially weird. Why isn't this
>>>>> just a single call with security_add_hooks(landlock_hooks,
>>>>> ARRAY_SIZE(landlock_hooks), "landlock")?
>>>> Yes, this is ugly with the new security_add_hooks() with three arguments
>>>> but I wanted to split the hooks definition in multiple files.
>>> Why? I'll buy a good argument, but there are dangers in
>>> allowing multiple calls to security_add_hooks().
> I prefer to have one file per hook "family" (e.g. filesystem, network,
> ptrace…). This reduce the mess with all the included files (needed for
> LSM hook argument types) and make the files easier to read, understand
> and maintain.

Yeah, there's that tradeoff and it really is a matter
of taste I suppose.

>>>> The current security_add_hooks() use lsm_append(lsm, &lsm_names) which
>>>> is not exported. Unfortunately, calling multiple security_add_hooks()
>>>> with the same LSM name would register multiple names for the same LSM…
>>>> Is it OK if I modify this function to not add duplicated entries?
>>> It may seem absurd, but it's conceivable that a module might
>>> have two hooks it wants called. My example is a module that
>>> counts the number of times SELinux denies a process access to
>>> things (which needs to be called before and after SELinux in
>>> order to detect denials) and takes "appropriate action" if
>>> too many denials occur. It would be weird, wonky and hackish,
>>> but that never stopped anybody before.
> Right, but now, with the new lsm_append(), module names are concatenated
> ("%s,%s") in the lsm_names variable. It would be nice to not pollute
> this string with multiple time the same module name.

All it would take is a check that the module name
isn't already on the list. It's a trivial change.

>> If ends up being sane and clear, I'm fine with allowing multiple calls.
>>
>> -Kees
>>



[PATCH v21 13/23] LSM: Ensure the correct LSM context releaser

2020-10-12 Thread Casey Schaufler
Add a new lsmcontext data structure to hold all the information
about a "security context", including the string, its size and
which LSM allocated the string. The allocation information is
necessary because LSMs have different policies regarding the
lifecycle of these strings. SELinux allocates and destroys
them on each use, whereas Smack provides a pointer to an entry
in a list that never goes away.

Reviewed-by: Kees Cook 
Reviewed-by: John Johansen 
Acked-by: Stephen Smalley 
Signed-off-by: Casey Schaufler 
Cc: linux-integr...@vger.kernel.org
Cc: netdev@vger.kernel.org
---
 drivers/android/binder.c| 10 ---
 fs/ceph/xattr.c |  6 -
 fs/nfs/nfs4proc.c   |  8 --
 fs/nfsd/nfs4xdr.c   |  7 +++--
 include/linux/security.h| 35 +++--
 include/net/scm.h   |  5 +++-
 kernel/audit.c  | 14 +++---
 kernel/auditsc.c| 12 ++---
 net/ipv4/ip_sockglue.c  |  4 ++-
 net/netfilter/nf_conntrack_netlink.c|  4 ++-
 net/netfilter/nf_conntrack_standalone.c |  4 ++-
 net/netfilter/nfnetlink_queue.c | 13 ++---
 net/netlabel/netlabel_unlabeled.c   | 19 +++---
 net/netlabel/netlabel_user.c|  4 ++-
 security/security.c | 11 
 15 files changed, 121 insertions(+), 35 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 1d9b0e385cd0..b0d9e9fad07a 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2861,6 +2861,7 @@ static void binder_transaction(struct binder_proc *proc,
int t_debug_id = atomic_inc_return(&binder_last_id);
char *secctx = NULL;
u32 secctx_sz = 0;
+   struct lsmcontext scaff; /* scaffolding */
 
e = binder_transaction_log_add(&binder_transaction_log);
e->debug_id = t_debug_id;
@@ -3163,7 +3164,8 @@ static void binder_transaction(struct binder_proc *proc,
t->security_ctx = 0;
WARN_ON(1);
}
-   security_release_secctx(secctx, secctx_sz);
+   lsmcontext_init(&scaff, secctx, secctx_sz, 0);
+   security_release_secctx(&scaff);
secctx = NULL;
}
t->buffer->debug_id = t->debug_id;
@@ -3496,8 +3498,10 @@ static void binder_transaction(struct binder_proc *proc,
binder_alloc_free_buf(&target_proc->alloc, t->buffer);
 err_binder_alloc_buf_failed:
 err_bad_extra_size:
-   if (secctx)
-   security_release_secctx(secctx, secctx_sz);
+   if (secctx) {
+   lsmcontext_init(&scaff, secctx, secctx_sz, 0);
+   security_release_secctx(&scaff);
+   }
 err_get_secctx_failed:
kfree(tcomplete);
binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c
index 3a733ac33d9b..27932f6b4cd6 100644
--- a/fs/ceph/xattr.c
+++ b/fs/ceph/xattr.c
@@ -1272,12 +1272,16 @@ int ceph_security_init_secctx(struct dentry *dentry, 
umode_t mode,
 
 void ceph_release_acl_sec_ctx(struct ceph_acl_sec_ctx *as_ctx)
 {
+#ifdef CONFIG_CEPH_FS_SECURITY_LABEL
+   struct lsmcontext scaff; /* scaffolding */
+#endif
 #ifdef CONFIG_CEPH_FS_POSIX_ACL
posix_acl_release(as_ctx->acl);
posix_acl_release(as_ctx->default_acl);
 #endif
 #ifdef CONFIG_CEPH_FS_SECURITY_LABEL
-   security_release_secctx(as_ctx->sec_ctx, as_ctx->sec_ctxlen);
+   lsmcontext_init(&scaff, as_ctx->sec_ctx, as_ctx->sec_ctxlen, 0);
+   security_release_secctx(&scaff);
 #endif
if (as_ctx->pagelist)
ceph_pagelist_release(as_ctx->pagelist);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index f8946b9468ef..28cc7944dd17 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -131,8 +131,12 @@ nfs4_label_init_security(struct inode *dir, struct dentry 
*dentry,
 static inline void
 nfs4_label_release_security(struct nfs4_label *label)
 {
-   if (label)
-   security_release_secctx(label->label, label->len);
+   struct lsmcontext scaff; /* scaffolding */
+
+   if (label) {
+   lsmcontext_init(&scaff, label->label, label->len, 0);
+   security_release_secctx(&scaff);
+   }
 }
 static inline u32 *nfs4_bitmask(struct nfs_server *server, struct nfs4_label 
*label)
 {
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 259d5ad0e3f4..0fc505392728 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2717,6 +2717,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh 
*fhp,
int err;
struct nfs4_acl *acl = NULL;
 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
+   struct lsmcontext scaff; /* scaffolding */
void *context = NULL;
int contextlen;

[PATCH v21 14/23] LSM: Use lsmcontext in security_secid_to_secctx

2020-10-12 Thread Casey Schaufler
Replace the (secctx,seclen) pointer pair with a single
lsmcontext pointer to allow return of the LSM identifier
along with the context and context length. This allows
security_release_secctx() to know how to release the
context. Callers have been modified to use or save the
returned data from the new structure.

Reviewed-by: Kees Cook 
Acked-by: Stephen Smalley 
Acked-by: Paul Moore 
Signed-off-by: Casey Schaufler 
Cc: netdev@vger.kernel.org
---
 drivers/android/binder.c| 26 +++-
 include/linux/security.h|  4 +--
 include/net/scm.h   |  9 ++
 kernel/audit.c  | 39 +++-
 kernel/auditsc.c| 31 +++
 net/ipv4/ip_sockglue.c  |  8 ++---
 net/netfilter/nf_conntrack_netlink.c| 18 +--
 net/netfilter/nf_conntrack_standalone.c |  7 ++---
 net/netfilter/nfnetlink_queue.c |  5 +++-
 net/netlabel/netlabel_unlabeled.c   | 40 -
 net/netlabel/netlabel_user.c|  7 ++---
 security/security.c | 10 +--
 12 files changed, 81 insertions(+), 123 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index b0d9e9fad07a..0bde1b96680e 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2859,9 +2859,7 @@ static void binder_transaction(struct binder_proc *proc,
binder_size_t last_fixup_min_off = 0;
struct binder_context *context = proc->context;
int t_debug_id = atomic_inc_return(&binder_last_id);
-   char *secctx = NULL;
-   u32 secctx_sz = 0;
-   struct lsmcontext scaff; /* scaffolding */
+   struct lsmcontext lsmctx = { };
 
e = binder_transaction_log_add(&binder_transaction_log);
e->debug_id = t_debug_id;
@@ -3115,14 +3113,14 @@ static void binder_transaction(struct binder_proc *proc,
size_t added_size;
 
security_task_getsecid(proc->tsk, &blob);
-   ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz);
+   ret = security_secid_to_secctx(&blob, &lsmctx);
if (ret) {
return_error = BR_FAILED_REPLY;
return_error_param = ret;
return_error_line = __LINE__;
goto err_get_secctx_failed;
}
-   added_size = ALIGN(secctx_sz, sizeof(u64));
+   added_size = ALIGN(lsmctx.len, sizeof(u64));
extra_buffers_size += added_size;
if (extra_buffers_size < added_size) {
/* integer overflow of extra_buffers_size */
@@ -3149,24 +3147,22 @@ static void binder_transaction(struct binder_proc *proc,
t->buffer = NULL;
goto err_binder_alloc_buf_failed;
}
-   if (secctx) {
+   if (lsmctx.context) {
int err;
size_t buf_offset = ALIGN(tr->data_size, sizeof(void *)) +
ALIGN(tr->offsets_size, sizeof(void *)) +
ALIGN(extra_buffers_size, sizeof(void *)) -
-   ALIGN(secctx_sz, sizeof(u64));
+   ALIGN(lsmctx.len, sizeof(u64));
 
t->security_ctx = (uintptr_t)t->buffer->user_data + buf_offset;
err = binder_alloc_copy_to_buffer(&target_proc->alloc,
  t->buffer, buf_offset,
- secctx, secctx_sz);
+ lsmctx.context, lsmctx.len);
if (err) {
t->security_ctx = 0;
WARN_ON(1);
}
-   lsmcontext_init(&scaff, secctx, secctx_sz, 0);
-   security_release_secctx(&scaff);
-   secctx = NULL;
+   security_release_secctx(&lsmctx);
}
t->buffer->debug_id = t->debug_id;
t->buffer->transaction = t;
@@ -3222,7 +3218,7 @@ static void binder_transaction(struct binder_proc *proc,
off_end_offset = off_start_offset + tr->offsets_size;
sg_buf_offset = ALIGN(off_end_offset, sizeof(void *));
sg_buf_end_offset = sg_buf_offset + extra_buffers_size -
-   ALIGN(secctx_sz, sizeof(u64));
+   ALIGN(lsmctx.len, sizeof(u64));
off_min = 0;
for (buffer_offset = off_start_offset; buffer_offset < off_end_offset;
 buffer_offset += sizeof(binder_size_t)) {
@@ -3498,10 +3494,8 @@ static void binder_transaction(struct binder_proc *proc,
binder_alloc_free_buf(&target_proc->alloc, t->buffer);
 err_binder_alloc_buf_failed:
 err_bad_extra_size:
-   if (secctx) {
- 

[PATCH v21 16/23] LSM: security_secid_to_secctx in netlink netfilter

2020-10-12 Thread Casey Schaufler
Change netlink netfilter interfaces to use lsmcontext
pointers, and remove scaffolding.

Reviewed-by: Kees Cook 
Reviewed-by: John Johansen 
Acked-by: Stephen Smalley 
Signed-off-by: Casey Schaufler 
Cc: netdev@vger.kernel.org
Cc: netfilter-de...@vger.kernel.org
---
 net/netfilter/nfnetlink_queue.c | 37 +
 1 file changed, 14 insertions(+), 23 deletions(-)

diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 84be5a49a157..0d8b83d84422 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -301,15 +301,13 @@ static int nfqnl_put_sk_uidgid(struct sk_buff *skb, 
struct sock *sk)
return -1;
 }
 
-static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata)
+static void nfqnl_get_sk_secctx(struct sk_buff *skb, struct lsmcontext 
*context)
 {
-   u32 seclen = 0;
 #if IS_ENABLED(CONFIG_NETWORK_SECMARK)
struct lsmblob blob;
-   struct lsmcontext context = { };
 
if (!skb || !sk_fullsock(skb->sk))
-   return 0;
+   return;
 
read_lock_bh(&skb->sk->sk_callback_lock);
 
@@ -318,14 +316,12 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char 
**secdata)
 * blob. security_secid_to_secctx() will know which security
 * module to use to create the secctx.  */
lsmblob_init(&blob, skb->secmark);
-   security_secid_to_secctx(&blob, &context);
-   *secdata = context.context;
+   security_secid_to_secctx(&blob, context);
}
 
read_unlock_bh(&skb->sk->sk_callback_lock);
-   seclen = context.len;
 #endif
-   return seclen;
+   return;
 }
 
 static u32 nfqnl_get_bridge_size(struct nf_queue_entry *entry)
@@ -398,12 +394,10 @@ nfqnl_build_packet_message(struct net *net, struct 
nfqnl_instance *queue,
struct net_device *indev;
struct net_device *outdev;
struct nf_conn *ct = NULL;
+   struct lsmcontext context = { };
enum ip_conntrack_info ctinfo;
struct nfnl_ct_hook *nfnl_ct;
bool csum_verify;
-   struct lsmcontext scaff; /* scaffolding */
-   char *secdata = NULL;
-   u32 seclen = 0;
 
size = nlmsg_total_size(sizeof(struct nfgenmsg))
+ nla_total_size(sizeof(struct nfqnl_msg_packet_hdr))
@@ -469,9 +463,9 @@ nfqnl_build_packet_message(struct net *net, struct 
nfqnl_instance *queue,
}
 
if ((queue->flags & NFQA_CFG_F_SECCTX) && entskb->sk) {
-   seclen = nfqnl_get_sk_secctx(entskb, &secdata);
-   if (seclen)
-   size += nla_total_size(seclen);
+   nfqnl_get_sk_secctx(entskb, &context);
+   if (context.len)
+   size += nla_total_size(context.len);
}
 
skb = alloc_skb(size, GFP_ATOMIC);
@@ -604,7 +598,8 @@ nfqnl_build_packet_message(struct net *net, struct 
nfqnl_instance *queue,
nfqnl_put_sk_uidgid(skb, entskb->sk) < 0)
goto nla_put_failure;
 
-   if (seclen && nla_put(skb, NFQA_SECCTX, seclen, secdata))
+   if (context.len &&
+   nla_put(skb, NFQA_SECCTX, context.len, context.context))
goto nla_put_failure;
 
if (ct && nfnl_ct->build(skb, ct, ctinfo, NFQA_CT, NFQA_CT_INFO) < 0)
@@ -632,10 +627,8 @@ nfqnl_build_packet_message(struct net *net, struct 
nfqnl_instance *queue,
}
 
nlh->nlmsg_len = skb->len;
-   if (seclen) {
-   lsmcontext_init(&scaff, secdata, seclen, 0);
-   security_release_secctx(&scaff);
-   }
+   if (context.len)
+   security_release_secctx(&context);
return skb;
 
 nla_put_failure:
@@ -643,10 +636,8 @@ nfqnl_build_packet_message(struct net *net, struct 
nfqnl_instance *queue,
kfree_skb(skb);
net_err_ratelimited("nf_queue: error creating packet message\n");
 nlmsg_failure:
-   if (seclen) {
-   lsmcontext_init(&scaff, secdata, seclen, 0);
-   security_release_secctx(&scaff);
-   }
+   if (context.len)
+   security_release_secctx(&context);
return NULL;
 }
 
-- 
2.24.1



[PATCH v21 17/23] NET: Store LSM netlabel data in a lsmblob

2020-10-12 Thread Casey Schaufler
Netlabel uses LSM interfaces requiring an lsmblob and
the internal storage is used to pass information between
these interfaces, so change the internal data from a secid
to a lsmblob. Update the netlabel interfaces and their
callers to accommodate the change. This requires that the
modules using netlabel use the lsm_id.slot to access the
correct secid when using netlabel.

Reviewed-by: Kees Cook 
Reviewed-by: John Johansen 
Acked-by: Stephen Smalley 
Acked-by: Paul Moore 
Signed-off-by: Casey Schaufler 
Cc: netdev@vger.kernel.org
---
 include/net/netlabel.h  |  8 +--
 net/ipv4/cipso_ipv4.c   | 26 ++
 net/netlabel/netlabel_kapi.c|  6 +--
 net/netlabel/netlabel_unlabeled.c   | 79 +
 net/netlabel/netlabel_unlabeled.h   |  2 +-
 security/selinux/hooks.c|  2 +-
 security/selinux/include/security.h |  1 +
 security/selinux/netlabel.c |  2 +-
 security/selinux/ss/services.c  |  4 +-
 security/smack/smack.h  |  1 +
 security/smack/smack_lsm.c  |  5 +-
 security/smack/smackfs.c| 10 ++--
 12 files changed, 64 insertions(+), 82 deletions(-)

diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index 43ae50337685..73fc25b4042b 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -166,7 +166,7 @@ struct netlbl_lsm_catmap {
  * @attr.mls: MLS sensitivity label
  * @attr.mls.cat: MLS category bitmap
  * @attr.mls.lvl: MLS sensitivity level
- * @attr.secid: LSM specific secid token
+ * @attr.lsmblob: LSM specific data
  *
  * Description:
  * This structure is used to pass security attributes between NetLabel and the
@@ -201,7 +201,7 @@ struct netlbl_lsm_secattr {
struct netlbl_lsm_catmap *cat;
u32 lvl;
} mls;
-   u32 secid;
+   struct lsmblob lsmblob;
} attr;
 };
 
@@ -415,7 +415,7 @@ int netlbl_cfg_unlbl_static_add(struct net *net,
const void *addr,
const void *mask,
u16 family,
-   u32 secid,
+   struct lsmblob *lsmblob,
struct netlbl_audit *audit_info);
 int netlbl_cfg_unlbl_static_del(struct net *net,
const char *dev_name,
@@ -523,7 +523,7 @@ static inline int netlbl_cfg_unlbl_static_add(struct net 
*net,
  const void *addr,
  const void *mask,
  u16 family,
- u32 secid,
+ struct lsmblob *lsmblob,
  struct netlbl_audit *audit_info)
 {
return -ENOSYS;
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index 2eb71579f4d2..eb84d7fede17 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -106,15 +106,17 @@ int cipso_v4_rbm_strictvalid = 1;
 /* Base length of the local tag (non-standard tag).
  *  Tag definition (may change between kernel versions)
  *
- * 0  8  16 24 32
- * +--+--+--+--+
- * | 1000 | 0110 | 32-bit secid value  |
- * +--+--+--+--+
- * | in (host byte order)|
- * +--+--+
- *
+ * 0  8  1616 + sizeof(struct lsmblob)
+ * +--+--+-+
+ * | 1000 | 0110 | LSM blob data   |
+ * +--+--+-+
+ *
+ * All secid and flag fields are in host byte order.
+ * The lsmblob structure size varies depending on which
+ * Linux security modules are built in the kernel.
+ * The data is opaque.
  */
-#define CIPSO_V4_TAG_LOC_BLEN 6
+#define CIPSO_V4_TAG_LOC_BLEN (2 + sizeof(struct lsmblob))
 
 /*
  * Helper Functions
@@ -1469,7 +1471,11 @@ static int cipso_v4_gentag_loc(const struct cipso_v4_doi 
*doi_def,
 
buffer[0] = CIPSO_V4_TAG_LOCAL;
buffer[1] = CIPSO_V4_TAG_LOC_BLEN;
-   *(u32 *)&buffer[2] = secattr->attr.secid;
+   /* Ensure that there is sufficient space in the CIPSO header
+* for the LSM data. */
+   BUILD_BUG_ON(CIPSO_V4_TAG_LOC_BLEN > CIPSO_V4_OPT_LEN_MAX);
+   memcpy(&buffer[2], &secattr->attr.lsmblob,
+  sizeof(secattr->attr.lsmblob));
 
return CIPSO_V4_TAG_LOC_BLEN;
 }
@@ -1489,7 +1495,7 @@ static int cipso_v4_parsetag_loc(const struct 
cipso_v4_doi *doi_def,
 const unsigned char *tag,
 struct netlbl_lsm_secattr *secattr)
 {
-   secattr->attr.secid = *(u32 *)&tag[2];
+   memcpy(&secattr->attr.lsmblob, &tag[2], sizeof(secattr->attr.lsmblob));
 

Re: [PATCH 1/2] rtnetlink: gate MAC address with an LSM hook

2019-08-21 Thread Casey Schaufler
On 8/21/2019 6:45 AM, Jeff Vander Stoep wrote:
> MAC addresses are often considered sensitive because they are
> usually unique and can be used to identify/track a device or
> user [1].
>
> The MAC address is accessible via the RTM_NEWLINK message type of a
> netlink route socket[2]. Ideally we could grant/deny access to the
> MAC address on a case-by-case basis without blocking the entire
> RTM_NEWLINK message type which contains a lot of other useful
> information. This can be achieved using a new LSM hook on the netlink
> message receive path. Using this new hook, individual LSMs can select
> which processes are allowed access to the real MAC, otherwise a
> default value of zeros is returned. Offloading access control
> decisions like this to an LSM is convenient because it preserves the
> status quo for most Linux users while giving the various LSMs
> flexibility to make finer grained decisions on access to sensitive
> data based on policy.

Is the MAC address the only bit of skb data that you might
want to control with MAC? ( Sorry, couldn't help it ;) )
Just musing, but might it make more sense to leave the core
code unmodified and clear the MAC address in the skb inside
the LSM? If you did it that way you could address any other
data you want to control using the same hook. I would hate
to see separate LSM hooks for each of several bits of data. 
On the other hand, I wouldn't want you to violate any layering
policies in the networking code. That would be wrong.

>
> [1] https://adamdrake.com/mac-addresses-udids-and-privacy.html
> [2] Other access vectors like ioctl(SIOCGIFHWADDR) are already covered
> by existing LSM hooks.
>
> Signed-off-by: Jeff Vander Stoep 
> ---
>  include/linux/lsm_hooks.h |  8 
>  include/linux/security.h  |  6 ++
>  net/core/rtnetlink.c  | 12 ++--
>  security/security.c   |  5 +
>  4 files changed, 29 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index df1318d85f7d..dfcb2e11ff43 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -728,6 +728,12 @@
>   *
>   * Security hooks for Netlink messaging.
>   *
> + * @netlink_receive
> + *   Check permissions on a netlink message field before populating it.
> + *   @sk associated sock of task receiving the message.
> + *   @skb contains the sk_buff structure for the netlink message.
> + *   Return 0 if the data should be included in the message.
> + *
>   * @netlink_send:
>   *   Save security information for a netlink message so that permission
>   *   checking can be performed when the message is processed.  The security
> @@ -1673,6 +1679,7 @@ union security_list_options {
>   int (*sem_semop)(struct kern_ipc_perm *perm, struct sembuf *sops,
>   unsigned nsops, int alter);
>  
> + int (*netlink_receive)(struct sock *sk, struct sk_buff *skb);
>   int (*netlink_send)(struct sock *sk, struct sk_buff *skb);
>  
>   void (*d_instantiate)(struct dentry *dentry, struct inode *inode);
> @@ -1952,6 +1959,7 @@ struct security_hook_heads {
>   struct hlist_head sem_associate;
>   struct hlist_head sem_semctl;
>   struct hlist_head sem_semop;
> + struct hlist_head netlink_receive;
>   struct hlist_head netlink_send;
>   struct hlist_head d_instantiate;
>   struct hlist_head getprocattr;
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 5f7441abbf42..46b5af6de59e 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -382,6 +382,7 @@ int security_getprocattr(struct task_struct *p, const 
> char *lsm, char *name,
>char **value);
>  int security_setprocattr(const char *lsm, const char *name, void *value,
>size_t size);
> +int security_netlink_receive(struct sock *sk, struct sk_buff *skb);
>  int security_netlink_send(struct sock *sk, struct sk_buff *skb);
>  int security_ismaclabel(const char *name);
>  int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
> @@ -1162,6 +1163,11 @@ static inline int security_setprocattr(const char 
> *lsm, char *name,
>   return -EINVAL;
>  }
>  
> +static inline int security_netlink_receive(struct sock *sk, struct sk_buff 
> *skb)
> +{
> + return 0;
> +}
> +
>  static inline int security_netlink_send(struct sock *sk, struct sk_buff *skb)
>  {
>   return 0;
> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
> index 1ee6460f8275..7d69fcb8d22e 100644
> --- a/net/core/rtnetlink.c
> +++ b/net/core/rtnetlink.c
> @@ -1650,8 +1650,16 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb,
>   goto nla_put_failure;
>  
>   if (dev->addr_len) {
> - if (nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr) ||
> - nla_put(skb, IFLA_BROADCAST, dev->addr_len, dev->broadcast))
> + if (skb->sk && security_netlink_receive(skb->sk, skb)) {
> +  

Re: New skb extension for use by LSMs (skb "security blob")?

2019-08-22 Thread Casey Schaufler
On 8/21/2019 8:54 PM, David Miller wrote:
> From: Paul Moore 
> Date: Wed, 21 Aug 2019 23:27:03 -0400
>
>> On Wed, Aug 21, 2019 at 6:50 PM David Miller  wrote:
>>> From: Paul Moore 
>>> Date: Wed, 21 Aug 2019 18:00:09 -0400
>>>
 I was just made aware of the skb extension work, and it looks very
 appealing from a LSM perspective.  As some of you probably remember,
 we (the LSM folks) have wanted a proper security blob in the skb for
 quite some time, but netdev has been resistant to this idea thus far.

 If I were to propose a patchset to add a SKB_EXT_SECURITY skb
 extension (a single extension ID to be shared among the different
 LSMs), would that be something that netdev would consider merging, or
 is there still a philosophical objection to things like this?
>>> Unlike it's main intended user (MPTCP), it sounds like LSM's would use
>>> this in a way such that it would be enabled on most systems all the
>>> time.

Only SELinux and Smack use the networking hooks today,
although I understand that AppArmor has plans to do so
in the not too distant future. Smack enables labeled
networking at all times. While Smack doesn't have the
expansive use that SELinux does because of Android, it
is used extensively in embedded systems via Tizen and
Yocto Project deployments.

>>> That really defeats the whole purpose of making it dynamic. :-/

It argues that fulfilling the needs of LSMs ought to be a basic
feature of the skb, rather than a dynamic extension. When LSMs were
introduced 20 years ago it was assumed their use would be rare, and
it was. Today almost all Linux systems use LSMs, and once AppArmor
adds network labeling it will be quite difficult to find a major
distribution that doesn't need the support.

>> I would be okay with only adding a skb extension when we needed it,
>> which I'm currently thinking would only be when we had labeled
>> networking actually configured at runtime and not just built into the
>> kernel.  In SELinux we do something similar today when it comes to our
>> per-packet access controls; if labeled networking is not configured we
>> bail out of the LSM hooks early to improve performance (we would just
>> be comparing unlabeled_t to unlabeled_t anyway).  I think the other
>> LSMs would be okay with this usage as well.

Smack uses labeled (CIPSO now, CALIPSO 'soon') networking by default
and depends on it heavily for basic system policy enforcement.

>> While a number of distros due enable some form of LSM and the labeled
>> networking bits at build time, vary few (if any?) provide a default
>> configuration so I would expect no additional overhead in the common
>> case.

Tizen isn't a distro, but neither is Android.

>> Would that be acceptable?
> I honestly don't know, I kinda feared that once the SKB extension went in
> people would start dumping things there and that's exactly what's happening.

As Paul has mentioned, the LSM community (Paul and me in particular)
have been looking for a better way to deal with the network stack
for a long time.

> I just so happened to be reviewing:
>
>   https://patchwork.ozlabs.org/patch/1150091/
>
> while you were writing this email.
>
> It's rediculous, the vultures are out.



Re: New skb extension for use by LSMs (skb "security blob")?

2019-08-22 Thread Casey Schaufler
On 8/22/2019 9:32 AM, Paul Moore wrote:
> On Thu, Aug 22, 2019 at 3:03 AM Florian Westphal  wrote:
>> Paul Moore  wrote:
>>> Hello netdev,
>>>
>>> I was just made aware of the skb extension work, and it looks very
>>> appealing from a LSM perspective.  As some of you probably remember,
>>> we (the LSM folks) have wanted a proper security blob in the skb for
>>> quite some time, but netdev has been resistant to this idea thus far.
>> Is that "blob" in addition to skb->secmark, or a replacement?
> That's a good question.  While I thought about that, I wasn't sure if
> that was worth bringing up as previous attempts to trade the secmark
> field for a void pointer met with failure.  Last time I played with it
> I was able to take the additional 32-bits from holes in the skb, and
> possibly even improve some of the cacheline groupings (but that is
> always going to be a dependent on use case I think), but that wasn't
> enough.
>
> I think we could consider freeing up the secmark in the main skb, and
> move it to a skb extension, but this would potentially increase the
> chances that we would need to add an extension to a skb.  I don't have
> any hard numbers, but based on discussions and questions I suspect
> Secmark is more widely used than NetLabel and/or labeled IPsec;
> although I'm confident it is still a minor percentage of the overall
> Linux installed base.

Smack uses both extensively. As far as Smack is concerned giving up
the secmark for a blob would be just fine.

I am also working on security module stacking, and a blob in the
skb would dramatically improve the options for making that work
rationally.

> For me the big question is what would it take for us to get a security
> blob associated with the skb?  Would moving the secmark into the skb
> extension be enough?  Something else?  Or is this simply never going
> to happen?  I want to remain optimistic, but I've been trying for this
> off-and-on for over a decade and keep running into a brick wall ;)

Given that the original objection to using a skb extension for a
security blob was that an extension is dynamic, and that the ubiquitous
nature of LSM use makes that unreasonable, it would seem that supporting
the security blob as a basic part if the skb would be the obvious and
correct solution. If the normal case is that there is an LSM that would
befit from the native (unextended) support of a blob, it would seem
that that is the case that should be optimized.




Re: New skb extension for use by LSMs (skb "security blob")?

2019-08-22 Thread Casey Schaufler
On 8/22/2019 1:15 PM, Florian Westphal wrote:
> Casey Schaufler  wrote:
>> Given that the original objection to using a skb extension for a
>> security blob was that an extension is dynamic, and that the ubiquitous
>> nature of LSM use makes that unreasonable, it would seem that supporting
>> the security blob as a basic part if the skb would be the obvious and
>> correct solution. If the normal case is that there is an LSM that would
>> befit from the native (unextended) support of a blob, it would seem
>> that that is the case that should be optimized.
> What is this "blob"? i.e., what would you like to add to sk_buff to make
> whatever use cases you have in mind work?

In LSM terminology a blob is a set of data managed and used by
the LSM (either in the infrastructure or the security module).
Blob pointers are included in the system data structures to which
they relate. The inode has an i_security field, which is a void *.
If the secmark where replaced by a security blob, the u32 secmark field
in an sk_buff would be replaced by a void * security field.




Re: New skb extension for use by LSMs (skb "security blob")?

2019-08-22 Thread Casey Schaufler
On 8/22/2019 2:18 PM, David Miller wrote:
> From: Casey Schaufler 
> Date: Thu, 22 Aug 2019 13:35:01 -0700
>
>> If the secmark where replaced by a security blob, the u32 secmark field
>> in an sk_buff would be replaced by a void * security field.
> You can already use the secmark to hash to some kind of pointer or other
> object.

Would you really want that used in the most common configuration?
Sure, you *can* do that, but it would be insane to do so.



Re: New skb extension for use by LSMs (skb "security blob")?

2019-08-22 Thread Casey Schaufler
On 8/22/2019 3:28 PM, David Miller wrote:
> From: Casey Schaufler 
> Date: Thu, 22 Aug 2019 14:59:37 -0700
>
>> Sure, you *can* do that, but it would be insane to do so.
> We look up the neighbour table entries on every single packet we
> transmit from the kernel in the same exact way.
>
> And it was exactly to get rid of a pointer in a data structure.

I very much expect that the lifecycle management issues would
be completely different, but I'll admit to having little understanding
of the details of the neighbour table.



Re: New skb extension for use by LSMs (skb "security blob")?

2019-08-23 Thread Casey Schaufler
On 8/22/2019 3:36 PM, David Miller wrote:
> From: Casey Schaufler 
> Date: Thu, 22 Aug 2019 15:34:44 -0700
>
>> On 8/22/2019 3:28 PM, David Miller wrote:
>>> From: Casey Schaufler 
>>> Date: Thu, 22 Aug 2019 14:59:37 -0700
>>>
>>>> Sure, you *can* do that, but it would be insane to do so.
>>> We look up the neighbour table entries on every single packet we
>>> transmit from the kernel in the same exact way.
>>>
>>> And it was exactly to get rid of a pointer in a data structure.
>> I very much expect that the lifecycle management issues would
>> be completely different, but I'll admit to having little understanding
>> of the details of the neighbour table.
> Neighbour table entries can live anywhere from essentially forever down
> to several microseconds.
>
> If your hash is good, and you use RCU locking on the read side, it's a
> single pointer dereference in cost.

The secmark is the data used by the netfilter system.
While it would be (Turing compatible, after all) possible,
we're talking multiple attributes with different lifecycles
being managed in a table (list, whatever) that may expand
explosively. Using a single ID to reference into a table that
could contain:
secmark from iptables for SELinux
secmark from iptables for AppArmor
SELinux secid/context for the packet
AppArmor secid/context for the packet
will be hairy. In the netfilter processing we may have to
allocate a new table entry. There's no way to identify that
the entry is no longer necessary, as there is no lifecycle
on a secmark. Is it possible to come up with something that
will limp along? Possibly. If there's a blob pointer, we know
how to do all this effectively.




[PATCH v17 05/23] net: Prepare UDS for security module stacking

2020-05-14 Thread Casey Schaufler
Change the data used in UDS SO_PEERSEC processing from a
secid to a more general struct lsmblob. Update the
security_socket_getpeersec_dgram() interface to use the
lsmblob. There is a small amount of scaffolding code
that will come out when the security_secid_to_secctx()
code is brought in line with the lsmblob.

The secid field of the unix_skb_parms structure has been
replaced with a pointer to an lsmblob structure, and the
lsmblob is allocated as needed. This is similar to how the
list of passed files is managed. While an lsmblob structure
will fit in the available space today, there is no guarantee
that the addition of other data to the unix_skb_parms or
support for additional security modules wouldn't exceed what
is available.

Reviewed-by: Kees Cook 
Signed-off-by: Casey Schaufler 
cc: netdev@vger.kernel.org
---
 include/linux/security.h |  7 +--
 include/net/af_unix.h|  2 +-
 include/net/scm.h|  8 +---
 net/ipv4/ip_sockglue.c   |  8 +---
 net/unix/af_unix.c   |  7 ---
 net/unix/scm.c   |  6 ++
 security/security.c  | 18 +++---
 7 files changed, 41 insertions(+), 15 deletions(-)

diff --git a/include/linux/security.h b/include/linux/security.h
index 453737cefe09..2715b8dd115e 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1357,7 +1357,8 @@ int security_socket_shutdown(struct socket *sock, int 
how);
 int security_sock_rcv_skb(struct sock *sk, struct sk_buff *skb);
 int security_socket_getpeersec_stream(struct socket *sock, char __user *optval,
  int __user *optlen, unsigned len);
-int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, 
u32 *secid);
+int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb,
+struct lsmblob *blob);
 int security_sk_alloc(struct sock *sk, int family, gfp_t priority);
 void security_sk_free(struct sock *sk);
 void security_sk_clone(const struct sock *sk, struct sock *newsk);
@@ -1495,7 +1496,9 @@ static inline int 
security_socket_getpeersec_stream(struct socket *sock, char __
return -ENOPROTOOPT;
 }
 
-static inline int security_socket_getpeersec_dgram(struct socket *sock, struct 
sk_buff *skb, u32 *secid)
+static inline int security_socket_getpeersec_dgram(struct socket *sock,
+  struct sk_buff *skb,
+  struct lsmblob *blob)
 {
return -ENOPROTOOPT;
 }
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index f42fdddecd41..e99c84677e14 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -36,7 +36,7 @@ struct unix_skb_parms {
kgid_t  gid;
struct scm_fp_list  *fp;/* Passed files */
 #ifdef CONFIG_SECURITY_NETWORK
-   u32 secid;  /* Security ID  */
+   struct lsmblob  *lsmdata;   /* Security LSM data*/
 #endif
u32 consumed;
 } __randomize_layout;
diff --git a/include/net/scm.h b/include/net/scm.h
index 1ce365f4c256..e2e71c4bf9d0 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -33,7 +33,7 @@ struct scm_cookie {
struct scm_fp_list  *fp;/* Passed files */
struct scm_credscreds;  /* Skb credentials  */
 #ifdef CONFIG_SECURITY_NETWORK
-   u32 secid;  /* Passed security ID   */
+   struct lsmblob  lsmblob;/* Passed LSM data  */
 #endif
 };
 
@@ -46,7 +46,7 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl);
 #ifdef CONFIG_SECURITY_NETWORK
 static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct 
scm_cookie *scm)
 {
-   security_socket_getpeersec_dgram(sock, NULL, &scm->secid);
+   security_socket_getpeersec_dgram(sock, NULL, &scm->lsmblob);
 }
 #else
 static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct 
scm_cookie *scm)
@@ -97,7 +97,9 @@ static inline void scm_passec(struct socket *sock, struct 
msghdr *msg, struct sc
int err;
 
if (test_bit(SOCK_PASSSEC, &sock->flags)) {
-   err = security_secid_to_secctx(scm->secid, &secdata, &seclen);
+   /* Scaffolding - it has to be element 0 for now */
+   err = security_secid_to_secctx(scm->lsmblob.secid[0],
+  &secdata, &seclen);
 
if (!err) {
put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, 
secdata);
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index aa3fd61818c4..6cf57d5ac899 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -130,15 +130,17 @@ static void ip_cmsg_recv_checksum(struct msghdr *msg, 
struct sk_buff *skb,
 
 static void ip_cmsg_recv_security(struct msghdr *msg

[PATCH v17 14/23] LSM: Ensure the correct LSM context releaser

2020-05-14 Thread Casey Schaufler
Add a new lsmcontext data structure to hold all the information
about a "security context", including the string, its size and
which LSM allocated the string. The allocation information is
necessary because LSMs have different policies regarding the
lifecycle of these strings. SELinux allocates and destroys
them on each use, whereas Smack provides a pointer to an entry
in a list that never goes away.

Reviewed-by: Kees Cook 
Reviewed-by: John Johansen 
Acked-by: Stephen Smalley 
Signed-off-by: Casey Schaufler 
Cc: linux-integr...@vger.kernel.org
Cc: netdev@vger.kernel.org
---
 drivers/android/binder.c| 10 ---
 fs/ceph/xattr.c |  6 -
 fs/nfs/nfs4proc.c   |  8 --
 fs/nfsd/nfs4xdr.c   |  7 +++--
 include/linux/security.h| 35 +++--
 include/net/scm.h   |  5 +++-
 kernel/audit.c  | 14 +++---
 kernel/auditsc.c| 12 ++---
 net/ipv4/ip_sockglue.c  |  4 ++-
 net/netfilter/nf_conntrack_netlink.c|  4 ++-
 net/netfilter/nf_conntrack_standalone.c |  4 ++-
 net/netfilter/nfnetlink_queue.c | 13 ++---
 net/netlabel/netlabel_unlabeled.c   | 19 +++---
 net/netlabel/netlabel_user.c|  4 ++-
 security/security.c | 11 
 15 files changed, 121 insertions(+), 35 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index b6f22979a1db..30e59b386ce2 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2863,6 +2863,7 @@ static void binder_transaction(struct binder_proc *proc,
int t_debug_id = atomic_inc_return(&binder_last_id);
char *secctx = NULL;
u32 secctx_sz = 0;
+   struct lsmcontext scaff; /* scaffolding */
 
e = binder_transaction_log_add(&binder_transaction_log);
e->debug_id = t_debug_id;
@@ -3159,7 +3160,8 @@ static void binder_transaction(struct binder_proc *proc,
t->security_ctx = 0;
WARN_ON(1);
}
-   security_release_secctx(secctx, secctx_sz);
+   lsmcontext_init(&scaff, secctx, secctx_sz, 0);
+   security_release_secctx(&scaff);
secctx = NULL;
}
t->buffer->debug_id = t->debug_id;
@@ -3492,8 +3494,10 @@ static void binder_transaction(struct binder_proc *proc,
binder_alloc_free_buf(&target_proc->alloc, t->buffer);
 err_binder_alloc_buf_failed:
 err_bad_extra_size:
-   if (secctx)
-   security_release_secctx(secctx, secctx_sz);
+   if (secctx) {
+   lsmcontext_init(&scaff, secctx, secctx_sz, 0);
+   security_release_secctx(&scaff);
+   }
 err_get_secctx_failed:
kfree(tcomplete);
binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c
index 7b8a070a782d..9bf41894e3e1 100644
--- a/fs/ceph/xattr.c
+++ b/fs/ceph/xattr.c
@@ -1272,12 +1272,16 @@ int ceph_security_init_secctx(struct dentry *dentry, 
umode_t mode,
 
 void ceph_release_acl_sec_ctx(struct ceph_acl_sec_ctx *as_ctx)
 {
+#ifdef CONFIG_CEPH_FS_SECURITY_LABEL
+   struct lsmcontext scaff; /* scaffolding */
+#endif
 #ifdef CONFIG_CEPH_FS_POSIX_ACL
posix_acl_release(as_ctx->acl);
posix_acl_release(as_ctx->default_acl);
 #endif
 #ifdef CONFIG_CEPH_FS_SECURITY_LABEL
-   security_release_secctx(as_ctx->sec_ctx, as_ctx->sec_ctxlen);
+   lsmcontext_init(&scaff, as_ctx->sec_ctx, as_ctx->sec_ctxlen, 0);
+   security_release_secctx(&scaff);
 #endif
if (as_ctx->pagelist)
ceph_pagelist_release(as_ctx->pagelist);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index a0c1e653a935..7fcc27f0faf6 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -130,8 +130,12 @@ nfs4_label_init_security(struct inode *dir, struct dentry 
*dentry,
 static inline void
 nfs4_label_release_security(struct nfs4_label *label)
 {
-   if (label)
-   security_release_secctx(label->label, label->len);
+   struct lsmcontext scaff; /* scaffolding */
+
+   if (label) {
+   lsmcontext_init(&scaff, label->label, label->len, 0);
+   security_release_secctx(&scaff);
+   }
 }
 static inline u32 *nfs4_bitmask(struct nfs_server *server, struct nfs4_label 
*label)
 {
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 996ac01ee977..61d6b8a0e8f0 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2496,6 +2496,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh 
*fhp,
int err;
struct nfs4_acl *acl = NULL;
 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
+   struct lsmcontext scaff; /* scaffolding */
void *context = NULL;
int contextlen;

[PATCH v17 15/23] LSM: Use lsmcontext in security_secid_to_secctx

2020-05-14 Thread Casey Schaufler
Replace the (secctx,seclen) pointer pair with a single
lsmcontext pointer to allow return of the LSM identifier
along with the context and context length. This allows
security_release_secctx() to know how to release the
context. Callers have been modified to use or save the
returned data from the new structure.

Reviewed-by: Kees Cook 
Acked-by: Stephen Smalley 
Acked-by: Paul Moore 
Signed-off-by: Casey Schaufler 
Cc: netdev@vger.kernel.org
---
 drivers/android/binder.c| 26 +++-
 include/linux/security.h|  4 +--
 include/net/scm.h   | 10 ++-
 kernel/audit.c  | 35 --
 kernel/auditsc.c| 31 +++
 net/ipv4/ip_sockglue.c  |  7 ++---
 net/netfilter/nf_conntrack_netlink.c| 18 +--
 net/netfilter/nf_conntrack_standalone.c |  7 ++---
 net/netfilter/nfnetlink_queue.c |  5 +++-
 net/netlabel/netlabel_unlabeled.c   | 40 -
 net/netlabel/netlabel_user.c|  7 ++---
 security/security.c | 10 +--
 12 files changed, 76 insertions(+), 124 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 30e59b386ce2..c76fc2abd091 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2861,9 +2861,7 @@ static void binder_transaction(struct binder_proc *proc,
binder_size_t last_fixup_min_off = 0;
struct binder_context *context = proc->context;
int t_debug_id = atomic_inc_return(&binder_last_id);
-   char *secctx = NULL;
-   u32 secctx_sz = 0;
-   struct lsmcontext scaff; /* scaffolding */
+   struct lsmcontext lsmctx = { };
 
e = binder_transaction_log_add(&binder_transaction_log);
e->debug_id = t_debug_id;
@@ -3111,14 +3109,14 @@ static void binder_transaction(struct binder_proc *proc,
size_t added_size;
 
security_task_getsecid(proc->tsk, &blob);
-   ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz);
+   ret = security_secid_to_secctx(&blob, &lsmctx);
if (ret) {
return_error = BR_FAILED_REPLY;
return_error_param = ret;
return_error_line = __LINE__;
goto err_get_secctx_failed;
}
-   added_size = ALIGN(secctx_sz, sizeof(u64));
+   added_size = ALIGN(lsmctx.len, sizeof(u64));
extra_buffers_size += added_size;
if (extra_buffers_size < added_size) {
/* integer overflow of extra_buffers_size */
@@ -3145,24 +3143,22 @@ static void binder_transaction(struct binder_proc *proc,
t->buffer = NULL;
goto err_binder_alloc_buf_failed;
}
-   if (secctx) {
+   if (lsmctx.context) {
int err;
size_t buf_offset = ALIGN(tr->data_size, sizeof(void *)) +
ALIGN(tr->offsets_size, sizeof(void *)) +
ALIGN(extra_buffers_size, sizeof(void *)) -
-   ALIGN(secctx_sz, sizeof(u64));
+   ALIGN(lsmctx.len, sizeof(u64));
 
t->security_ctx = (uintptr_t)t->buffer->user_data + buf_offset;
err = binder_alloc_copy_to_buffer(&target_proc->alloc,
  t->buffer, buf_offset,
- secctx, secctx_sz);
+ lsmctx.context, lsmctx.len);
if (err) {
t->security_ctx = 0;
WARN_ON(1);
}
-   lsmcontext_init(&scaff, secctx, secctx_sz, 0);
-   security_release_secctx(&scaff);
-   secctx = NULL;
+   security_release_secctx(&lsmctx);
}
t->buffer->debug_id = t->debug_id;
t->buffer->transaction = t;
@@ -3218,7 +3214,7 @@ static void binder_transaction(struct binder_proc *proc,
off_end_offset = off_start_offset + tr->offsets_size;
sg_buf_offset = ALIGN(off_end_offset, sizeof(void *));
sg_buf_end_offset = sg_buf_offset + extra_buffers_size -
-   ALIGN(secctx_sz, sizeof(u64));
+   ALIGN(lsmctx.len, sizeof(u64));
off_min = 0;
for (buffer_offset = off_start_offset; buffer_offset < off_end_offset;
 buffer_offset += sizeof(binder_size_t)) {
@@ -3494,10 +3490,8 @@ static void binder_transaction(struct binder_proc *proc,
binder_alloc_free_buf(&target_proc->alloc, t->buffer);
 err_binder_alloc_buf_failed:
 err_bad_extra_size:
-   if (secctx) {
- 

[PATCH v17 17/23] LSM: security_secid_to_secctx in netlink netfilter

2020-05-14 Thread Casey Schaufler
Change netlink netfilter interfaces to use lsmcontext
pointers, and remove scaffolding.

Reviewed-by: Kees Cook 
Reviewed-by: John Johansen 
Acked-by: Stephen Smalley 
Signed-off-by: Casey Schaufler 
cc: netdev@vger.kernel.org
---
 net/netfilter/nfnetlink_queue.c | 31 ---
 1 file changed, 12 insertions(+), 19 deletions(-)

diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index fe19ae7216db..a4d4602ab9b7 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -301,12 +301,10 @@ static int nfqnl_put_sk_uidgid(struct sk_buff *skb, 
struct sock *sk)
return -1;
 }
 
-static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata)
+static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, struct lsmcontext *context)
 {
-   u32 seclen = 0;
 #if IS_ENABLED(CONFIG_NETWORK_SECMARK)
struct lsmblob blob;
-   struct lsmcontext context = { };
 
if (!skb || !sk_fullsock(skb->sk))
return 0;
@@ -318,14 +316,14 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char 
**secdata)
 * blob. security_secid_to_secctx() will know which security
 * module to use to create the secctx.  */
lsmblob_init(&blob, skb->secmark);
-   security_secid_to_secctx(&blob, &context);
-   *secdata = context.context;
+   security_secid_to_secctx(&blob, context);
}
 
read_unlock_bh(&skb->sk->sk_callback_lock);
-   seclen = context.len;
+   return context->len;
+#else
+   return 0;
 #endif
-   return seclen;
 }
 
 static u32 nfqnl_get_bridge_size(struct nf_queue_entry *entry)
@@ -401,8 +399,7 @@ nfqnl_build_packet_message(struct net *net, struct 
nfqnl_instance *queue,
enum ip_conntrack_info uninitialized_var(ctinfo);
struct nfnl_ct_hook *nfnl_ct;
bool csum_verify;
-   struct lsmcontext scaff; /* scaffolding */
-   char *secdata = NULL;
+   struct lsmcontext context = { };
u32 seclen = 0;
 
size = nlmsg_total_size(sizeof(struct nfgenmsg))
@@ -469,7 +466,7 @@ nfqnl_build_packet_message(struct net *net, struct 
nfqnl_instance *queue,
}
 
if ((queue->flags & NFQA_CFG_F_SECCTX) && entskb->sk) {
-   seclen = nfqnl_get_sk_secctx(entskb, &secdata);
+   seclen = nfqnl_get_sk_secctx(entskb, &context);
if (seclen)
size += nla_total_size(seclen);
}
@@ -604,7 +601,7 @@ nfqnl_build_packet_message(struct net *net, struct 
nfqnl_instance *queue,
nfqnl_put_sk_uidgid(skb, entskb->sk) < 0)
goto nla_put_failure;
 
-   if (seclen && nla_put(skb, NFQA_SECCTX, seclen, secdata))
+   if (seclen && nla_put(skb, NFQA_SECCTX, context.len, context.context))
goto nla_put_failure;
 
if (ct && nfnl_ct->build(skb, ct, ctinfo, NFQA_CT, NFQA_CT_INFO) < 0)
@@ -632,10 +629,8 @@ nfqnl_build_packet_message(struct net *net, struct 
nfqnl_instance *queue,
}
 
nlh->nlmsg_len = skb->len;
-   if (seclen) {
-   lsmcontext_init(&scaff, secdata, seclen, 0);
-   security_release_secctx(&scaff);
-   }
+   if (seclen)
+   security_release_secctx(&context);
return skb;
 
 nla_put_failure:
@@ -643,10 +638,8 @@ nfqnl_build_packet_message(struct net *net, struct 
nfqnl_instance *queue,
kfree_skb(skb);
net_err_ratelimited("nf_queue: error creating packet message\n");
 nlmsg_failure:
-   if (seclen) {
-   lsmcontext_init(&scaff, secdata, seclen, 0);
-   security_release_secctx(&scaff);
-   }
+   if (seclen)
+   security_release_secctx(&context);
return NULL;
 }
 
-- 
2.24.1



Re: [PATCH] security: fix the default value of secid_to_secctx hook

2020-05-18 Thread Casey Schaufler
On 5/18/2020 2:43 PM, Schaufler, Casey wrote:
>> -Original Message-
>> From: linux-kernel-ow...@vger.kernel.org > ow...@vger.kernel.org> On Behalf Of Arnd Bergmann
>> Sent: Saturday, May 16, 2020 1:05 AM
>> To: Alexei Starovoitov 
>> Cc: James Morris ; Anders Roxell
>> ; Alexei Starovoitov ; Daniel
>> Borkmann ; LKML ;
>> Network Development ; bpf
>> 
>> Subject: Re: [PATCH] security: fix the default value of secid_to_secctx hook
> I would *really* appreciate it if discussions about the LSM infrastructure
> where done on the linux-security-module mail list. (added to CC).
>
>> On Sat, May 16, 2020 at 1:29 AM Alexei Starovoitov
>>  wrote:
>>> On Thu, May 14, 2020 at 12:47 PM Alexei Starovoitov
>>>  wrote:
 On Thu, May 14, 2020 at 12:43 PM James Morris
  wrote:
> On Wed, 13 May 2020, Alexei Starovoitov wrote:
>
>> James,
>>
>> since you took the previous similar patch are you going to pick this
>> one up as well?
>> Or we can route it via bpf tree to Linus asap.
> Routing via your tree is fine.
 Perfect.
 Applied to bpf tree. Thanks everyone.
>>> Looks like it was a wrong fix.
>>> It breaks audit like this:
>>> sudo auditctl -e 0
>>> [   88.400296] audit: error in audit_log_task_context
>>> [   88.400976] audit: error in audit_log_task_context
>>> [   88.401597] audit: type=1305 audit(1589584951.198:89): op=set
>>> audit_enabled=0 old=1 auid=0 ses=1 res=0
>>> [   88.402691] audit: type=1300 audit(1589584951.198:89):
>>> arch=c03e syscall=44 success=yes exit=52 a0=3 a1=7ffe42a37400
>>> a2=34 a3=0 items=0 ppid=2250 pid=2251 auid=0 uid=0 gid=0 euid=0 suid=0
>>> fsuid=0 egid=0 sgid=0 fsgid=0 tty=ttyS0 se)
>>> [   88.405587] audit: type=1327 audit(1589584951.198:89):
>>> proctitle=617564697463746C002D650030
>>> Error sending enable request (Operation not supported)
>>>
>>> when CONFIG_LSM= has "bpf" in it.
>> Do you have more than one LSM enabled? It looks like
>> the problem with security_secid_to_secctx() is now that it
>> returns an error if any of the LSMs fail and the caller expects
>> it to succeed if at least one of them sets the secdata pointer.

security_secid_to_secctx() is not currently stackable (I'm
looking at 5.7-rc6) even for this simple case. call_int_hook()
does bail-on-fail and will try all hooks registered, looking for
a failure.

You need to replace the call_int_hook() with an explicit
hlist_for_each_entry(), as is done in security_inode_getsecurity().

>>
>> The problem earlier was that the call succeeded even though
>> no LSM had set the pointer.
>>
>> What is the behavior we actually expect from this function if
>> multiple LSM are loaded?
>>
>>Arnd



[PATCH v24 15/25] LSM: Ensure the correct LSM context releaser

2021-01-26 Thread Casey Schaufler
Add a new lsmcontext data structure to hold all the information
about a "security context", including the string, its size and
which LSM allocated the string. The allocation information is
necessary because LSMs have different policies regarding the
lifecycle of these strings. SELinux allocates and destroys
them on each use, whereas Smack provides a pointer to an entry
in a list that never goes away.

Reviewed-by: Kees Cook 
Reviewed-by: John Johansen 
Acked-by: Stephen Smalley 
Signed-off-by: Casey Schaufler 
Cc: linux-integr...@vger.kernel.org
Cc: netdev@vger.kernel.org
Cc: linux-au...@redhat.com
Cc: netfilter-de...@vger.kernel.org
To: Pablo Neira Ayuso 
Cc: linux-...@vger.kernel.org
---
 drivers/android/binder.c| 10 ---
 fs/ceph/xattr.c |  6 -
 fs/nfs/nfs4proc.c   |  8 --
 fs/nfsd/nfs4xdr.c   |  7 +++--
 include/linux/security.h| 35 +++--
 include/net/scm.h   |  5 +++-
 kernel/audit.c  | 14 +++---
 kernel/auditsc.c| 12 ++---
 net/ipv4/ip_sockglue.c  |  4 ++-
 net/netfilter/nf_conntrack_netlink.c|  4 ++-
 net/netfilter/nf_conntrack_standalone.c |  4 ++-
 net/netfilter/nfnetlink_queue.c | 13 ++---
 net/netlabel/netlabel_unlabeled.c   | 19 +++---
 net/netlabel/netlabel_user.c|  4 ++-
 security/security.c | 11 
 15 files changed, 121 insertions(+), 35 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 1a15e9e19e22..f74a72867ec9 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2448,6 +2448,7 @@ static void binder_transaction(struct binder_proc *proc,
int t_debug_id = atomic_inc_return(&binder_last_id);
char *secctx = NULL;
u32 secctx_sz = 0;
+   struct lsmcontext scaff; /* scaffolding */
 
e = binder_transaction_log_add(&binder_transaction_log);
e->debug_id = t_debug_id;
@@ -2750,7 +2751,8 @@ static void binder_transaction(struct binder_proc *proc,
t->security_ctx = 0;
WARN_ON(1);
}
-   security_release_secctx(secctx, secctx_sz);
+   lsmcontext_init(&scaff, secctx, secctx_sz, 0);
+   security_release_secctx(&scaff);
secctx = NULL;
}
t->buffer->debug_id = t->debug_id;
@@ -3084,8 +3086,10 @@ static void binder_transaction(struct binder_proc *proc,
binder_alloc_free_buf(&target_proc->alloc, t->buffer);
 err_binder_alloc_buf_failed:
 err_bad_extra_size:
-   if (secctx)
-   security_release_secctx(secctx, secctx_sz);
+   if (secctx) {
+   lsmcontext_init(&scaff, secctx, secctx_sz, 0);
+   security_release_secctx(&scaff);
+   }
 err_get_secctx_failed:
kfree(tcomplete);
binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c
index 24997982de01..cc4f911f0d74 100644
--- a/fs/ceph/xattr.c
+++ b/fs/ceph/xattr.c
@@ -1348,12 +1348,16 @@ int ceph_security_init_secctx(struct dentry *dentry, 
umode_t mode,
 
 void ceph_release_acl_sec_ctx(struct ceph_acl_sec_ctx *as_ctx)
 {
+#ifdef CONFIG_CEPH_FS_SECURITY_LABEL
+   struct lsmcontext scaff; /* scaffolding */
+#endif
 #ifdef CONFIG_CEPH_FS_POSIX_ACL
posix_acl_release(as_ctx->acl);
posix_acl_release(as_ctx->default_acl);
 #endif
 #ifdef CONFIG_CEPH_FS_SECURITY_LABEL
-   security_release_secctx(as_ctx->sec_ctx, as_ctx->sec_ctxlen);
+   lsmcontext_init(&scaff, as_ctx->sec_ctx, as_ctx->sec_ctxlen, 0);
+   security_release_secctx(&scaff);
 #endif
if (as_ctx->pagelist)
ceph_pagelist_release(as_ctx->pagelist);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 0ce04e0e5d82..d3c29eb2e9dd 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -139,8 +139,12 @@ nfs4_label_init_security(struct inode *dir, struct dentry 
*dentry,
 static inline void
 nfs4_label_release_security(struct nfs4_label *label)
 {
-   if (label)
-   security_release_secctx(label->label, label->len);
+   struct lsmcontext scaff; /* scaffolding */
+
+   if (label) {
+   lsmcontext_init(&scaff, label->label, label->len, 0);
+   security_release_secctx(&scaff);
+   }
 }
 static inline u32 *nfs4_bitmask(struct nfs_server *server, struct nfs4_label 
*label)
 {
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 45ee6b12ce5b..43698f15a52b 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2834,6 +2834,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh 
*fhp,
int err;
struct nfs4_acl *acl = NULL;
 #ifdef CONFIG_NFSD_V4_SECURIT

[PATCH v24 18/25] LSM: security_secid_to_secctx in netlink netfilter

2021-01-26 Thread Casey Schaufler
Change netlink netfilter interfaces to use lsmcontext
pointers, and remove scaffolding.

Reviewed-by: Kees Cook 
Reviewed-by: John Johansen 
Acked-by: Stephen Smalley 
Acked-by: Pablo Neira Ayuso 
Signed-off-by: Casey Schaufler 
Cc: netdev@vger.kernel.org
Cc: netfilter-de...@vger.kernel.org
---
 net/netfilter/nfnetlink_queue.c | 37 +
 1 file changed, 14 insertions(+), 23 deletions(-)

diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 84be5a49a157..0d8b83d84422 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -301,15 +301,13 @@ static int nfqnl_put_sk_uidgid(struct sk_buff *skb, 
struct sock *sk)
return -1;
 }
 
-static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata)
+static void nfqnl_get_sk_secctx(struct sk_buff *skb, struct lsmcontext 
*context)
 {
-   u32 seclen = 0;
 #if IS_ENABLED(CONFIG_NETWORK_SECMARK)
struct lsmblob blob;
-   struct lsmcontext context = { };
 
if (!skb || !sk_fullsock(skb->sk))
-   return 0;
+   return;
 
read_lock_bh(&skb->sk->sk_callback_lock);
 
@@ -318,14 +316,12 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char 
**secdata)
 * blob. security_secid_to_secctx() will know which security
 * module to use to create the secctx.  */
lsmblob_init(&blob, skb->secmark);
-   security_secid_to_secctx(&blob, &context);
-   *secdata = context.context;
+   security_secid_to_secctx(&blob, context);
}
 
read_unlock_bh(&skb->sk->sk_callback_lock);
-   seclen = context.len;
 #endif
-   return seclen;
+   return;
 }
 
 static u32 nfqnl_get_bridge_size(struct nf_queue_entry *entry)
@@ -398,12 +394,10 @@ nfqnl_build_packet_message(struct net *net, struct 
nfqnl_instance *queue,
struct net_device *indev;
struct net_device *outdev;
struct nf_conn *ct = NULL;
+   struct lsmcontext context = { };
enum ip_conntrack_info ctinfo;
struct nfnl_ct_hook *nfnl_ct;
bool csum_verify;
-   struct lsmcontext scaff; /* scaffolding */
-   char *secdata = NULL;
-   u32 seclen = 0;
 
size = nlmsg_total_size(sizeof(struct nfgenmsg))
+ nla_total_size(sizeof(struct nfqnl_msg_packet_hdr))
@@ -469,9 +463,9 @@ nfqnl_build_packet_message(struct net *net, struct 
nfqnl_instance *queue,
}
 
if ((queue->flags & NFQA_CFG_F_SECCTX) && entskb->sk) {
-   seclen = nfqnl_get_sk_secctx(entskb, &secdata);
-   if (seclen)
-   size += nla_total_size(seclen);
+   nfqnl_get_sk_secctx(entskb, &context);
+   if (context.len)
+   size += nla_total_size(context.len);
}
 
skb = alloc_skb(size, GFP_ATOMIC);
@@ -604,7 +598,8 @@ nfqnl_build_packet_message(struct net *net, struct 
nfqnl_instance *queue,
nfqnl_put_sk_uidgid(skb, entskb->sk) < 0)
goto nla_put_failure;
 
-   if (seclen && nla_put(skb, NFQA_SECCTX, seclen, secdata))
+   if (context.len &&
+   nla_put(skb, NFQA_SECCTX, context.len, context.context))
goto nla_put_failure;
 
if (ct && nfnl_ct->build(skb, ct, ctinfo, NFQA_CT, NFQA_CT_INFO) < 0)
@@ -632,10 +627,8 @@ nfqnl_build_packet_message(struct net *net, struct 
nfqnl_instance *queue,
}
 
nlh->nlmsg_len = skb->len;
-   if (seclen) {
-   lsmcontext_init(&scaff, secdata, seclen, 0);
-   security_release_secctx(&scaff);
-   }
+   if (context.len)
+   security_release_secctx(&context);
return skb;
 
 nla_put_failure:
@@ -643,10 +636,8 @@ nfqnl_build_packet_message(struct net *net, struct 
nfqnl_instance *queue,
kfree_skb(skb);
net_err_ratelimited("nf_queue: error creating packet message\n");
 nlmsg_failure:
-   if (seclen) {
-   lsmcontext_init(&scaff, secdata, seclen, 0);
-   security_release_secctx(&scaff);
-   }
+   if (context.len)
+   security_release_secctx(&context);
return NULL;
 }
 
-- 
2.25.4



[PATCH v24 10/25] LSM: Use lsmblob in security_task_getsecid

2021-01-26 Thread Casey Schaufler
Change the security_task_getsecid() interface to fill in
a lsmblob structure instead of a u32 secid in support of
LSM stacking. Audit interfaces will need to collect all
possible secids for possible reporting.

Reviewed-by: Kees Cook 
Reviewed-by: John Johansen 
Acked-by: Stephen Smalley 
Acked-by: Paul Moore 
Signed-off-by: Casey Schaufler 
Cc: linux-integr...@vger.kernel.org
Cc: linux-au...@redhat.com
Cc: netdev@vger.kernel.org
---
 drivers/android/binder.c  | 12 +-
 include/linux/security.h  |  7 ++--
 kernel/audit.c| 16 +++-
 kernel/auditfilter.c  |  4 +-
 kernel/auditsc.c  | 25 ++--
 net/netlabel/netlabel_unlabeled.c |  5 ++-
 net/netlabel/netlabel_user.h  |  6 ++-
 security/integrity/ima/ima_appraise.c | 10 +++--
 security/integrity/ima/ima_main.c | 56 +++
 security/security.c   | 12 --
 10 files changed, 80 insertions(+), 73 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 5fb8555ce166..1a15e9e19e22 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2697,20 +2697,10 @@ static void binder_transaction(struct binder_proc *proc,
t->priority = task_nice(current);
 
if (target_node && target_node->txn_security_ctx) {
-   u32 secid;
struct lsmblob blob;
size_t added_size;
 
-   security_task_getsecid(proc->tsk, &secid);
-   /*
-* Later in this patch set security_task_getsecid() will
-* provide a lsmblob instead of a secid. lsmblob_init
-* is used to ensure that all the secids in the lsmblob
-* get the value returned from security_task_getsecid(),
-* which means that the one expected by
-* security_secid_to_secctx() will be set.
-*/
-   lsmblob_init(&blob, secid);
+   security_task_getsecid(proc->tsk, &blob);
ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz);
if (ret) {
return_error = BR_FAILED_REPLY;
diff --git a/include/linux/security.h b/include/linux/security.h
index 20a47bd3930b..9fc245c1f739 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -487,7 +487,7 @@ int security_task_fix_setgid(struct cred *new, const struct 
cred *old,
 int security_task_setpgid(struct task_struct *p, pid_t pgid);
 int security_task_getpgid(struct task_struct *p);
 int security_task_getsid(struct task_struct *p);
-void security_task_getsecid(struct task_struct *p, u32 *secid);
+void security_task_getsecid(struct task_struct *p, struct lsmblob *blob);
 int security_task_setnice(struct task_struct *p, int nice);
 int security_task_setioprio(struct task_struct *p, int ioprio);
 int security_task_getioprio(struct task_struct *p);
@@ -1160,9 +1160,10 @@ static inline int security_task_getsid(struct 
task_struct *p)
return 0;
 }
 
-static inline void security_task_getsecid(struct task_struct *p, u32 *secid)
+static inline void security_task_getsecid(struct task_struct *p,
+ struct lsmblob *blob)
 {
-   *secid = 0;
+   lsmblob_init(blob, 0);
 }
 
 static inline int security_task_setnice(struct task_struct *p, int nice)
diff --git a/kernel/audit.c b/kernel/audit.c
index 72f6672a445e..e70bbd6b91c4 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -2139,19 +2139,12 @@ int audit_log_task_context(struct audit_buffer *ab)
char *ctx = NULL;
unsigned len;
int error;
-   u32 sid;
struct lsmblob blob;
 
-   security_task_getsecid(current, &sid);
-   if (!sid)
+   security_task_getsecid(current, &blob);
+   if (!lsmblob_is_set(&blob))
return 0;
 
-   /*
-* lsmblob_init sets all values in the lsmblob to sid.
-* This is temporary until security_task_getsecid is converted
-* to use a lsmblob, which happens later in this patch set.
-*/
-   lsmblob_init(&blob, sid);
error = security_secid_to_secctx(&blob, &ctx, &len);
if (error) {
if (error != -EINVAL)
@@ -2359,6 +2352,7 @@ int audit_set_loginuid(kuid_t loginuid)
 int audit_signal_info(int sig, struct task_struct *t)
 {
kuid_t uid = current_uid(), auid;
+   struct lsmblob blob;
 
if (auditd_test_task(t) &&
(sig == SIGTERM || sig == SIGHUP ||
@@ -2369,7 +2363,9 @@ int audit_signal_info(int sig, struct task_struct *t)
audit_sig_uid = auid;
else
audit_sig_uid = uid;
-   security_task_getsecid(current, &audit_sig_sid);
+   security_task_getsecid(current, &blob);
+   /* scaf

[PATCH v24 22/25] Audit: Add new record for multiple process LSM attributes

2021-01-26 Thread Casey Schaufler
Create a new audit record type to contain the subject information
when there are multiple security modules that require such data.
This record is linked with the same timestamp and serial number
using the audit_alloc_local() mechanism.
The record is produced only in cases where there is more than one
security module with a process "context".
In cases where this record is produced the subj= fields of
other records in the audit event will be set to "subj=?".

An example of the MAC_TASK_CONTEXTS (1420) record is:

type=UNKNOWN[1420]
msg=audit(1600880931.832:113)
subj_apparmor==unconfined
subj_smack=_

There will be a subj_$LSM= entry for each security module
LSM that supports the secid_to_secctx and secctx_to_secid
hooks. The BPF security module implements secid/secctx
translation hooks, so it has to be considered to provide a
secctx even though it may not actually do so.

Signed-off-by: Casey Schaufler 
To: p...@paul-moore.com
To: linux-au...@redhat.com
To: r...@redhat.com
Cc: netdev@vger.kernel.org
---
 drivers/android/binder.c|  2 +-
 include/linux/audit.h   | 24 
 include/linux/security.h| 16 -
 include/net/netlabel.h  |  3 +-
 include/net/scm.h   |  2 +-
 include/net/xfrm.h  | 13 +++-
 include/uapi/linux/audit.h  |  1 +
 kernel/audit.c  | 80 ++---
 kernel/audit.h  |  3 +
 kernel/auditfilter.c|  6 +-
 kernel/auditsc.c| 75 ---
 net/ipv4/ip_sockglue.c  |  2 +-
 net/netfilter/nf_conntrack_netlink.c|  4 +-
 net/netfilter/nf_conntrack_standalone.c |  2 +-
 net/netfilter/nfnetlink_queue.c |  2 +-
 net/netlabel/netlabel_domainhash.c  |  4 +-
 net/netlabel/netlabel_unlabeled.c   | 24 
 net/netlabel/netlabel_user.c| 20 ---
 net/netlabel/netlabel_user.h|  6 +-
 net/xfrm/xfrm_policy.c  | 10 ++--
 net/xfrm/xfrm_state.c   | 20 ---
 security/integrity/ima/ima_api.c|  7 ++-
 security/integrity/integrity_audit.c|  6 +-
 security/security.c | 46 +-
 security/smack/smackfs.c|  3 +-
 25 files changed, 274 insertions(+), 107 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 4c810ea52ab7..28f573d46391 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2700,7 +2700,7 @@ static void binder_transaction(struct binder_proc *proc,
size_t added_size;
 
security_task_getsecid(proc->tsk, &blob);
-   ret = security_secid_to_secctx(&blob, &lsmctx);
+   ret = security_secid_to_secctx(&blob, &lsmctx, LSMBLOB_DISPLAY);
if (ret) {
return_error = BR_FAILED_REPLY;
return_error_param = ret;
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 97cd7471e572..229cd71fbf09 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -164,6 +164,8 @@ extern struct audit_buffer *audit_log_start(struct 
audit_context *ctx, gfp_t gfp
 extern __printf(2, 3)
 void audit_log_format(struct audit_buffer *ab, const char *fmt, ...);
 extern voidaudit_log_end(struct audit_buffer *ab);
+extern voidaudit_log_end_local(struct audit_buffer *ab,
+   struct audit_context *context);
 extern boolaudit_string_contains_control(const char *string,
  size_t len);
 extern voidaudit_log_n_hex(struct audit_buffer *ab,
@@ -188,6 +190,7 @@ extern void audit_log_lost(const char *message);
 
 extern int audit_log_task_context(struct audit_buffer *ab);
 extern void audit_log_task_info(struct audit_buffer *ab);
+extern void audit_log_lsm(struct audit_context *context);
 
 extern int audit_update_lsm_rules(void);
 
@@ -226,6 +229,9 @@ void audit_log_format(struct audit_buffer *ab, const char 
*fmt, ...)
 { }
 static inline void audit_log_end(struct audit_buffer *ab)
 { }
+static inline void audit_log_end_local(struct audit_buffer *ab,
+  struct audit_context *context)
+{ }
 static inline void audit_log_n_hex(struct audit_buffer *ab,
   const unsigned char *buf, size_t len)
 { }
@@ -252,6 +258,8 @@ static inline int audit_log_task_context(struct 
audit_buffer *ab)
 }
 static inline void audit_log_task_info(struct audit_buffer *ab)
 { }
+static void audit_log_lsm(struct audit_context *context)
+{ }
 
 static inline kuid_t audit_get_loginuid(struct task_struct *tsk)
 {
@@ -291,6 +299,7 @@ extern int  audit_alloc(struct task_struct *task);
 

[PATCH v24 16/25] LSM: Use lsmcontext in security_secid_to_secctx

2021-01-26 Thread Casey Schaufler
Replace the (secctx,seclen) pointer pair with a single
lsmcontext pointer to allow return of the LSM identifier
along with the context and context length. This allows
security_release_secctx() to know how to release the
context. Callers have been modified to use or save the
returned data from the new structure.

Reviewed-by: Kees Cook 
Acked-by: Stephen Smalley 
Acked-by: Paul Moore 
Signed-off-by: Casey Schaufler 
Cc: netdev@vger.kernel.org
Cc: linux-au...@redhat.com
Cc: netfilter-de...@vger.kernel.org
---
 drivers/android/binder.c| 26 +++-
 include/linux/security.h|  4 +--
 include/net/scm.h   |  9 ++
 kernel/audit.c  | 39 +++-
 kernel/auditsc.c| 31 +++
 net/ipv4/ip_sockglue.c  |  8 ++---
 net/netfilter/nf_conntrack_netlink.c| 18 +--
 net/netfilter/nf_conntrack_standalone.c |  7 ++---
 net/netfilter/nfnetlink_queue.c |  5 +++-
 net/netlabel/netlabel_unlabeled.c   | 40 -
 net/netlabel/netlabel_user.c|  7 ++---
 security/security.c | 10 +--
 12 files changed, 81 insertions(+), 123 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index f74a72867ec9..4c810ea52ab7 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2446,9 +2446,7 @@ static void binder_transaction(struct binder_proc *proc,
binder_size_t last_fixup_min_off = 0;
struct binder_context *context = proc->context;
int t_debug_id = atomic_inc_return(&binder_last_id);
-   char *secctx = NULL;
-   u32 secctx_sz = 0;
-   struct lsmcontext scaff; /* scaffolding */
+   struct lsmcontext lsmctx = { };
 
e = binder_transaction_log_add(&binder_transaction_log);
e->debug_id = t_debug_id;
@@ -2702,14 +2700,14 @@ static void binder_transaction(struct binder_proc *proc,
size_t added_size;
 
security_task_getsecid(proc->tsk, &blob);
-   ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz);
+   ret = security_secid_to_secctx(&blob, &lsmctx);
if (ret) {
return_error = BR_FAILED_REPLY;
return_error_param = ret;
return_error_line = __LINE__;
goto err_get_secctx_failed;
}
-   added_size = ALIGN(secctx_sz, sizeof(u64));
+   added_size = ALIGN(lsmctx.len, sizeof(u64));
extra_buffers_size += added_size;
if (extra_buffers_size < added_size) {
/* integer overflow of extra_buffers_size */
@@ -2736,24 +2734,22 @@ static void binder_transaction(struct binder_proc *proc,
t->buffer = NULL;
goto err_binder_alloc_buf_failed;
}
-   if (secctx) {
+   if (lsmctx.context) {
int err;
size_t buf_offset = ALIGN(tr->data_size, sizeof(void *)) +
ALIGN(tr->offsets_size, sizeof(void *)) +
ALIGN(extra_buffers_size, sizeof(void *)) -
-   ALIGN(secctx_sz, sizeof(u64));
+   ALIGN(lsmctx.len, sizeof(u64));
 
t->security_ctx = (uintptr_t)t->buffer->user_data + buf_offset;
err = binder_alloc_copy_to_buffer(&target_proc->alloc,
  t->buffer, buf_offset,
- secctx, secctx_sz);
+ lsmctx.context, lsmctx.len);
if (err) {
t->security_ctx = 0;
WARN_ON(1);
}
-   lsmcontext_init(&scaff, secctx, secctx_sz, 0);
-   security_release_secctx(&scaff);
-   secctx = NULL;
+   security_release_secctx(&lsmctx);
}
t->buffer->debug_id = t->debug_id;
t->buffer->transaction = t;
@@ -2810,7 +2806,7 @@ static void binder_transaction(struct binder_proc *proc,
off_end_offset = off_start_offset + tr->offsets_size;
sg_buf_offset = ALIGN(off_end_offset, sizeof(void *));
sg_buf_end_offset = sg_buf_offset + extra_buffers_size -
-   ALIGN(secctx_sz, sizeof(u64));
+   ALIGN(lsmctx.len, sizeof(u64));
off_min = 0;
for (buffer_offset = off_start_offset; buffer_offset < off_end_offset;
 buffer_offset += sizeof(binder_size_t)) {
@@ -3086,10 +3082,8 @@ static void binder_transaction(struct binder_proc *proc,
binder_alloc_free_buf(&target_proc->alloc, t->buffer);
 err_binder_all

[PATCH v24 19/25] NET: Store LSM netlabel data in a lsmblob

2021-01-26 Thread Casey Schaufler
Netlabel uses LSM interfaces requiring an lsmblob and
the internal storage is used to pass information between
these interfaces, so change the internal data from a secid
to a lsmblob. Update the netlabel interfaces and their
callers to accommodate the change. This requires that the
modules using netlabel use the lsm_id.slot to access the
correct secid when using netlabel.

Reviewed-by: Kees Cook 
Reviewed-by: John Johansen 
Acked-by: Stephen Smalley 
Acked-by: Paul Moore 
Signed-off-by: Casey Schaufler 
Cc: netdev@vger.kernel.org
---
 include/net/netlabel.h  |  8 +--
 net/ipv4/cipso_ipv4.c   | 26 ++
 net/netlabel/netlabel_kapi.c|  6 +--
 net/netlabel/netlabel_unlabeled.c   | 79 +
 net/netlabel/netlabel_unlabeled.h   |  2 +-
 security/selinux/hooks.c|  2 +-
 security/selinux/include/security.h |  1 +
 security/selinux/netlabel.c |  2 +-
 security/selinux/ss/services.c  |  4 +-
 security/smack/smack.h  |  1 +
 security/smack/smack_access.c   |  2 +-
 security/smack/smack_lsm.c  | 11 ++--
 security/smack/smackfs.c| 10 ++--
 13 files changed, 68 insertions(+), 86 deletions(-)

diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index 43ae50337685..73fc25b4042b 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -166,7 +166,7 @@ struct netlbl_lsm_catmap {
  * @attr.mls: MLS sensitivity label
  * @attr.mls.cat: MLS category bitmap
  * @attr.mls.lvl: MLS sensitivity level
- * @attr.secid: LSM specific secid token
+ * @attr.lsmblob: LSM specific data
  *
  * Description:
  * This structure is used to pass security attributes between NetLabel and the
@@ -201,7 +201,7 @@ struct netlbl_lsm_secattr {
struct netlbl_lsm_catmap *cat;
u32 lvl;
} mls;
-   u32 secid;
+   struct lsmblob lsmblob;
} attr;
 };
 
@@ -415,7 +415,7 @@ int netlbl_cfg_unlbl_static_add(struct net *net,
const void *addr,
const void *mask,
u16 family,
-   u32 secid,
+   struct lsmblob *lsmblob,
struct netlbl_audit *audit_info);
 int netlbl_cfg_unlbl_static_del(struct net *net,
const char *dev_name,
@@ -523,7 +523,7 @@ static inline int netlbl_cfg_unlbl_static_add(struct net 
*net,
  const void *addr,
  const void *mask,
  u16 family,
- u32 secid,
+ struct lsmblob *lsmblob,
  struct netlbl_audit *audit_info)
 {
return -ENOSYS;
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index 471d33a0d095..1ac343d02b58 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -106,15 +106,17 @@ int cipso_v4_rbm_strictvalid = 1;
 /* Base length of the local tag (non-standard tag).
  *  Tag definition (may change between kernel versions)
  *
- * 0  8  16 24 32
- * +--+--+--+--+
- * | 1000 | 0110 | 32-bit secid value  |
- * +--+--+--+--+
- * | in (host byte order)|
- * +--+--+
- *
+ * 0  8  1616 + sizeof(struct lsmblob)
+ * +--+--+-+
+ * | 1000 | 0110 | LSM blob data   |
+ * +--+--+-+
+ *
+ * All secid and flag fields are in host byte order.
+ * The lsmblob structure size varies depending on which
+ * Linux security modules are built in the kernel.
+ * The data is opaque.
  */
-#define CIPSO_V4_TAG_LOC_BLEN 6
+#define CIPSO_V4_TAG_LOC_BLEN (2 + sizeof(struct lsmblob))
 
 /*
  * Helper Functions
@@ -1469,7 +1471,11 @@ static int cipso_v4_gentag_loc(const struct cipso_v4_doi 
*doi_def,
 
buffer[0] = CIPSO_V4_TAG_LOCAL;
buffer[1] = CIPSO_V4_TAG_LOC_BLEN;
-   *(u32 *)&buffer[2] = secattr->attr.secid;
+   /* Ensure that there is sufficient space in the CIPSO header
+* for the LSM data. */
+   BUILD_BUG_ON(CIPSO_V4_TAG_LOC_BLEN > CIPSO_V4_OPT_LEN_MAX);
+   memcpy(&buffer[2], &secattr->attr.lsmblob,
+  sizeof(secattr->attr.lsmblob));
 
return CIPSO_V4_TAG_LOC_BLEN;
 }
@@ -1489,7 +1495,7 @@ static int cipso_v4_parsetag_loc(const struct 
cipso_v4_doi *doi_def,
 const unsigned char *tag,
 struct netlbl_lsm_secattr *secattr)
 {
-   secattr->attr.secid = *(u32 *)&tag[2];
+   memcpy(&secattr->attr.lsmblob,

[PATCH v24 07/25] LSM: Use lsmblob in security_secctx_to_secid

2021-01-27 Thread Casey Schaufler
Change the security_secctx_to_secid interface to use a lsmblob
structure in place of the single u32 secid in support of
module stacking. Change its callers to do the same.

The security module hook is unchanged, still passing back a secid.
The infrastructure passes the correct entry from the lsmblob.

Signed-off-by: Casey Schaufler 
Cc: netdev@vger.kernel.org
Cc: netfilter-de...@vger.kernel.org
To: Pablo Neira Ayuso 
---
 include/linux/security.h  | 26 ++--
 kernel/cred.c |  4 +---
 net/netfilter/nft_meta.c  | 10 
 net/netfilter/xt_SECMARK.c|  7 +-
 net/netlabel/netlabel_unlabeled.c | 23 +++---
 security/security.c   | 40 ++-
 6 files changed, 85 insertions(+), 25 deletions(-)

diff --git a/include/linux/security.h b/include/linux/security.h
index 5d8dbfb1dabb..af1d69b41f1c 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -196,6 +196,27 @@ static inline bool lsmblob_equal(struct lsmblob *bloba, 
struct lsmblob *blobb)
 extern int lsm_name_to_slot(char *name);
 extern const char *lsm_slot_to_name(int slot);
 
+/**
+ * lsmblob_value - find the first non-zero value in an lsmblob structure.
+ * @blob: Pointer to the data
+ *
+ * This needs to be used with extreme caution, as the cases where
+ * it is appropriate are rare.
+ *
+ * Return the first secid value set in the lsmblob.
+ * There should only be one.
+ */
+static inline u32 lsmblob_value(const struct lsmblob *blob)
+{
+   int i;
+
+   for (i = 0; i < LSMBLOB_ENTRIES; i++)
+   if (blob->secid[i])
+   return blob->secid[i];
+
+   return 0;
+}
+
 /* These functions are in security/commoncap.c */
 extern int cap_capable(const struct cred *cred, struct user_namespace *ns,
   int cap, unsigned int opts);
@@ -513,7 +534,8 @@ int security_setprocattr(const char *lsm, const char *name, 
void *value,
 int security_netlink_send(struct sock *sk, struct sk_buff *skb);
 int security_ismaclabel(const char *name);
 int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
-int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
+int security_secctx_to_secid(const char *secdata, u32 seclen,
+struct lsmblob *blob);
 void security_release_secctx(char *secdata, u32 seclen);
 void security_inode_invalidate_secctx(struct inode *inode);
 int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
@@ -1340,7 +1362,7 @@ static inline int security_secid_to_secctx(u32 secid, 
char **secdata, u32 *secle
 
 static inline int security_secctx_to_secid(const char *secdata,
   u32 seclen,
-  u32 *secid)
+  struct lsmblob *blob)
 {
return -EOPNOTSUPP;
 }
diff --git a/kernel/cred.c b/kernel/cred.c
index 22e0e7cbefde..848306c7d823 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -757,14 +757,12 @@ EXPORT_SYMBOL(set_security_override);
 int set_security_override_from_ctx(struct cred *new, const char *secctx)
 {
struct lsmblob blob;
-   u32 secid;
int ret;
 
-   ret = security_secctx_to_secid(secctx, strlen(secctx), &secid);
+   ret = security_secctx_to_secid(secctx, strlen(secctx), &blob);
if (ret < 0)
return ret;
 
-   lsmblob_init(&blob, secid);
return set_security_override(new, &blob);
 }
 EXPORT_SYMBOL(set_security_override_from_ctx);
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index bf4b3ad5314c..58a994db0069 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -811,21 +811,21 @@ 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 lsmblob blob;
int err;
 
-   err = security_secctx_to_secid(priv->ctx, strlen(priv->ctx), 
&tmp_secid);
+   err = security_secctx_to_secid(priv->ctx, strlen(priv->ctx), &blob);
if (err)
return err;
 
-   if (!tmp_secid)
+   if (!lsmblob_is_set(&blob))
return -ENOENT;
 
-   err = security_secmark_relabel_packet(tmp_secid);
+   err = security_secmark_relabel_packet(lsmblob_value(&blob));
if (err)
return err;
 
-   priv->secid = tmp_secid;
+   priv->secid = lsmblob_value(&blob);
return 0;
 }
 
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c
index 75625d13e976..9845d98e6b77 100644
--- a/net/netfilter/xt_SECMARK.c
+++ b/net/netfilter/xt_SECMARK.c
@@ -43,13 +43,14 @@ secmark_tg(struct sk_buff *skb, const struct 
xt_action_param *par)
 
 static int checkentry_lsm(struct xt_secmark_target_info *info)
 {
+   struct lsmblo

[PATCH v24 08/25] LSM: Use lsmblob in security_secid_to_secctx

2021-01-27 Thread Casey Schaufler
Change security_secid_to_secctx() to take a lsmblob as input
instead of a u32 secid. It will then call the LSM hooks
using the lsmblob element allocated for that module. The
callers have been updated as well. This allows for the
possibility that more than one module may be called upon
to translate a secid to a string, as can occur in the
audit code.

Signed-off-by: Casey Schaufler 
Cc: netdev@vger.kernel.org
Cc: linux-au...@redhat.com
Cc: netfilter-de...@vger.kernel.org
To: Pablo Neira Ayuso 
To: Paul Moore 
---
 drivers/android/binder.c| 12 +-
 include/linux/security.h|  5 +++--
 include/net/scm.h   |  7 +-
 kernel/audit.c  | 20 +++--
 kernel/auditsc.c| 28 +++
 net/ipv4/ip_sockglue.c  |  4 +++-
 net/netfilter/nf_conntrack_netlink.c| 14 ++--
 net/netfilter/nf_conntrack_standalone.c |  4 +++-
 net/netfilter/nfnetlink_queue.c | 11 +++--
 net/netlabel/netlabel_unlabeled.c   | 30 +
 net/netlabel/netlabel_user.c|  6 ++---
 security/security.c | 11 +
 12 files changed, 123 insertions(+), 29 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index c119736ca56a..5fb8555ce166 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2698,10 +2698,20 @@ static void binder_transaction(struct binder_proc *proc,
 
if (target_node && target_node->txn_security_ctx) {
u32 secid;
+   struct lsmblob blob;
size_t added_size;
 
security_task_getsecid(proc->tsk, &secid);
-   ret = security_secid_to_secctx(secid, &secctx, &secctx_sz);
+   /*
+* Later in this patch set security_task_getsecid() will
+* provide a lsmblob instead of a secid. lsmblob_init
+* is used to ensure that all the secids in the lsmblob
+* get the value returned from security_task_getsecid(),
+* which means that the one expected by
+* security_secid_to_secctx() will be set.
+*/
+   lsmblob_init(&blob, secid);
+   ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz);
if (ret) {
return_error = BR_FAILED_REPLY;
return_error_param = ret;
diff --git a/include/linux/security.h b/include/linux/security.h
index af1d69b41f1c..f786d8833e7d 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -533,7 +533,7 @@ int security_setprocattr(const char *lsm, const char *name, 
void *value,
 size_t size);
 int security_netlink_send(struct sock *sk, struct sk_buff *skb);
 int security_ismaclabel(const char *name);
-int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
+int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 
*seclen);
 int security_secctx_to_secid(const char *secdata, u32 seclen,
 struct lsmblob *blob);
 void security_release_secctx(char *secdata, u32 seclen);
@@ -1355,7 +1355,8 @@ static inline int security_ismaclabel(const char *name)
return 0;
 }
 
-static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 
*seclen)
+static inline int security_secid_to_secctx(struct lsmblob *blob,
+  char **secdata, u32 *seclen)
 {
return -EOPNOTSUPP;
 }
diff --git a/include/net/scm.h b/include/net/scm.h
index 1ce365f4c256..23a35ff1b3f2 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -92,12 +92,17 @@ static __inline__ int scm_send(struct socket *sock, struct 
msghdr *msg,
 #ifdef CONFIG_SECURITY_NETWORK
 static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct 
scm_cookie *scm)
 {
+   struct lsmblob lb;
char *secdata;
u32 seclen;
int err;
 
if (test_bit(SOCK_PASSSEC, &sock->flags)) {
-   err = security_secid_to_secctx(scm->secid, &secdata, &seclen);
+   /* There can only be one security module using the secid,
+* and the infrastructure will know which it is.
+*/
+   lsmblob_init(&lb, scm->secid);
+   err = security_secid_to_secctx(&lb, &secdata, &seclen);
 
if (!err) {
put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, 
secdata);
diff --git a/kernel/audit.c b/kernel/audit.c
index 1ffc2e059027..72f6672a445e 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1442,7 +1442,16 @@ static int audit_receive_msg(struct sk_buff *skb, struct 
nlmsghdr *nlh)
case AUDIT_SIGNAL_INFO:
len = 0;
if (audit_sig_sid) {
- 

Re: [PATCH] net: socket: Always initialize family field at move_addr_to_kernel().

2019-04-11 Thread Casey Schaufler

On 4/11/2019 4:31 AM, Tetsuo Handa wrote:

On 2019/04/04 13:49, David Miller wrote:

From: Tetsuo Handa 
Date: Wed, 3 Apr 2019 06:07:40 +0900


On 2019/04/03 5:23, David Miller wrote:

Please fix RDS and other protocols to examine the length properly
instead.

Do you prefer adding branches only for allow reading the family of socket 
address?

If the length is zero, there is no point in reading the family.


(Adding LSM people.)

syzbot is reporting that RDS is not checking valid length of address given from 
userspace.
It turned out that there are several users who access "struct sockaddr"->family 
without
checking valid length (which will be reported by KMSAN).

Unfortunately, since tipc_bind() in net/tipc/socket.c accepts length == 0 as a 
valid input,
we can't reject length < offsetofend(struct sockaddr, sa_family) with -EINVAL at
move_addr_to_kernel() which are called from bind()/connect() system calls. I 
proposed
always setting "struct sockaddr"->family at move_addr_to_kernel() but David 
does not
like such trick.

Therefore, LSM modules which checks address and/or port have to check valid 
length
before accessing "struct sockaddr"->family in order to determine IPv4 or IPv6 
or UNIX.

Below is all-in-one change (for x86_64 allmodconfig). Well, I've just realized 
that
move_addr_to_kernel() is also called by sendmsg() system call and for now added 
changes
for only security/ directory. Is this change appropriate for you? (I wish we 
could
simplify this by automatically initializing "struct sockaddr_storage" with 0 at
move_addr_to_kernel()...)
---
  drivers/isdn/mISDN/socket.c |  4 ++--
  net/bluetooth/sco.c |  4 ++--
  net/core/filter.c   |  2 ++
  net/ipv6/udp.c  |  2 ++
  net/llc/af_llc.c|  3 +--
  net/netlink/af_netlink.c|  3 ++-
  net/rds/af_rds.c|  3 +++
  net/rds/bind.c  |  2 ++
  net/rxrpc/af_rxrpc.c|  3 ++-
  net/sctp/socket.c   |  3 ++-
  security/apparmor/lsm.c |  6 ++
  security/selinux/hooks.c| 12 
  security/smack/smack_lsm.c  | 39 +++
  security/tomoyo/network.c   | 12 
  14 files changed, 85 insertions(+), 13 deletions(-)


Except as noted below this looks fine for Smack.


...



diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 5c16135..7c19c04 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -2805,13 +2805,21 @@ static int smack_socket_socketpair(struct socket *socka,
   *
   * Records the label bound to a port.
   *
- * Returns 0
+ * Returns 0 on success, and error code otherwise
   */
  static int smack_socket_bind(struct socket *sock, struct sockaddr *address,
int addrlen)
  {
-   if (sock->sk != NULL && sock->sk->sk_family == PF_INET6)
+   if (sock->sk != NULL && sock->sk->sk_family == PF_INET6) {
+   /*
+* Reject if valid length is too short for IPv6 address or
+* address family is not IPv6.
+*/
+   if (addr_len < SIN6_LEN_RFC2133 ||


 +  if (addrlen < SIN6_LEN_RFC2133 ||
 


+   address->sa_family != AF_INET6)
+   return -EINVAL;
smk_ipv6_port_label(sock, address);
+   }
return 0;
  }
  #endif /* SMACK_IPV6_PORT_LABELING */
@@ -2847,12 +2855,21 @@ static int smack_socket_connect(struct socket *sock, 
struct sockaddr *sap,
  
  	switch (sock->sk->sk_family) {

case PF_INET:
-   if (addrlen < sizeof(struct sockaddr_in))
+   /*
+* Reject if valid length is too short for IPv4 address or
+* address family is not IPv4.
+*/
+   if (addrlen < sizeof(struct sockaddr_in) ||
+   sap->sa_family != AF_INET)
return -EINVAL;
rc = smack_netlabel_send(sock->sk, (struct sockaddr_in *)sap);
break;
case PF_INET6:
-   if (addrlen < sizeof(struct sockaddr_in6))
+   /*
+* Reject if valid length is too short for IPv6 address or
+* address family is not IPv6.
+*/
+   if (addrlen < SIN6_LEN_RFC2133 || sap->sa_family != AF_INET6)
return -EINVAL;
  #ifdef SMACK_IPV6_SECMARK_LABELING
rsp = smack_ipv6host_label(sip);
@@ -3682,9 +3699,23 @@ static int smack_socket_sendmsg(struct socket *sock, 
struct msghdr *msg,
  
  	switch (sock->sk->sk_family) {

case AF_INET:
+   /*
+* Reject if valid length is too short for IPv4 address or
+* address family is not IPv4.
+*/
+   if (msg->msg_namelen < sizeof(struct sockaddr_in) ||
+   sip->sin_family != AF_INET)
+   return -EINVAL;
rc = smack_netlabel_send(so

Re: [PATCH net] ipv6: make icmp6_send() robust against null skb->dev

2019-01-04 Thread Casey Schaufler
On 1/4/2019 11:00 AM, Eric Dumazet wrote:
> syzbot was able to crash one host with the following stack trace :
>
> kasan: GPF could be caused by NULL-ptr deref or user memory access
> general protection fault:  [#1] PREEMPT SMP KASAN
> CPU: 0 PID: 8625 Comm: syz-executor4 Not tainted 4.20.0+ #8
> RIP: 0010:dev_net include/linux/netdevice.h:2169 [inline]
> RIP: 0010:icmp6_send+0x116/0x2d30 net/ipv6/icmp.c:426
>  icmpv6_send
>  smack_socket_sock_rcv_skb
>  security_sock_rcv_skb
>  sk_filter_trim_cap
>  __sk_receive_skb
>  dccp_v6_do_rcv
>  release_sock
>
> This is because a RX packet found socket owned by user and
> was stored into socket backlog. Before leaving RCU protected section,
> skb->dev was cleared in __sk_receive_skb(). When socket backlog
> was finally handled at release_sock() time, skb was fed to
> smack_socket_sock_rcv_skb() then icmp6_send()
>
> We could fix the bug in smack_socket_sock_rcv_skb(), or simply
> make icmp6_send() more robust against such possibility.

The Smack patch would be a trivial check for skb->dev == NULL,
in which case it wouldn't call icmp6_send(). Unless there's a
timing issue, of course. If there are no known timing issues I
would be happy to create a Smack patch to address this problem.

Or, I'm happy with the patch below if you like it.

>
> In the future we might provide to icmp6_send() the net pointer
> instead of infering it.
>
> Fixes: d66a8acbda92 ("Smack: Inform peer that IPv6 traffic has been blocked")
> Signed-off-by: Eric Dumazet 
> Cc: Piotr Sawicki 
> Cc: Casey Schaufler 
> Reported-by: syzbot 
> ---
>  net/ipv6/icmp.c | 8 ++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
> index 
> 5d7aa2c2770ca2b4981d2dd211c3cf0a79a6f9e2..bbcdfd2996926a78c3ea0b274adfa9b5f297efbc
>  100644
> --- a/net/ipv6/icmp.c
> +++ b/net/ipv6/icmp.c
> @@ -423,10 +423,10 @@ static int icmp6_iif(const struct sk_buff *skb)
>  static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
>  const struct in6_addr *force_saddr)
>  {
> - struct net *net = dev_net(skb->dev);
>   struct inet6_dev *idev = NULL;
>   struct ipv6hdr *hdr = ipv6_hdr(skb);
>   struct sock *sk;
> + struct net *net;
>   struct ipv6_pinfo *np;
>   const struct in6_addr *saddr = NULL;
>   struct dst_entry *dst;
> @@ -437,12 +437,16 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 
> code, __u32 info,
>   int iif = 0;
>   int addr_type = 0;
>   int len;
> - u32 mark = IP6_REPLY_MARK(net, skb->mark);
> + u32 mark;
>  
>   if ((u8 *)hdr < skb->head ||
>   (skb_network_header(skb) + sizeof(*hdr)) > skb_tail_pointer(skb))
>   return;
>  
> + if (!skb->dev)
> + return;
> + net = dev_net(skb->dev);
> + mark = IP6_REPLY_MARK(net, skb->mark);
>   /*
>*  Make sure we respect the rules
>*  i.e. RFC 1885 2.4(e)



Re: [PATCH net] ipv6: make icmp6_send() robust against null skb->dev

2019-01-04 Thread Casey Schaufler
On 1/4/2019 11:38 AM, Eric Dumazet wrote:
> On Fri, Jan 4, 2019 at 11:36 AM Casey Schaufler  
> wrote:
>> On 1/4/2019 11:00 AM, Eric Dumazet wrote:
>>> syzbot was able to crash one host with the following stack trace :
>>>
>>> kasan: GPF could be caused by NULL-ptr deref or user memory access
>>> general protection fault:  [#1] PREEMPT SMP KASAN
>>> CPU: 0 PID: 8625 Comm: syz-executor4 Not tainted 4.20.0+ #8
>>> RIP: 0010:dev_net include/linux/netdevice.h:2169 [inline]
>>> RIP: 0010:icmp6_send+0x116/0x2d30 net/ipv6/icmp.c:426
>>>  icmpv6_send
>>>  smack_socket_sock_rcv_skb
>>>  security_sock_rcv_skb
>>>  sk_filter_trim_cap
>>>  __sk_receive_skb
>>>  dccp_v6_do_rcv
>>>  release_sock
>>>
>>> This is because a RX packet found socket owned by user and
>>> was stored into socket backlog. Before leaving RCU protected section,
>>> skb->dev was cleared in __sk_receive_skb(). When socket backlog
>>> was finally handled at release_sock() time, skb was fed to
>>> smack_socket_sock_rcv_skb() then icmp6_send()
>>>
>>> We could fix the bug in smack_socket_sock_rcv_skb(), or simply
>>> make icmp6_send() more robust against such possibility.
>> The Smack patch would be a trivial check for skb->dev == NULL,
>> in which case it wouldn't call icmp6_send(). Unless there's a
>> timing issue, of course. If there are no known timing issues I
>> would be happy to create a Smack patch to address this problem.
>>
>> Or, I'm happy with the patch below if you like it.
>>
> Well, doing the check in icmp6_send() is more generic, this is the path I 
> took,
> thanks ;)
>
>>> In the future we might provide to icmp6_send() the net pointer
>>> instead of infering it.
>>>
>>> Fixes: d66a8acbda92 ("Smack: Inform peer that IPv6 traffic has been 
>>> blocked")
>>> Signed-off-by: Eric Dumazet 
>>> Cc: Piotr Sawicki 
>>> Cc: Casey Schaufler 
>>> Reported-by: syzbot 

OK, you can add my

Acked-by: Casey Schaufler 

>>> ---
>>>  net/ipv6/icmp.c | 8 ++--
>>>  1 file changed, 6 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
>>> index 
>>> 5d7aa2c2770ca2b4981d2dd211c3cf0a79a6f9e2..bbcdfd2996926a78c3ea0b274adfa9b5f297efbc
>>>  100644
>>> --- a/net/ipv6/icmp.c
>>> +++ b/net/ipv6/icmp.c
>>> @@ -423,10 +423,10 @@ static int icmp6_iif(const struct sk_buff *skb)
>>>  static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
>>>  const struct in6_addr *force_saddr)
>>>  {
>>> - struct net *net = dev_net(skb->dev);
>>>   struct inet6_dev *idev = NULL;
>>>   struct ipv6hdr *hdr = ipv6_hdr(skb);
>>>   struct sock *sk;
>>> + struct net *net;
>>>   struct ipv6_pinfo *np;
>>>   const struct in6_addr *saddr = NULL;
>>>   struct dst_entry *dst;
>>> @@ -437,12 +437,16 @@ static void icmp6_send(struct sk_buff *skb, u8 type, 
>>> u8 code, __u32 info,
>>>   int iif = 0;
>>>   int addr_type = 0;
>>>   int len;
>>> - u32 mark = IP6_REPLY_MARK(net, skb->mark);
>>> + u32 mark;
>>>
>>>   if ((u8 *)hdr < skb->head ||
>>>   (skb_network_header(skb) + sizeof(*hdr)) > skb_tail_pointer(skb))
>>>   return;
>>>
>>> + if (!skb->dev)
>>> + return;
>>> + net = dev_net(skb->dev);
>>> + mark = IP6_REPLY_MARK(net, skb->mark);
>>>   /*
>>>*  Make sure we respect the rules
>>>*  i.e. RFC 1885 2.4(e)



Re: [PATCH] selinux:Delete selinux_xfrm_policy_lookup() useless argument

2021-04-08 Thread Casey Schaufler
On 4/8/2021 1:49 AM, Zhongjun Tan wrote:
> From: Zhongjun Tan 
>
> Delete selinux selinux_xfrm_policy_lookup() useless argument.
>
> Signed-off-by: Zhongjun Tan 
> ---
>  include/linux/lsm_hook_defs.h   | 3 +--
>  include/linux/security.h| 4 ++--
>  net/xfrm/xfrm_policy.c  | 6 ++
>  security/security.c | 4 ++--
>  security/selinux/include/xfrm.h | 2 +-
>  security/selinux/xfrm.c | 2 +-
>  6 files changed, 9 insertions(+), 12 deletions(-)
>
> diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
> index 04c0179..2adeea4 100644
> --- a/include/linux/lsm_hook_defs.h
> +++ b/include/linux/lsm_hook_defs.h
> @@ -358,8 +358,7 @@
>struct xfrm_sec_ctx *polsec, u32 secid)
>  LSM_HOOK(void, LSM_RET_VOID, xfrm_state_free_security, struct xfrm_state *x)
>  LSM_HOOK(int, 0, xfrm_state_delete_security, struct xfrm_state *x)
> -LSM_HOOK(int, 0, xfrm_policy_lookup, struct xfrm_sec_ctx *ctx, u32 fl_secid,
> -  u8 dir)
> +LSM_HOOK(int, 0, xfrm_policy_lookup, struct xfrm_sec_ctx *ctx, u32 fl_secid)
>  LSM_HOOK(int, 1, xfrm_state_pol_flow_match, struct xfrm_state *x,
>struct xfrm_policy *xp, const struct flowi_common *flic)
>  LSM_HOOK(int, 0, xfrm_decode_session, struct sk_buff *skb, u32 *secid,

Please update the descriptive comment at the top of the file.

> diff --git a/include/linux/security.h b/include/linux/security.h
> index 06f7c50..24eda04 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -1681,7 +1681,7 @@ int security_xfrm_state_alloc_acquire(struct xfrm_state 
> *x,
> struct xfrm_sec_ctx *polsec, u32 secid);
>  int security_xfrm_state_delete(struct xfrm_state *x);
>  void security_xfrm_state_free(struct xfrm_state *x);
> -int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 
> dir);
> +int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid);
>  int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
>  struct xfrm_policy *xp,
>  const struct flowi_common *flic);
> @@ -1732,7 +1732,7 @@ static inline int security_xfrm_state_delete(struct 
> xfrm_state *x)
>   return 0;
>  }
>  
> -static inline int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 
> fl_secid, u8 dir)
> +static inline int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 
> fl_secid)
>  {
>   return 0;
>  }
> diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
> index 156347f..d5d934e 100644
> --- a/net/xfrm/xfrm_policy.c
> +++ b/net/xfrm/xfrm_policy.c
> @@ -1902,8 +1902,7 @@ static int xfrm_policy_match(const struct xfrm_policy 
> *pol,
>  
>   match = xfrm_selector_match(sel, fl, family);
>   if (match)
> - ret = security_xfrm_policy_lookup(pol->security, 
> fl->flowi_secid,
> -   dir);
> + ret = security_xfrm_policy_lookup(pol->security, 
> fl->flowi_secid);
>   return ret;
>  }
>  
> @@ -2181,8 +2180,7 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(const 
> struct sock *sk, int dir,
>   goto out;
>   }
>   err = security_xfrm_policy_lookup(pol->security,
> -   fl->flowi_secid,
> -   dir);
> +   fl->flowi_secid);
>   if (!err) {
>   if (!xfrm_pol_hold_rcu(pol))
>   goto again;
> diff --git a/security/security.c b/security/security.c
> index b38155b..0c1c979 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -2466,9 +2466,9 @@ void security_xfrm_state_free(struct xfrm_state *x)
>   call_void_hook(xfrm_state_free_security, x);
>  }
>  
> -int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 
> dir)
> +int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid)
>  {
> - return call_int_hook(xfrm_policy_lookup, 0, ctx, fl_secid, dir);
> + return call_int_hook(xfrm_policy_lookup, 0, ctx, fl_secid);
>  }
>  
>  int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
> diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
> index 0a6f34a..7415940 100644
> --- a/security/selinux/include/xfrm.h
> +++ b/security/selinux/include/xfrm.h
> @@ -23,7 +23,7 @@ int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x,
>struct xfrm_sec_ctx *polsec, u32 secid);
>  void selinux_xfrm_state_free(struct xfrm_state *x);
>  int selinux_xfrm_state_delete(struct xfrm_state *x);
> -int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 
> dir);
> +int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid);
>  int selinux_xfrm_state_pol_flow_match(struct 

[PATCH v19 06/23] LSM: Use lsmblob in security_secctx_to_secid

2020-07-24 Thread Casey Schaufler
Change security_secctx_to_secid() to fill in a lsmblob instead
of a u32 secid. Multiple LSMs may be able to interpret the
string, and this allows for setting whichever secid is
appropriate. Change security_secmark_relabel_packet() to use a
lsmblob instead of a u32 secid. In some other cases there is
scaffolding where interfaces have yet to be converted.

Reviewed-by: Kees Cook 
Signed-off-by: Casey Schaufler 
Cc: netdev@vger.kernel.org
---
 include/linux/security.h  | 30 +++
 include/net/scm.h |  7 +--
 kernel/cred.c |  4 +---
 net/ipv4/ip_sockglue.c|  6 --
 net/netfilter/nft_meta.c  | 18 +---
 net/netfilter/xt_SECMARK.c|  9 ++--
 net/netlabel/netlabel_unlabeled.c | 23 +
 security/security.c   | 34 ++-
 8 files changed, 98 insertions(+), 33 deletions(-)

diff --git a/include/linux/security.h b/include/linux/security.h
index d81e8886d799..98176faaaba5 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -189,6 +189,27 @@ static inline bool lsmblob_equal(struct lsmblob *bloba, 
struct lsmblob *blobb)
return !memcmp(bloba, blobb, sizeof(*bloba));
 }
 
+/**
+ * lsmblob_value - find the first non-zero value in an lsmblob structure.
+ * @blob: Pointer to the data
+ *
+ * This needs to be used with extreme caution, as the cases where
+ * it is appropriate are rare.
+ *
+ * Return the first secid value set in the lsmblob.
+ * There should only be one.
+ */
+static inline u32 lsmblob_value(const struct lsmblob *blob)
+{
+   int i;
+
+   for (i = 0; i < LSMBLOB_ENTRIES; i++)
+   if (blob->secid[i])
+   return blob->secid[i];
+
+   return 0;
+}
+
 /* These functions are in security/commoncap.c */
 extern int cap_capable(const struct cred *cred, struct user_namespace *ns,
   int cap, unsigned int opts);
@@ -502,7 +523,8 @@ int security_setprocattr(const char *lsm, const char *name, 
void *value,
 int security_netlink_send(struct sock *sk, struct sk_buff *skb);
 int security_ismaclabel(const char *name);
 int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
-int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
+int security_secctx_to_secid(const char *secdata, u32 seclen,
+struct lsmblob *blob);
 void security_release_secctx(char *secdata, u32 seclen);
 void security_inode_invalidate_secctx(struct inode *inode);
 int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
@@ -1321,7 +1343,7 @@ static inline int security_secid_to_secctx(u32 secid, 
char **secdata, u32 *secle
 
 static inline int security_secctx_to_secid(const char *secdata,
   u32 seclen,
-  u32 *secid)
+  struct lsmblob *blob)
 {
return -EOPNOTSUPP;
 }
@@ -1411,7 +1433,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 lsmblob *blob);
 void security_secmark_refcount_inc(void);
 void security_secmark_refcount_dec(void);
 int security_tun_dev_alloc_security(void **security);
@@ -1584,7 +1606,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 lsmblob *blob)
 {
return 0;
 }
diff --git a/include/net/scm.h b/include/net/scm.h
index e2e71c4bf9d0..c09f2dfeec88 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -97,8 +97,11 @@ static inline void scm_passec(struct socket *sock, struct 
msghdr *msg, struct sc
int err;
 
if (test_bit(SOCK_PASSSEC, &sock->flags)) {
-   /* Scaffolding - it has to be element 0 for now */
-   err = security_secid_to_secctx(scm->lsmblob.secid[0],
+   /* There can currently be only one value in the lsmblob,
+* so getting it from lsmblob_value is appropriate until
+* security_secid_to_secctx() is converted to taking a
+* lsmblob directly. */
+   err = security_secid_to_secctx(lsmblob_value(&scm->lsmblob),
   &secdata, &seclen);
 
if (!err) {
diff --git a/kernel/cred.c b/kernel/cred.c
index 22e0e7cbefde..848306c7d823 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -757,14 +757,12 @@ EXPORT_SYMBOL(set_security_override);
 int set_security_override_from_ctx(struct cred *new, const char *secctx)
 {
struct lsmblob blob;
-   u32 sec

[PATCH v19 14/23] LSM: Ensure the correct LSM context releaser

2020-07-24 Thread Casey Schaufler
Add a new lsmcontext data structure to hold all the information
about a "security context", including the string, its size and
which LSM allocated the string. The allocation information is
necessary because LSMs have different policies regarding the
lifecycle of these strings. SELinux allocates and destroys
them on each use, whereas Smack provides a pointer to an entry
in a list that never goes away.

Reviewed-by: Kees Cook 
Reviewed-by: John Johansen 
Acked-by: Stephen Smalley 
Signed-off-by: Casey Schaufler 
Cc: linux-integr...@vger.kernel.org
Cc: netdev@vger.kernel.org
---
 drivers/android/binder.c| 10 ---
 fs/ceph/xattr.c |  6 -
 fs/nfs/nfs4proc.c   |  8 --
 fs/nfsd/nfs4xdr.c   |  7 +++--
 include/linux/security.h| 35 +++--
 include/net/scm.h   |  5 +++-
 kernel/audit.c  | 14 +++---
 kernel/auditsc.c| 12 ++---
 net/ipv4/ip_sockglue.c  |  4 ++-
 net/netfilter/nf_conntrack_netlink.c|  4 ++-
 net/netfilter/nf_conntrack_standalone.c |  4 ++-
 net/netfilter/nfnetlink_queue.c | 13 ++---
 net/netlabel/netlabel_unlabeled.c   | 19 +++---
 net/netlabel/netlabel_user.c|  4 ++-
 security/security.c | 11 
 15 files changed, 121 insertions(+), 35 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 46e2a26089cc..b7ab206f8bb3 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2863,6 +2863,7 @@ static void binder_transaction(struct binder_proc *proc,
int t_debug_id = atomic_inc_return(&binder_last_id);
char *secctx = NULL;
u32 secctx_sz = 0;
+   struct lsmcontext scaff; /* scaffolding */
 
e = binder_transaction_log_add(&binder_transaction_log);
e->debug_id = t_debug_id;
@@ -3159,7 +3160,8 @@ static void binder_transaction(struct binder_proc *proc,
t->security_ctx = 0;
WARN_ON(1);
}
-   security_release_secctx(secctx, secctx_sz);
+   lsmcontext_init(&scaff, secctx, secctx_sz, 0);
+   security_release_secctx(&scaff);
secctx = NULL;
}
t->buffer->debug_id = t->debug_id;
@@ -3492,8 +3494,10 @@ static void binder_transaction(struct binder_proc *proc,
binder_alloc_free_buf(&target_proc->alloc, t->buffer);
 err_binder_alloc_buf_failed:
 err_bad_extra_size:
-   if (secctx)
-   security_release_secctx(secctx, secctx_sz);
+   if (secctx) {
+   lsmcontext_init(&scaff, secctx, secctx_sz, 0);
+   security_release_secctx(&scaff);
+   }
 err_get_secctx_failed:
kfree(tcomplete);
binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c
index 71ee34d160c3..ad36d5fd7a84 100644
--- a/fs/ceph/xattr.c
+++ b/fs/ceph/xattr.c
@@ -1272,12 +1272,16 @@ int ceph_security_init_secctx(struct dentry *dentry, 
umode_t mode,
 
 void ceph_release_acl_sec_ctx(struct ceph_acl_sec_ctx *as_ctx)
 {
+#ifdef CONFIG_CEPH_FS_SECURITY_LABEL
+   struct lsmcontext scaff; /* scaffolding */
+#endif
 #ifdef CONFIG_CEPH_FS_POSIX_ACL
posix_acl_release(as_ctx->acl);
posix_acl_release(as_ctx->default_acl);
 #endif
 #ifdef CONFIG_CEPH_FS_SECURITY_LABEL
-   security_release_secctx(as_ctx->sec_ctx, as_ctx->sec_ctxlen);
+   lsmcontext_init(&scaff, as_ctx->sec_ctx, as_ctx->sec_ctxlen, 0);
+   security_release_secctx(&scaff);
 #endif
if (as_ctx->pagelist)
ceph_pagelist_release(as_ctx->pagelist);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 2e2dac29a9e9..8fe09ce2eff7 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -130,8 +130,12 @@ nfs4_label_init_security(struct inode *dir, struct dentry 
*dentry,
 static inline void
 nfs4_label_release_security(struct nfs4_label *label)
 {
-   if (label)
-   security_release_secctx(label->label, label->len);
+   struct lsmcontext scaff; /* scaffolding */
+
+   if (label) {
+   lsmcontext_init(&scaff, label->label, label->len, 0);
+   security_release_secctx(&scaff);
+   }
 }
 static inline u32 *nfs4_bitmask(struct nfs_server *server, struct nfs4_label 
*label)
 {
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 996ac01ee977..61d6b8a0e8f0 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2496,6 +2496,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh 
*fhp,
int err;
struct nfs4_acl *acl = NULL;
 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
+   struct lsmcontext scaff; /* scaffolding */
void *context = NULL;
int contextlen;

[PATCH v19 15/23] LSM: Use lsmcontext in security_secid_to_secctx

2020-07-24 Thread Casey Schaufler
Replace the (secctx,seclen) pointer pair with a single
lsmcontext pointer to allow return of the LSM identifier
along with the context and context length. This allows
security_release_secctx() to know how to release the
context. Callers have been modified to use or save the
returned data from the new structure.

Reviewed-by: Kees Cook 
Acked-by: Stephen Smalley 
Acked-by: Paul Moore 
Signed-off-by: Casey Schaufler 
Cc: netdev@vger.kernel.org
---
 drivers/android/binder.c| 26 +++-
 include/linux/security.h|  4 +--
 include/net/scm.h   | 10 ++-
 kernel/audit.c  | 35 --
 kernel/auditsc.c| 31 +++
 net/ipv4/ip_sockglue.c  |  7 ++---
 net/netfilter/nf_conntrack_netlink.c| 18 +--
 net/netfilter/nf_conntrack_standalone.c |  7 ++---
 net/netfilter/nfnetlink_queue.c |  5 +++-
 net/netlabel/netlabel_unlabeled.c   | 40 -
 net/netlabel/netlabel_user.c|  7 ++---
 security/security.c | 10 +--
 12 files changed, 76 insertions(+), 124 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index b7ab206f8bb3..ceb5987c7d76 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2861,9 +2861,7 @@ static void binder_transaction(struct binder_proc *proc,
binder_size_t last_fixup_min_off = 0;
struct binder_context *context = proc->context;
int t_debug_id = atomic_inc_return(&binder_last_id);
-   char *secctx = NULL;
-   u32 secctx_sz = 0;
-   struct lsmcontext scaff; /* scaffolding */
+   struct lsmcontext lsmctx = { };
 
e = binder_transaction_log_add(&binder_transaction_log);
e->debug_id = t_debug_id;
@@ -3111,14 +3109,14 @@ static void binder_transaction(struct binder_proc *proc,
size_t added_size;
 
security_task_getsecid(proc->tsk, &blob);
-   ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz);
+   ret = security_secid_to_secctx(&blob, &lsmctx);
if (ret) {
return_error = BR_FAILED_REPLY;
return_error_param = ret;
return_error_line = __LINE__;
goto err_get_secctx_failed;
}
-   added_size = ALIGN(secctx_sz, sizeof(u64));
+   added_size = ALIGN(lsmctx.len, sizeof(u64));
extra_buffers_size += added_size;
if (extra_buffers_size < added_size) {
/* integer overflow of extra_buffers_size */
@@ -3145,24 +3143,22 @@ static void binder_transaction(struct binder_proc *proc,
t->buffer = NULL;
goto err_binder_alloc_buf_failed;
}
-   if (secctx) {
+   if (lsmctx.context) {
int err;
size_t buf_offset = ALIGN(tr->data_size, sizeof(void *)) +
ALIGN(tr->offsets_size, sizeof(void *)) +
ALIGN(extra_buffers_size, sizeof(void *)) -
-   ALIGN(secctx_sz, sizeof(u64));
+   ALIGN(lsmctx.len, sizeof(u64));
 
t->security_ctx = (uintptr_t)t->buffer->user_data + buf_offset;
err = binder_alloc_copy_to_buffer(&target_proc->alloc,
  t->buffer, buf_offset,
- secctx, secctx_sz);
+ lsmctx.context, lsmctx.len);
if (err) {
t->security_ctx = 0;
WARN_ON(1);
}
-   lsmcontext_init(&scaff, secctx, secctx_sz, 0);
-   security_release_secctx(&scaff);
-   secctx = NULL;
+   security_release_secctx(&lsmctx);
}
t->buffer->debug_id = t->debug_id;
t->buffer->transaction = t;
@@ -3218,7 +3214,7 @@ static void binder_transaction(struct binder_proc *proc,
off_end_offset = off_start_offset + tr->offsets_size;
sg_buf_offset = ALIGN(off_end_offset, sizeof(void *));
sg_buf_end_offset = sg_buf_offset + extra_buffers_size -
-   ALIGN(secctx_sz, sizeof(u64));
+   ALIGN(lsmctx.len, sizeof(u64));
off_min = 0;
for (buffer_offset = off_start_offset; buffer_offset < off_end_offset;
 buffer_offset += sizeof(binder_size_t)) {
@@ -3494,10 +3490,8 @@ static void binder_transaction(struct binder_proc *proc,
binder_alloc_free_buf(&target_proc->alloc, t->buffer);
 err_binder_alloc_buf_failed:
 err_bad_extra_size:
-   if (secctx) {
- 

[PATCH v19 17/23] LSM: security_secid_to_secctx in netlink netfilter

2020-07-24 Thread Casey Schaufler
Change netlink netfilter interfaces to use lsmcontext
pointers, and remove scaffolding.

Reviewed-by: Kees Cook 
Reviewed-by: John Johansen 
Acked-by: Stephen Smalley 
Signed-off-by: Casey Schaufler 
cc: netdev@vger.kernel.org
---
 net/netfilter/nfnetlink_queue.c | 31 ---
 1 file changed, 12 insertions(+), 19 deletions(-)

diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index fe19ae7216db..a4d4602ab9b7 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -301,12 +301,10 @@ static int nfqnl_put_sk_uidgid(struct sk_buff *skb, 
struct sock *sk)
return -1;
 }
 
-static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata)
+static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, struct lsmcontext *context)
 {
-   u32 seclen = 0;
 #if IS_ENABLED(CONFIG_NETWORK_SECMARK)
struct lsmblob blob;
-   struct lsmcontext context = { };
 
if (!skb || !sk_fullsock(skb->sk))
return 0;
@@ -318,14 +316,14 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char 
**secdata)
 * blob. security_secid_to_secctx() will know which security
 * module to use to create the secctx.  */
lsmblob_init(&blob, skb->secmark);
-   security_secid_to_secctx(&blob, &context);
-   *secdata = context.context;
+   security_secid_to_secctx(&blob, context);
}
 
read_unlock_bh(&skb->sk->sk_callback_lock);
-   seclen = context.len;
+   return context->len;
+#else
+   return 0;
 #endif
-   return seclen;
 }
 
 static u32 nfqnl_get_bridge_size(struct nf_queue_entry *entry)
@@ -401,8 +399,7 @@ nfqnl_build_packet_message(struct net *net, struct 
nfqnl_instance *queue,
enum ip_conntrack_info uninitialized_var(ctinfo);
struct nfnl_ct_hook *nfnl_ct;
bool csum_verify;
-   struct lsmcontext scaff; /* scaffolding */
-   char *secdata = NULL;
+   struct lsmcontext context = { };
u32 seclen = 0;
 
size = nlmsg_total_size(sizeof(struct nfgenmsg))
@@ -469,7 +466,7 @@ nfqnl_build_packet_message(struct net *net, struct 
nfqnl_instance *queue,
}
 
if ((queue->flags & NFQA_CFG_F_SECCTX) && entskb->sk) {
-   seclen = nfqnl_get_sk_secctx(entskb, &secdata);
+   seclen = nfqnl_get_sk_secctx(entskb, &context);
if (seclen)
size += nla_total_size(seclen);
}
@@ -604,7 +601,7 @@ nfqnl_build_packet_message(struct net *net, struct 
nfqnl_instance *queue,
nfqnl_put_sk_uidgid(skb, entskb->sk) < 0)
goto nla_put_failure;
 
-   if (seclen && nla_put(skb, NFQA_SECCTX, seclen, secdata))
+   if (seclen && nla_put(skb, NFQA_SECCTX, context.len, context.context))
goto nla_put_failure;
 
if (ct && nfnl_ct->build(skb, ct, ctinfo, NFQA_CT, NFQA_CT_INFO) < 0)
@@ -632,10 +629,8 @@ nfqnl_build_packet_message(struct net *net, struct 
nfqnl_instance *queue,
}
 
nlh->nlmsg_len = skb->len;
-   if (seclen) {
-   lsmcontext_init(&scaff, secdata, seclen, 0);
-   security_release_secctx(&scaff);
-   }
+   if (seclen)
+   security_release_secctx(&context);
return skb;
 
 nla_put_failure:
@@ -643,10 +638,8 @@ nfqnl_build_packet_message(struct net *net, struct 
nfqnl_instance *queue,
kfree_skb(skb);
net_err_ratelimited("nf_queue: error creating packet message\n");
 nlmsg_failure:
-   if (seclen) {
-   lsmcontext_init(&scaff, secdata, seclen, 0);
-   security_release_secctx(&scaff);
-   }
+   if (seclen)
+   security_release_secctx(&context);
return NULL;
 }
 
-- 
2.24.1



[PATCH v19 18/23] NET: Store LSM netlabel data in a lsmblob

2020-07-24 Thread Casey Schaufler
Netlabel uses LSM interfaces requiring an lsmblob and
the internal storage is used to pass information between
these interfaces, so change the internal data from a secid
to a lsmblob. Update the netlabel interfaces and their
callers to accommodate the change. This requires that the
modules using netlabel use the lsm_id.slot to access the
correct secid when using netlabel.

Reviewed-by: Kees Cook 
Reviewed-by: John Johansen 
Acked-by: Stephen Smalley 
Signed-off-by: Casey Schaufler 
Cc: netdev@vger.kernel.org
---
 include/net/netlabel.h  |  8 +--
 net/ipv4/cipso_ipv4.c   | 27 ++
 net/netlabel/netlabel_kapi.c|  6 +--
 net/netlabel/netlabel_unlabeled.c   | 79 +
 net/netlabel/netlabel_unlabeled.h   |  2 +-
 security/selinux/hooks.c|  2 +-
 security/selinux/include/security.h |  1 +
 security/selinux/netlabel.c |  2 +-
 security/selinux/ss/services.c  |  4 +-
 security/smack/smack.h  |  1 +
 security/smack/smack_lsm.c  |  5 +-
 security/smack/smackfs.c| 10 ++--
 12 files changed, 65 insertions(+), 82 deletions(-)

diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index 43ae50337685..73fc25b4042b 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -166,7 +166,7 @@ struct netlbl_lsm_catmap {
  * @attr.mls: MLS sensitivity label
  * @attr.mls.cat: MLS category bitmap
  * @attr.mls.lvl: MLS sensitivity level
- * @attr.secid: LSM specific secid token
+ * @attr.lsmblob: LSM specific data
  *
  * Description:
  * This structure is used to pass security attributes between NetLabel and the
@@ -201,7 +201,7 @@ struct netlbl_lsm_secattr {
struct netlbl_lsm_catmap *cat;
u32 lvl;
} mls;
-   u32 secid;
+   struct lsmblob lsmblob;
} attr;
 };
 
@@ -415,7 +415,7 @@ int netlbl_cfg_unlbl_static_add(struct net *net,
const void *addr,
const void *mask,
u16 family,
-   u32 secid,
+   struct lsmblob *lsmblob,
struct netlbl_audit *audit_info);
 int netlbl_cfg_unlbl_static_del(struct net *net,
const char *dev_name,
@@ -523,7 +523,7 @@ static inline int netlbl_cfg_unlbl_static_add(struct net 
*net,
  const void *addr,
  const void *mask,
  u16 family,
- u32 secid,
+ struct lsmblob *lsmblob,
  struct netlbl_audit *audit_info)
 {
return -ENOSYS;
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index a23094b050f8..469baf6704f5 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -106,15 +106,17 @@ int cipso_v4_rbm_strictvalid = 1;
 /* Base length of the local tag (non-standard tag).
  *  Tag definition (may change between kernel versions)
  *
- * 0  8  16 24 32
- * +--+--+--+--+
- * | 1000 | 0110 | 32-bit secid value  |
- * +--+--+--+--+
- * | in (host byte order)|
- * +--+--+
- *
+ * 0  8  1616 + sizeof(struct lsmblob)
+ * +--+--+-+
+ * | 1000 | 0110 | LSM blob data   |
+ * +--+--+-+
+ *
+ * All secid and flag fields are in host byte order.
+ * The lsmblob structure size varies depending on which
+ * Linux security modules are built in the kernel.
+ * The data is opaque.
  */
-#define CIPSO_V4_TAG_LOC_BLEN 6
+#define CIPSO_V4_TAG_LOC_BLEN (2 + sizeof(struct lsmblob))
 
 /*
  * Helper Functions
@@ -1469,7 +1471,12 @@ static int cipso_v4_gentag_loc(const struct cipso_v4_doi 
*doi_def,
 
buffer[0] = CIPSO_V4_TAG_LOCAL;
buffer[1] = CIPSO_V4_TAG_LOC_BLEN;
-   *(u32 *)&buffer[2] = secattr->attr.secid;
+   /* Ensure that there is sufficient space in the CIPSO header
+* for the LSM data. This should never become an issue.
+* The check is made from an abundance of caution. */
+   BUILD_BUG_ON(CIPSO_V4_TAG_LOC_BLEN > CIPSO_V4_OPT_LEN_MAX);
+   memcpy(&buffer[2], &secattr->attr.lsmblob,
+  sizeof(secattr->attr.lsmblob));
 
return CIPSO_V4_TAG_LOC_BLEN;
 }
@@ -1489,7 +1496,7 @@ static int cipso_v4_parsetag_loc(const struct 
cipso_v4_doi *doi_def,
 const unsigned char *tag,
 struct netlbl_lsm_secattr *secattr)
 {
-   secattr->attr.secid = *(u32 *)&tag[2];
+   memcpy(&secattr->

Re: [PATCH v19 06/23] LSM: Use lsmblob in security_secctx_to_secid

2020-07-28 Thread Casey Schaufler
On 7/28/2020 4:11 AM, John Johansen wrote:
> On 7/24/20 1:32 PM, Casey Schaufler wrote:
>> Change security_secctx_to_secid() to fill in a lsmblob instead
>> of a u32 secid. Multiple LSMs may be able to interpret the
>> string, and this allows for setting whichever secid is
>> appropriate. Change security_secmark_relabel_packet() to use a
>> lsmblob instead of a u32 secid. In some other cases there is
>> scaffolding where interfaces have yet to be converted.
>>
>> Reviewed-by: Kees Cook 
>> Signed-off-by: Casey Schaufler 
>> Cc: netdev@vger.kernel.org
> one comment below, but its a nice to have so
>
> Reviewed-by: John Johansen 
>
>
>> ---
>>  include/linux/security.h  | 30 +++
>>  include/net/scm.h |  7 +--
>>  kernel/cred.c |  4 +---
>>  net/ipv4/ip_sockglue.c|  6 --
>>  net/netfilter/nft_meta.c  | 18 +---
>>  net/netfilter/xt_SECMARK.c|  9 ++--
>>  net/netlabel/netlabel_unlabeled.c | 23 +
>>  security/security.c   | 34 ++-
>>  8 files changed, 98 insertions(+), 33 deletions(-)
>>
>> diff --git a/include/linux/security.h b/include/linux/security.h
>> index d81e8886d799..98176faaaba5 100644
>> --- a/include/linux/security.h
>> +++ b/include/linux/security.h
>> @@ -189,6 +189,27 @@ static inline bool lsmblob_equal(struct lsmblob *bloba, 
>> struct lsmblob *blobb)
>>  return !memcmp(bloba, blobb, sizeof(*bloba));
>>  }
>>  
>> +/**
>> + * lsmblob_value - find the first non-zero value in an lsmblob structure.
>> + * @blob: Pointer to the data
>> + *
>> + * This needs to be used with extreme caution, as the cases where
>> + * it is appropriate are rare.
>> + *
>> + * Return the first secid value set in the lsmblob.
>> + * There should only be one.
> It would be really nice if we could have an LSM debug config, that would
> do things like checking there is indeed only one value when this fn
> is called.

I can't see a CONFIG_LSM_DEBUG for this alone, but if you have
other places you'd like to see it I'm open to it.



[PATCH v25 07/25] LSM: Use lsmblob in security_secctx_to_secid

2021-03-09 Thread Casey Schaufler
Change the security_secctx_to_secid interface to use a lsmblob
structure in place of the single u32 secid in support of
module stacking. Change its callers to do the same.

The security module hook is unchanged, still passing back a secid.
The infrastructure passes the correct entry from the lsmblob.

Signed-off-by: Casey Schaufler 
Cc: netdev@vger.kernel.org
Cc: netfilter-de...@vger.kernel.org
To: Pablo Neira Ayuso 
---
 include/linux/security.h  | 26 ++--
 kernel/cred.c |  4 +---
 net/netfilter/nft_meta.c  | 10 
 net/netfilter/xt_SECMARK.c|  7 +-
 net/netlabel/netlabel_unlabeled.c | 23 +++---
 security/security.c   | 40 ++-
 6 files changed, 85 insertions(+), 25 deletions(-)

diff --git a/include/linux/security.h b/include/linux/security.h
index b63a14866464..1a1fbe0746a0 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -196,6 +196,27 @@ static inline bool lsmblob_equal(struct lsmblob *bloba, 
struct lsmblob *blobb)
 extern int lsm_name_to_slot(char *name);
 extern const char *lsm_slot_to_name(int slot);
 
+/**
+ * lsmblob_value - find the first non-zero value in an lsmblob structure.
+ * @blob: Pointer to the data
+ *
+ * This needs to be used with extreme caution, as the cases where
+ * it is appropriate are rare.
+ *
+ * Return the first secid value set in the lsmblob.
+ * There should only be one.
+ */
+static inline u32 lsmblob_value(const struct lsmblob *blob)
+{
+   int i;
+
+   for (i = 0; i < LSMBLOB_ENTRIES; i++)
+   if (blob->secid[i])
+   return blob->secid[i];
+
+   return 0;
+}
+
 /* These functions are in security/commoncap.c */
 extern int cap_capable(const struct cred *cred, struct user_namespace *ns,
   int cap, unsigned int opts);
@@ -524,7 +545,8 @@ int security_setprocattr(const char *lsm, const char *name, 
void *value,
 int security_netlink_send(struct sock *sk, struct sk_buff *skb);
 int security_ismaclabel(const char *name);
 int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
-int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
+int security_secctx_to_secid(const char *secdata, u32 seclen,
+struct lsmblob *blob);
 void security_release_secctx(char *secdata, u32 seclen);
 void security_inode_invalidate_secctx(struct inode *inode);
 int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
@@ -1364,7 +1386,7 @@ static inline int security_secid_to_secctx(u32 secid, 
char **secdata, u32 *secle
 
 static inline int security_secctx_to_secid(const char *secdata,
   u32 seclen,
-  u32 *secid)
+  struct lsmblob *blob)
 {
return -EOPNOTSUPP;
 }
diff --git a/kernel/cred.c b/kernel/cred.c
index 22e0e7cbefde..848306c7d823 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -757,14 +757,12 @@ EXPORT_SYMBOL(set_security_override);
 int set_security_override_from_ctx(struct cred *new, const char *secctx)
 {
struct lsmblob blob;
-   u32 secid;
int ret;
 
-   ret = security_secctx_to_secid(secctx, strlen(secctx), &secid);
+   ret = security_secctx_to_secid(secctx, strlen(secctx), &blob);
if (ret < 0)
return ret;
 
-   lsmblob_init(&blob, secid);
return set_security_override(new, &blob);
 }
 EXPORT_SYMBOL(set_security_override_from_ctx);
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index a7e01e9952f1..f9448e81798e 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -809,21 +809,21 @@ 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 lsmblob blob;
int err;
 
-   err = security_secctx_to_secid(priv->ctx, strlen(priv->ctx), 
&tmp_secid);
+   err = security_secctx_to_secid(priv->ctx, strlen(priv->ctx), &blob);
if (err)
return err;
 
-   if (!tmp_secid)
+   if (!lsmblob_is_set(&blob))
return -ENOENT;
 
-   err = security_secmark_relabel_packet(tmp_secid);
+   err = security_secmark_relabel_packet(lsmblob_value(&blob));
if (err)
return err;
 
-   priv->secid = tmp_secid;
+   priv->secid = lsmblob_value(&blob);
return 0;
 }
 
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c
index 75625d13e976..9845d98e6b77 100644
--- a/net/netfilter/xt_SECMARK.c
+++ b/net/netfilter/xt_SECMARK.c
@@ -43,13 +43,14 @@ secmark_tg(struct sk_buff *skb, const struct 
xt_action_param *par)
 
 static int checkentry_lsm(struct xt_secmark_target_info *info)
 {
+   struct lsmblo

[PATCH v25 08/25] LSM: Use lsmblob in security_secid_to_secctx

2021-03-09 Thread Casey Schaufler
Change security_secid_to_secctx() to take a lsmblob as input
instead of a u32 secid. It will then call the LSM hooks
using the lsmblob element allocated for that module. The
callers have been updated as well. This allows for the
possibility that more than one module may be called upon
to translate a secid to a string, as can occur in the
audit code.

Signed-off-by: Casey Schaufler 
Cc: netdev@vger.kernel.org
Cc: linux-au...@redhat.com
Cc: netfilter-de...@vger.kernel.org
To: Pablo Neira Ayuso 
To: Paul Moore 
---
 drivers/android/binder.c| 12 +-
 include/linux/security.h|  5 +++--
 include/net/scm.h   |  7 +-
 kernel/audit.c  | 20 +++--
 kernel/auditsc.c| 28 +++
 net/ipv4/ip_sockglue.c  |  4 +++-
 net/netfilter/nf_conntrack_netlink.c| 14 ++--
 net/netfilter/nf_conntrack_standalone.c |  4 +++-
 net/netfilter/nfnetlink_queue.c | 11 +++--
 net/netlabel/netlabel_unlabeled.c   | 30 +
 net/netlabel/netlabel_user.c|  6 ++---
 security/security.c | 11 +
 12 files changed, 123 insertions(+), 29 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index c119736ca56a..5fb8555ce166 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2698,10 +2698,20 @@ static void binder_transaction(struct binder_proc *proc,
 
if (target_node && target_node->txn_security_ctx) {
u32 secid;
+   struct lsmblob blob;
size_t added_size;
 
security_task_getsecid(proc->tsk, &secid);
-   ret = security_secid_to_secctx(secid, &secctx, &secctx_sz);
+   /*
+* Later in this patch set security_task_getsecid() will
+* provide a lsmblob instead of a secid. lsmblob_init
+* is used to ensure that all the secids in the lsmblob
+* get the value returned from security_task_getsecid(),
+* which means that the one expected by
+* security_secid_to_secctx() will be set.
+*/
+   lsmblob_init(&blob, secid);
+   ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz);
if (ret) {
return_error = BR_FAILED_REPLY;
return_error_param = ret;
diff --git a/include/linux/security.h b/include/linux/security.h
index 1a1fbe0746a0..01bf23c68847 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -544,7 +544,7 @@ int security_setprocattr(const char *lsm, const char *name, 
void *value,
 size_t size);
 int security_netlink_send(struct sock *sk, struct sk_buff *skb);
 int security_ismaclabel(const char *name);
-int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
+int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 
*seclen);
 int security_secctx_to_secid(const char *secdata, u32 seclen,
 struct lsmblob *blob);
 void security_release_secctx(char *secdata, u32 seclen);
@@ -1379,7 +1379,8 @@ static inline int security_ismaclabel(const char *name)
return 0;
 }
 
-static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 
*seclen)
+static inline int security_secid_to_secctx(struct lsmblob *blob,
+  char **secdata, u32 *seclen)
 {
return -EOPNOTSUPP;
 }
diff --git a/include/net/scm.h b/include/net/scm.h
index 1ce365f4c256..23a35ff1b3f2 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -92,12 +92,17 @@ static __inline__ int scm_send(struct socket *sock, struct 
msghdr *msg,
 #ifdef CONFIG_SECURITY_NETWORK
 static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct 
scm_cookie *scm)
 {
+   struct lsmblob lb;
char *secdata;
u32 seclen;
int err;
 
if (test_bit(SOCK_PASSSEC, &sock->flags)) {
-   err = security_secid_to_secctx(scm->secid, &secdata, &seclen);
+   /* There can only be one security module using the secid,
+* and the infrastructure will know which it is.
+*/
+   lsmblob_init(&lb, scm->secid);
+   err = security_secid_to_secctx(&lb, &secdata, &seclen);
 
if (!err) {
put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, 
secdata);
diff --git a/kernel/audit.c b/kernel/audit.c
index 551a394bc8f4..fcbdce83a9d8 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1442,7 +1442,16 @@ static int audit_receive_msg(struct sk_buff *skb, struct 
nlmsghdr *nlh)
case AUDIT_SIGNAL_INFO:
len = 0;
if (audit_sig_sid) {
- 

[PATCH v25 10/25] LSM: Use lsmblob in security_task_getsecid

2021-03-09 Thread Casey Schaufler
Change the security_task_getsecid() interface to fill in
a lsmblob structure instead of a u32 secid in support of
LSM stacking. Audit interfaces will need to collect all
possible secids for possible reporting.

Reviewed-by: Kees Cook 
Reviewed-by: John Johansen 
Acked-by: Stephen Smalley 
Acked-by: Paul Moore 
Signed-off-by: Casey Schaufler 
Cc: linux-integr...@vger.kernel.org
Cc: linux-au...@redhat.com
Cc: netdev@vger.kernel.org
---
 drivers/android/binder.c  | 12 +-
 include/linux/security.h  |  7 ++--
 kernel/audit.c| 16 +++-
 kernel/auditfilter.c  |  4 +-
 kernel/auditsc.c  | 25 ++--
 net/netlabel/netlabel_unlabeled.c |  5 ++-
 net/netlabel/netlabel_user.h  |  6 ++-
 security/integrity/ima/ima_appraise.c | 10 +++--
 security/integrity/ima/ima_main.c | 56 +++
 security/security.c   | 12 --
 10 files changed, 80 insertions(+), 73 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 5fb8555ce166..1a15e9e19e22 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2697,20 +2697,10 @@ static void binder_transaction(struct binder_proc *proc,
t->priority = task_nice(current);
 
if (target_node && target_node->txn_security_ctx) {
-   u32 secid;
struct lsmblob blob;
size_t added_size;
 
-   security_task_getsecid(proc->tsk, &secid);
-   /*
-* Later in this patch set security_task_getsecid() will
-* provide a lsmblob instead of a secid. lsmblob_init
-* is used to ensure that all the secids in the lsmblob
-* get the value returned from security_task_getsecid(),
-* which means that the one expected by
-* security_secid_to_secctx() will be set.
-*/
-   lsmblob_init(&blob, secid);
+   security_task_getsecid(proc->tsk, &blob);
ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz);
if (ret) {
return_error = BR_FAILED_REPLY;
diff --git a/include/linux/security.h b/include/linux/security.h
index 4f5bc3b424e4..852a4764a609 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -498,7 +498,7 @@ int security_task_fix_setgid(struct cred *new, const struct 
cred *old,
 int security_task_setpgid(struct task_struct *p, pid_t pgid);
 int security_task_getpgid(struct task_struct *p);
 int security_task_getsid(struct task_struct *p);
-void security_task_getsecid(struct task_struct *p, u32 *secid);
+void security_task_getsecid(struct task_struct *p, struct lsmblob *blob);
 int security_task_setnice(struct task_struct *p, int nice);
 int security_task_setioprio(struct task_struct *p, int ioprio);
 int security_task_getioprio(struct task_struct *p);
@@ -1184,9 +1184,10 @@ static inline int security_task_getsid(struct 
task_struct *p)
return 0;
 }
 
-static inline void security_task_getsecid(struct task_struct *p, u32 *secid)
+static inline void security_task_getsecid(struct task_struct *p,
+ struct lsmblob *blob)
 {
-   *secid = 0;
+   lsmblob_init(blob, 0);
 }
 
 static inline int security_task_setnice(struct task_struct *p, int nice)
diff --git a/kernel/audit.c b/kernel/audit.c
index fcbdce83a9d8..70df7ac1b357 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -2139,19 +2139,12 @@ int audit_log_task_context(struct audit_buffer *ab)
char *ctx = NULL;
unsigned len;
int error;
-   u32 sid;
struct lsmblob blob;
 
-   security_task_getsecid(current, &sid);
-   if (!sid)
+   security_task_getsecid(current, &blob);
+   if (!lsmblob_is_set(&blob))
return 0;
 
-   /*
-* lsmblob_init sets all values in the lsmblob to sid.
-* This is temporary until security_task_getsecid is converted
-* to use a lsmblob, which happens later in this patch set.
-*/
-   lsmblob_init(&blob, sid);
error = security_secid_to_secctx(&blob, &ctx, &len);
if (error) {
if (error != -EINVAL)
@@ -2359,6 +2352,7 @@ int audit_set_loginuid(kuid_t loginuid)
 int audit_signal_info(int sig, struct task_struct *t)
 {
kuid_t uid = current_uid(), auid;
+   struct lsmblob blob;
 
if (auditd_test_task(t) &&
(sig == SIGTERM || sig == SIGHUP ||
@@ -2369,7 +2363,9 @@ int audit_signal_info(int sig, struct task_struct *t)
audit_sig_uid = auid;
else
audit_sig_uid = uid;
-   security_task_getsecid(current, &audit_sig_sid);
+   security_task_getsecid(current, &blob);
+   /* scaf

[PATCH v25 15/25] LSM: Ensure the correct LSM context releaser

2021-03-09 Thread Casey Schaufler
Add a new lsmcontext data structure to hold all the information
about a "security context", including the string, its size and
which LSM allocated the string. The allocation information is
necessary because LSMs have different policies regarding the
lifecycle of these strings. SELinux allocates and destroys
them on each use, whereas Smack provides a pointer to an entry
in a list that never goes away.

Reviewed-by: Kees Cook 
Reviewed-by: John Johansen 
Acked-by: Stephen Smalley 
Signed-off-by: Casey Schaufler 
Cc: linux-integr...@vger.kernel.org
Cc: netdev@vger.kernel.org
Cc: linux-au...@redhat.com
Cc: netfilter-de...@vger.kernel.org
To: Pablo Neira Ayuso 
Cc: linux-...@vger.kernel.org
---
 drivers/android/binder.c| 10 ---
 fs/ceph/xattr.c |  6 -
 fs/nfs/nfs4proc.c   |  8 --
 fs/nfsd/nfs4xdr.c   |  7 +++--
 include/linux/security.h| 35 +++--
 include/net/scm.h   |  5 +++-
 kernel/audit.c  | 14 +++---
 kernel/auditsc.c| 12 ++---
 net/ipv4/ip_sockglue.c  |  4 ++-
 net/netfilter/nf_conntrack_netlink.c|  4 ++-
 net/netfilter/nf_conntrack_standalone.c |  4 ++-
 net/netfilter/nfnetlink_queue.c | 13 ++---
 net/netlabel/netlabel_unlabeled.c   | 19 +++---
 net/netlabel/netlabel_user.c|  4 ++-
 security/security.c | 11 
 15 files changed, 121 insertions(+), 35 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 1a15e9e19e22..f74a72867ec9 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2448,6 +2448,7 @@ static void binder_transaction(struct binder_proc *proc,
int t_debug_id = atomic_inc_return(&binder_last_id);
char *secctx = NULL;
u32 secctx_sz = 0;
+   struct lsmcontext scaff; /* scaffolding */
 
e = binder_transaction_log_add(&binder_transaction_log);
e->debug_id = t_debug_id;
@@ -2750,7 +2751,8 @@ static void binder_transaction(struct binder_proc *proc,
t->security_ctx = 0;
WARN_ON(1);
}
-   security_release_secctx(secctx, secctx_sz);
+   lsmcontext_init(&scaff, secctx, secctx_sz, 0);
+   security_release_secctx(&scaff);
secctx = NULL;
}
t->buffer->debug_id = t->debug_id;
@@ -3084,8 +3086,10 @@ static void binder_transaction(struct binder_proc *proc,
binder_alloc_free_buf(&target_proc->alloc, t->buffer);
 err_binder_alloc_buf_failed:
 err_bad_extra_size:
-   if (secctx)
-   security_release_secctx(secctx, secctx_sz);
+   if (secctx) {
+   lsmcontext_init(&scaff, secctx, secctx_sz, 0);
+   security_release_secctx(&scaff);
+   }
 err_get_secctx_failed:
kfree(tcomplete);
binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c
index 02f59bcb4f27..27b1bbe5ab08 100644
--- a/fs/ceph/xattr.c
+++ b/fs/ceph/xattr.c
@@ -1349,12 +1349,16 @@ int ceph_security_init_secctx(struct dentry *dentry, 
umode_t mode,
 
 void ceph_release_acl_sec_ctx(struct ceph_acl_sec_ctx *as_ctx)
 {
+#ifdef CONFIG_CEPH_FS_SECURITY_LABEL
+   struct lsmcontext scaff; /* scaffolding */
+#endif
 #ifdef CONFIG_CEPH_FS_POSIX_ACL
posix_acl_release(as_ctx->acl);
posix_acl_release(as_ctx->default_acl);
 #endif
 #ifdef CONFIG_CEPH_FS_SECURITY_LABEL
-   security_release_secctx(as_ctx->sec_ctx, as_ctx->sec_ctxlen);
+   lsmcontext_init(&scaff, as_ctx->sec_ctx, as_ctx->sec_ctxlen, 0);
+   security_release_secctx(&scaff);
 #endif
if (as_ctx->pagelist)
ceph_pagelist_release(as_ctx->pagelist);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 74bc5120013d..503ee773f571 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -135,8 +135,12 @@ nfs4_label_init_security(struct inode *dir, struct dentry 
*dentry,
 static inline void
 nfs4_label_release_security(struct nfs4_label *label)
 {
-   if (label)
-   security_release_secctx(label->label, label->len);
+   struct lsmcontext scaff; /* scaffolding */
+
+   if (label) {
+   lsmcontext_init(&scaff, label->label, label->len, 0);
+   security_release_secctx(&scaff);
+   }
 }
 static inline u32 *nfs4_bitmask(struct nfs_server *server, struct nfs4_label 
*label)
 {
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index eaaa1605b5b5..afccc4f257d0 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2844,6 +2844,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh 
*fhp,
int err;
struct nfs4_acl *acl = NULL;
 #ifdef CONFIG_NFSD_V4_SECURIT

[PATCH v25 16/25] LSM: Use lsmcontext in security_secid_to_secctx

2021-03-09 Thread Casey Schaufler
Replace the (secctx,seclen) pointer pair with a single
lsmcontext pointer to allow return of the LSM identifier
along with the context and context length. This allows
security_release_secctx() to know how to release the
context. Callers have been modified to use or save the
returned data from the new structure.

Reviewed-by: Kees Cook 
Acked-by: Stephen Smalley 
Acked-by: Paul Moore 
Signed-off-by: Casey Schaufler 
Cc: netdev@vger.kernel.org
Cc: linux-au...@redhat.com
Cc: netfilter-de...@vger.kernel.org
---
 drivers/android/binder.c| 26 +++-
 include/linux/security.h|  4 +--
 include/net/scm.h   |  9 ++
 kernel/audit.c  | 39 +++-
 kernel/auditsc.c| 31 +++
 net/ipv4/ip_sockglue.c  |  8 ++---
 net/netfilter/nf_conntrack_netlink.c| 18 +--
 net/netfilter/nf_conntrack_standalone.c |  7 ++---
 net/netfilter/nfnetlink_queue.c |  5 +++-
 net/netlabel/netlabel_unlabeled.c   | 40 -
 net/netlabel/netlabel_user.c|  7 ++---
 security/security.c | 10 +--
 12 files changed, 81 insertions(+), 123 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index f74a72867ec9..4c810ea52ab7 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2446,9 +2446,7 @@ static void binder_transaction(struct binder_proc *proc,
binder_size_t last_fixup_min_off = 0;
struct binder_context *context = proc->context;
int t_debug_id = atomic_inc_return(&binder_last_id);
-   char *secctx = NULL;
-   u32 secctx_sz = 0;
-   struct lsmcontext scaff; /* scaffolding */
+   struct lsmcontext lsmctx = { };
 
e = binder_transaction_log_add(&binder_transaction_log);
e->debug_id = t_debug_id;
@@ -2702,14 +2700,14 @@ static void binder_transaction(struct binder_proc *proc,
size_t added_size;
 
security_task_getsecid(proc->tsk, &blob);
-   ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz);
+   ret = security_secid_to_secctx(&blob, &lsmctx);
if (ret) {
return_error = BR_FAILED_REPLY;
return_error_param = ret;
return_error_line = __LINE__;
goto err_get_secctx_failed;
}
-   added_size = ALIGN(secctx_sz, sizeof(u64));
+   added_size = ALIGN(lsmctx.len, sizeof(u64));
extra_buffers_size += added_size;
if (extra_buffers_size < added_size) {
/* integer overflow of extra_buffers_size */
@@ -2736,24 +2734,22 @@ static void binder_transaction(struct binder_proc *proc,
t->buffer = NULL;
goto err_binder_alloc_buf_failed;
}
-   if (secctx) {
+   if (lsmctx.context) {
int err;
size_t buf_offset = ALIGN(tr->data_size, sizeof(void *)) +
ALIGN(tr->offsets_size, sizeof(void *)) +
ALIGN(extra_buffers_size, sizeof(void *)) -
-   ALIGN(secctx_sz, sizeof(u64));
+   ALIGN(lsmctx.len, sizeof(u64));
 
t->security_ctx = (uintptr_t)t->buffer->user_data + buf_offset;
err = binder_alloc_copy_to_buffer(&target_proc->alloc,
  t->buffer, buf_offset,
- secctx, secctx_sz);
+ lsmctx.context, lsmctx.len);
if (err) {
t->security_ctx = 0;
WARN_ON(1);
}
-   lsmcontext_init(&scaff, secctx, secctx_sz, 0);
-   security_release_secctx(&scaff);
-   secctx = NULL;
+   security_release_secctx(&lsmctx);
}
t->buffer->debug_id = t->debug_id;
t->buffer->transaction = t;
@@ -2810,7 +2806,7 @@ static void binder_transaction(struct binder_proc *proc,
off_end_offset = off_start_offset + tr->offsets_size;
sg_buf_offset = ALIGN(off_end_offset, sizeof(void *));
sg_buf_end_offset = sg_buf_offset + extra_buffers_size -
-   ALIGN(secctx_sz, sizeof(u64));
+   ALIGN(lsmctx.len, sizeof(u64));
off_min = 0;
for (buffer_offset = off_start_offset; buffer_offset < off_end_offset;
 buffer_offset += sizeof(binder_size_t)) {
@@ -3086,10 +3082,8 @@ static void binder_transaction(struct binder_proc *proc,
binder_alloc_free_buf(&target_proc->alloc, t->buffer);
 err_binder_all

[PATCH v25 18/25] LSM: security_secid_to_secctx in netlink netfilter

2021-03-09 Thread Casey Schaufler
Change netlink netfilter interfaces to use lsmcontext
pointers, and remove scaffolding.

Reviewed-by: Kees Cook 
Reviewed-by: John Johansen 
Acked-by: Stephen Smalley 
Acked-by: Pablo Neira Ayuso 
Signed-off-by: Casey Schaufler 
Cc: netdev@vger.kernel.org
Cc: netfilter-de...@vger.kernel.org
---
 net/netfilter/nfnetlink_queue.c | 37 +
 1 file changed, 14 insertions(+), 23 deletions(-)

diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 449c2c7c7b27..56784592c820 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -301,15 +301,13 @@ static int nfqnl_put_sk_uidgid(struct sk_buff *skb, 
struct sock *sk)
return -1;
 }
 
-static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata)
+static void nfqnl_get_sk_secctx(struct sk_buff *skb, struct lsmcontext 
*context)
 {
-   u32 seclen = 0;
 #if IS_ENABLED(CONFIG_NETWORK_SECMARK)
struct lsmblob blob;
-   struct lsmcontext context = { };
 
if (!skb || !sk_fullsock(skb->sk))
-   return 0;
+   return;
 
read_lock_bh(&skb->sk->sk_callback_lock);
 
@@ -318,14 +316,12 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char 
**secdata)
 * blob. security_secid_to_secctx() will know which security
 * module to use to create the secctx.  */
lsmblob_init(&blob, skb->secmark);
-   security_secid_to_secctx(&blob, &context);
-   *secdata = context.context;
+   security_secid_to_secctx(&blob, context);
}
 
read_unlock_bh(&skb->sk->sk_callback_lock);
-   seclen = context.len;
 #endif
-   return seclen;
+   return;
 }
 
 static u32 nfqnl_get_bridge_size(struct nf_queue_entry *entry)
@@ -398,12 +394,10 @@ nfqnl_build_packet_message(struct net *net, struct 
nfqnl_instance *queue,
struct net_device *indev;
struct net_device *outdev;
struct nf_conn *ct = NULL;
+   struct lsmcontext context = { };
enum ip_conntrack_info ctinfo;
struct nfnl_ct_hook *nfnl_ct;
bool csum_verify;
-   struct lsmcontext scaff; /* scaffolding */
-   char *secdata = NULL;
-   u32 seclen = 0;
 
size = nlmsg_total_size(sizeof(struct nfgenmsg))
+ nla_total_size(sizeof(struct nfqnl_msg_packet_hdr))
@@ -471,9 +465,9 @@ nfqnl_build_packet_message(struct net *net, struct 
nfqnl_instance *queue,
}
 
if ((queue->flags & NFQA_CFG_F_SECCTX) && entskb->sk) {
-   seclen = nfqnl_get_sk_secctx(entskb, &secdata);
-   if (seclen)
-   size += nla_total_size(seclen);
+   nfqnl_get_sk_secctx(entskb, &context);
+   if (context.len)
+   size += nla_total_size(context.len);
}
 
skb = alloc_skb(size, GFP_ATOMIC);
@@ -606,7 +600,8 @@ nfqnl_build_packet_message(struct net *net, struct 
nfqnl_instance *queue,
nfqnl_put_sk_uidgid(skb, entskb->sk) < 0)
goto nla_put_failure;
 
-   if (seclen && nla_put(skb, NFQA_SECCTX, seclen, secdata))
+   if (context.len &&
+   nla_put(skb, NFQA_SECCTX, context.len, context.context))
goto nla_put_failure;
 
if (ct && nfnl_ct->build(skb, ct, ctinfo, NFQA_CT, NFQA_CT_INFO) < 0)
@@ -634,10 +629,8 @@ nfqnl_build_packet_message(struct net *net, struct 
nfqnl_instance *queue,
}
 
nlh->nlmsg_len = skb->len;
-   if (seclen) {
-   lsmcontext_init(&scaff, secdata, seclen, 0);
-   security_release_secctx(&scaff);
-   }
+   if (context.len)
+   security_release_secctx(&context);
return skb;
 
 nla_put_failure:
@@ -645,10 +638,8 @@ nfqnl_build_packet_message(struct net *net, struct 
nfqnl_instance *queue,
kfree_skb(skb);
net_err_ratelimited("nf_queue: error creating packet message\n");
 nlmsg_failure:
-   if (seclen) {
-   lsmcontext_init(&scaff, secdata, seclen, 0);
-   security_release_secctx(&scaff);
-   }
+   if (context.len)
+   security_release_secctx(&context);
return NULL;
 }
 
-- 
2.29.2



[PATCH v25 19/25] NET: Store LSM netlabel data in a lsmblob

2021-03-09 Thread Casey Schaufler
Netlabel uses LSM interfaces requiring an lsmblob and
the internal storage is used to pass information between
these interfaces, so change the internal data from a secid
to a lsmblob. Update the netlabel interfaces and their
callers to accommodate the change. This requires that the
modules using netlabel use the lsm_id.slot to access the
correct secid when using netlabel.

Reviewed-by: Kees Cook 
Reviewed-by: John Johansen 
Acked-by: Stephen Smalley 
Acked-by: Paul Moore 
Signed-off-by: Casey Schaufler 
Cc: netdev@vger.kernel.org
---
 include/net/netlabel.h  |  8 +--
 net/ipv4/cipso_ipv4.c   | 26 ++
 net/netlabel/netlabel_kapi.c|  6 +--
 net/netlabel/netlabel_unlabeled.c   | 79 +
 net/netlabel/netlabel_unlabeled.h   |  2 +-
 security/selinux/hooks.c|  2 +-
 security/selinux/include/security.h |  1 +
 security/selinux/netlabel.c |  2 +-
 security/selinux/ss/services.c  |  4 +-
 security/smack/smack.h  |  1 +
 security/smack/smack_access.c   |  2 +-
 security/smack/smack_lsm.c  | 11 ++--
 security/smack/smackfs.c| 10 ++--
 13 files changed, 68 insertions(+), 86 deletions(-)

diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index 43ae50337685..73fc25b4042b 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -166,7 +166,7 @@ struct netlbl_lsm_catmap {
  * @attr.mls: MLS sensitivity label
  * @attr.mls.cat: MLS category bitmap
  * @attr.mls.lvl: MLS sensitivity level
- * @attr.secid: LSM specific secid token
+ * @attr.lsmblob: LSM specific data
  *
  * Description:
  * This structure is used to pass security attributes between NetLabel and the
@@ -201,7 +201,7 @@ struct netlbl_lsm_secattr {
struct netlbl_lsm_catmap *cat;
u32 lvl;
} mls;
-   u32 secid;
+   struct lsmblob lsmblob;
} attr;
 };
 
@@ -415,7 +415,7 @@ int netlbl_cfg_unlbl_static_add(struct net *net,
const void *addr,
const void *mask,
u16 family,
-   u32 secid,
+   struct lsmblob *lsmblob,
struct netlbl_audit *audit_info);
 int netlbl_cfg_unlbl_static_del(struct net *net,
const char *dev_name,
@@ -523,7 +523,7 @@ static inline int netlbl_cfg_unlbl_static_add(struct net 
*net,
  const void *addr,
  const void *mask,
  u16 family,
- u32 secid,
+ struct lsmblob *lsmblob,
  struct netlbl_audit *audit_info)
 {
return -ENOSYS;
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index 471d33a0d095..1ac343d02b58 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -106,15 +106,17 @@ int cipso_v4_rbm_strictvalid = 1;
 /* Base length of the local tag (non-standard tag).
  *  Tag definition (may change between kernel versions)
  *
- * 0  8  16 24 32
- * +--+--+--+--+
- * | 1000 | 0110 | 32-bit secid value  |
- * +--+--+--+--+
- * | in (host byte order)|
- * +--+--+
- *
+ * 0  8  1616 + sizeof(struct lsmblob)
+ * +--+--+-+
+ * | 1000 | 0110 | LSM blob data   |
+ * +--+--+-+
+ *
+ * All secid and flag fields are in host byte order.
+ * The lsmblob structure size varies depending on which
+ * Linux security modules are built in the kernel.
+ * The data is opaque.
  */
-#define CIPSO_V4_TAG_LOC_BLEN 6
+#define CIPSO_V4_TAG_LOC_BLEN (2 + sizeof(struct lsmblob))
 
 /*
  * Helper Functions
@@ -1469,7 +1471,11 @@ static int cipso_v4_gentag_loc(const struct cipso_v4_doi 
*doi_def,
 
buffer[0] = CIPSO_V4_TAG_LOCAL;
buffer[1] = CIPSO_V4_TAG_LOC_BLEN;
-   *(u32 *)&buffer[2] = secattr->attr.secid;
+   /* Ensure that there is sufficient space in the CIPSO header
+* for the LSM data. */
+   BUILD_BUG_ON(CIPSO_V4_TAG_LOC_BLEN > CIPSO_V4_OPT_LEN_MAX);
+   memcpy(&buffer[2], &secattr->attr.lsmblob,
+  sizeof(secattr->attr.lsmblob));
 
return CIPSO_V4_TAG_LOC_BLEN;
 }
@@ -1489,7 +1495,7 @@ static int cipso_v4_parsetag_loc(const struct 
cipso_v4_doi *doi_def,
 const unsigned char *tag,
 struct netlbl_lsm_secattr *secattr)
 {
-   secattr->attr.secid = *(u32 *)&tag[2];
+   memcpy(&secattr->attr.lsmblob,

[PATCH v25 22/25] Audit: Add new record for multiple process LSM attributes

2021-03-09 Thread Casey Schaufler
Create a new audit record type to contain the subject information
when there are multiple security modules that require such data.
This record is linked with the same timestamp and serial number
using the audit_alloc_local() mechanism.
The record is produced only in cases where there is more than one
security module with a process "context".
In cases where this record is produced the subj= fields of
other records in the audit event will be set to "subj=?".

An example of the MAC_TASK_CONTEXTS (1420) record is:

type=UNKNOWN[1420]
msg=audit(1600880931.832:113)
subj_apparmor==unconfined
subj_smack=_

There will be a subj_$LSM= entry for each security module
LSM that supports the secid_to_secctx and secctx_to_secid
hooks. The BPF security module implements secid/secctx
translation hooks, so it has to be considered to provide a
secctx even though it may not actually do so.

Signed-off-by: Casey Schaufler 
To: p...@paul-moore.com
To: linux-au...@redhat.com
To: r...@redhat.com
Cc: netdev@vger.kernel.org
---
 drivers/android/binder.c|  2 +-
 include/linux/audit.h   | 24 
 include/linux/security.h| 16 -
 include/net/netlabel.h  |  3 +-
 include/net/scm.h   |  2 +-
 include/net/xfrm.h  | 13 +++-
 include/uapi/linux/audit.h  |  1 +
 kernel/audit.c  | 80 ++---
 kernel/audit.h  |  3 +
 kernel/auditfilter.c|  6 +-
 kernel/auditsc.c| 75 ---
 net/ipv4/ip_sockglue.c  |  2 +-
 net/netfilter/nf_conntrack_netlink.c|  4 +-
 net/netfilter/nf_conntrack_standalone.c |  2 +-
 net/netfilter/nfnetlink_queue.c |  2 +-
 net/netlabel/netlabel_domainhash.c  |  4 +-
 net/netlabel/netlabel_unlabeled.c   | 24 
 net/netlabel/netlabel_user.c| 20 ---
 net/netlabel/netlabel_user.h|  6 +-
 net/xfrm/xfrm_policy.c  | 10 ++--
 net/xfrm/xfrm_state.c   | 20 ---
 security/integrity/ima/ima_api.c|  7 ++-
 security/integrity/integrity_audit.c|  6 +-
 security/security.c | 46 +-
 security/smack/smackfs.c|  3 +-
 25 files changed, 274 insertions(+), 107 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 4c810ea52ab7..28f573d46391 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2700,7 +2700,7 @@ static void binder_transaction(struct binder_proc *proc,
size_t added_size;
 
security_task_getsecid(proc->tsk, &blob);
-   ret = security_secid_to_secctx(&blob, &lsmctx);
+   ret = security_secid_to_secctx(&blob, &lsmctx, LSMBLOB_DISPLAY);
if (ret) {
return_error = BR_FAILED_REPLY;
return_error_param = ret;
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 97cd7471e572..229cd71fbf09 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -164,6 +164,8 @@ extern struct audit_buffer *audit_log_start(struct 
audit_context *ctx, gfp_t gfp
 extern __printf(2, 3)
 void audit_log_format(struct audit_buffer *ab, const char *fmt, ...);
 extern voidaudit_log_end(struct audit_buffer *ab);
+extern voidaudit_log_end_local(struct audit_buffer *ab,
+   struct audit_context *context);
 extern boolaudit_string_contains_control(const char *string,
  size_t len);
 extern voidaudit_log_n_hex(struct audit_buffer *ab,
@@ -188,6 +190,7 @@ extern void audit_log_lost(const char *message);
 
 extern int audit_log_task_context(struct audit_buffer *ab);
 extern void audit_log_task_info(struct audit_buffer *ab);
+extern void audit_log_lsm(struct audit_context *context);
 
 extern int audit_update_lsm_rules(void);
 
@@ -226,6 +229,9 @@ void audit_log_format(struct audit_buffer *ab, const char 
*fmt, ...)
 { }
 static inline void audit_log_end(struct audit_buffer *ab)
 { }
+static inline void audit_log_end_local(struct audit_buffer *ab,
+  struct audit_context *context)
+{ }
 static inline void audit_log_n_hex(struct audit_buffer *ab,
   const unsigned char *buf, size_t len)
 { }
@@ -252,6 +258,8 @@ static inline int audit_log_task_context(struct 
audit_buffer *ab)
 }
 static inline void audit_log_task_info(struct audit_buffer *ab)
 { }
+static void audit_log_lsm(struct audit_context *context)
+{ }
 
 static inline kuid_t audit_get_loginuid(struct task_struct *tsk)
 {
@@ -291,6 +299,7 @@ extern int  audit_alloc(struct task_struct *task);
 

[PATCH v22 05/23] LSM: Use lsmblob in security_secctx_to_secid

2020-11-04 Thread Casey Schaufler
Change the security_secctx_to_secid interface to use a lsmblob
structure in place of the single u32 secid in support of
module stacking. Change its callers to do the same.

The security module hook is unchanged, still passing back a secid.
The infrastructure passes the correct entry from the lsmblob.

Signed-off-by: Casey Schaufler 
Cc: netdev@vger.kernel.org
---
 include/linux/security.h  | 26 ++--
 kernel/cred.c |  4 +---
 net/netfilter/nft_meta.c  | 10 
 net/netfilter/xt_SECMARK.c|  7 +-
 net/netlabel/netlabel_unlabeled.c | 23 +++---
 security/security.c   | 40 ++-
 6 files changed, 85 insertions(+), 25 deletions(-)

diff --git a/include/linux/security.h b/include/linux/security.h
index 948d12a5eb25..0766725a6b21 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -191,6 +191,27 @@ static inline bool lsmblob_equal(struct lsmblob *bloba, 
struct lsmblob *blobb)
return !memcmp(bloba, blobb, sizeof(*bloba));
 }
 
+/**
+ * lsmblob_value - find the first non-zero value in an lsmblob structure.
+ * @blob: Pointer to the data
+ *
+ * This needs to be used with extreme caution, as the cases where
+ * it is appropriate are rare.
+ *
+ * Return the first secid value set in the lsmblob.
+ * There should only be one.
+ */
+static inline u32 lsmblob_value(const struct lsmblob *blob)
+{
+   int i;
+
+   for (i = 0; i < LSMBLOB_ENTRIES; i++)
+   if (blob->secid[i])
+   return blob->secid[i];
+
+   return 0;
+}
+
 /* These functions are in security/commoncap.c */
 extern int cap_capable(const struct cred *cred, struct user_namespace *ns,
   int cap, unsigned int opts);
@@ -508,7 +529,8 @@ int security_setprocattr(const char *lsm, const char *name, 
void *value,
 int security_netlink_send(struct sock *sk, struct sk_buff *skb);
 int security_ismaclabel(const char *name);
 int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
-int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
+int security_secctx_to_secid(const char *secdata, u32 seclen,
+struct lsmblob *blob);
 void security_release_secctx(char *secdata, u32 seclen);
 void security_inode_invalidate_secctx(struct inode *inode);
 int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
@@ -1335,7 +1357,7 @@ static inline int security_secid_to_secctx(u32 secid, 
char **secdata, u32 *secle
 
 static inline int security_secctx_to_secid(const char *secdata,
   u32 seclen,
-  u32 *secid)
+  struct lsmblob *blob)
 {
return -EOPNOTSUPP;
 }
diff --git a/kernel/cred.c b/kernel/cred.c
index 22e0e7cbefde..848306c7d823 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -757,14 +757,12 @@ EXPORT_SYMBOL(set_security_override);
 int set_security_override_from_ctx(struct cred *new, const char *secctx)
 {
struct lsmblob blob;
-   u32 secid;
int ret;
 
-   ret = security_secctx_to_secid(secctx, strlen(secctx), &secid);
+   ret = security_secctx_to_secid(secctx, strlen(secctx), &blob);
if (ret < 0)
return ret;
 
-   lsmblob_init(&blob, secid);
return set_security_override(new, &blob);
 }
 EXPORT_SYMBOL(set_security_override_from_ctx);
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index b37bd02448d8..f1b9b0021414 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -811,21 +811,21 @@ 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 lsmblob blob;
int err;
 
-   err = security_secctx_to_secid(priv->ctx, strlen(priv->ctx), 
&tmp_secid);
+   err = security_secctx_to_secid(priv->ctx, strlen(priv->ctx), &blob);
if (err)
return err;
 
-   if (!tmp_secid)
+   if (!lsmblob_is_set(&blob))
return -ENOENT;
 
-   err = security_secmark_relabel_packet(tmp_secid);
+   err = security_secmark_relabel_packet(lsmblob_value(&blob));
if (err)
return err;
 
-   priv->secid = tmp_secid;
+   priv->secid = lsmblob_value(&blob);
return 0;
 }
 
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c
index 75625d13e976..9845d98e6b77 100644
--- a/net/netfilter/xt_SECMARK.c
+++ b/net/netfilter/xt_SECMARK.c
@@ -43,13 +43,14 @@ secmark_tg(struct sk_buff *skb, const struct 
xt_action_param *par)
 
 static int checkentry_lsm(struct xt_secmark_target_info *info)
 {
+   struct lsmblob blob;
int err;
 
info->secctx[SECMARK_SECCTX_MAX - 1] = '\0';

[PATCH v22 06/23] LSM: Use lsmblob in security_secid_to_secctx

2020-11-04 Thread Casey Schaufler
Change security_secid_to_secctx() to take a lsmblob as input
instead of a u32 secid. It will then call the LSM hooks
using the lsmblob element allocated for that module. The
callers have been updated as well. This allows for the
possibility that more than one module may be called upon
to translate a secid to a string, as can occur in the
audit code.

Signed-off-by: Casey Schaufler 
Cc: netdev@vger.kernel.org
Cc: linux-au...@redhat.com
---
 drivers/android/binder.c| 12 +-
 include/linux/security.h|  5 +++--
 include/net/scm.h   |  7 +-
 kernel/audit.c  | 20 +++--
 kernel/auditsc.c| 28 +++
 net/ipv4/ip_sockglue.c  |  4 +++-
 net/netfilter/nf_conntrack_netlink.c| 14 ++--
 net/netfilter/nf_conntrack_standalone.c |  4 +++-
 net/netfilter/nfnetlink_queue.c | 11 +++--
 net/netlabel/netlabel_unlabeled.c   | 30 +
 net/netlabel/netlabel_user.c|  6 ++---
 security/security.c | 11 +
 12 files changed, 123 insertions(+), 29 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index b5117576792b..55f3fa073c7b 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -3088,10 +3088,20 @@ static void binder_transaction(struct binder_proc *proc,
 
if (target_node && target_node->txn_security_ctx) {
u32 secid;
+   struct lsmblob blob;
size_t added_size;
 
security_task_getsecid(proc->tsk, &secid);
-   ret = security_secid_to_secctx(secid, &secctx, &secctx_sz);
+   /*
+* Later in this patch set security_task_getsecid() will
+* provide a lsmblob instead of a secid. lsmblob_init
+* is used to ensure that all the secids in the lsmblob
+* get the value returned from security_task_getsecid(),
+* which means that the one expected by
+* security_secid_to_secctx() will be set.
+*/
+   lsmblob_init(&blob, secid);
+   ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz);
if (ret) {
return_error = BR_FAILED_REPLY;
return_error_param = ret;
diff --git a/include/linux/security.h b/include/linux/security.h
index 0766725a6b21..fad361bf320e 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -528,7 +528,7 @@ int security_setprocattr(const char *lsm, const char *name, 
void *value,
 size_t size);
 int security_netlink_send(struct sock *sk, struct sk_buff *skb);
 int security_ismaclabel(const char *name);
-int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
+int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 
*seclen);
 int security_secctx_to_secid(const char *secdata, u32 seclen,
 struct lsmblob *blob);
 void security_release_secctx(char *secdata, u32 seclen);
@@ -1350,7 +1350,8 @@ static inline int security_ismaclabel(const char *name)
return 0;
 }
 
-static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 
*seclen)
+static inline int security_secid_to_secctx(struct lsmblob *blob,
+  char **secdata, u32 *seclen)
 {
return -EOPNOTSUPP;
 }
diff --git a/include/net/scm.h b/include/net/scm.h
index 1ce365f4c256..23a35ff1b3f2 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -92,12 +92,17 @@ static __inline__ int scm_send(struct socket *sock, struct 
msghdr *msg,
 #ifdef CONFIG_SECURITY_NETWORK
 static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct 
scm_cookie *scm)
 {
+   struct lsmblob lb;
char *secdata;
u32 seclen;
int err;
 
if (test_bit(SOCK_PASSSEC, &sock->flags)) {
-   err = security_secid_to_secctx(scm->secid, &secdata, &seclen);
+   /* There can only be one security module using the secid,
+* and the infrastructure will know which it is.
+*/
+   lsmblob_init(&lb, scm->secid);
+   err = security_secid_to_secctx(&lb, &secdata, &seclen);
 
if (!err) {
put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, 
secdata);
diff --git a/kernel/audit.c b/kernel/audit.c
index 68cee3bc8cfe..4cd6339e513d 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1442,7 +1442,16 @@ static int audit_receive_msg(struct sk_buff *skb, struct 
nlmsghdr *nlh)
case AUDIT_SIGNAL_INFO:
len = 0;
if (audit_sig_sid) {
-   err = security_secid_to_

[PATCH v22 08/23] LSM: Use lsmblob in security_task_getsecid

2020-11-04 Thread Casey Schaufler
Change the security_task_getsecid() interface to fill in
a lsmblob structure instead of a u32 secid in support of
LSM stacking. Audit interfaces will need to collect all
possible secids for possible reporting.

Reviewed-by: Kees Cook 
Reviewed-by: John Johansen 
Acked-by: Stephen Smalley 
Acked-by: Paul Moore 
Signed-off-by: Casey Schaufler 
Cc: linux-integr...@vger.kernel.org
Cc: linux-au...@redhat.com
Cc: netdev@vger.kernel.org
---
 drivers/android/binder.c  | 12 +-
 include/linux/security.h  |  7 ++--
 kernel/audit.c| 16 +++-
 kernel/auditfilter.c  |  4 +-
 kernel/auditsc.c  | 25 ++--
 net/netlabel/netlabel_unlabeled.c |  5 ++-
 net/netlabel/netlabel_user.h  |  6 ++-
 security/integrity/ima/ima_appraise.c | 10 +++--
 security/integrity/ima/ima_main.c | 56 +++
 security/security.c   | 12 --
 10 files changed, 80 insertions(+), 73 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 55f3fa073c7b..08737a07f997 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -3087,20 +3087,10 @@ static void binder_transaction(struct binder_proc *proc,
t->priority = task_nice(current);
 
if (target_node && target_node->txn_security_ctx) {
-   u32 secid;
struct lsmblob blob;
size_t added_size;
 
-   security_task_getsecid(proc->tsk, &secid);
-   /*
-* Later in this patch set security_task_getsecid() will
-* provide a lsmblob instead of a secid. lsmblob_init
-* is used to ensure that all the secids in the lsmblob
-* get the value returned from security_task_getsecid(),
-* which means that the one expected by
-* security_secid_to_secctx() will be set.
-*/
-   lsmblob_init(&blob, secid);
+   security_task_getsecid(proc->tsk, &blob);
ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz);
if (ret) {
return_error = BR_FAILED_REPLY;
diff --git a/include/linux/security.h b/include/linux/security.h
index be8db737da74..6b9e3571960d 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -482,7 +482,7 @@ int security_task_fix_setgid(struct cred *new, const struct 
cred *old,
 int security_task_setpgid(struct task_struct *p, pid_t pgid);
 int security_task_getpgid(struct task_struct *p);
 int security_task_getsid(struct task_struct *p);
-void security_task_getsecid(struct task_struct *p, u32 *secid);
+void security_task_getsecid(struct task_struct *p, struct lsmblob *blob);
 int security_task_setnice(struct task_struct *p, int nice);
 int security_task_setioprio(struct task_struct *p, int ioprio);
 int security_task_getioprio(struct task_struct *p);
@@ -1155,9 +1155,10 @@ static inline int security_task_getsid(struct 
task_struct *p)
return 0;
 }
 
-static inline void security_task_getsecid(struct task_struct *p, u32 *secid)
+static inline void security_task_getsecid(struct task_struct *p,
+ struct lsmblob *blob)
 {
-   *secid = 0;
+   lsmblob_init(blob, 0);
 }
 
 static inline int security_task_setnice(struct task_struct *p, int nice)
diff --git a/kernel/audit.c b/kernel/audit.c
index 4cd6339e513d..9e3eec0a9c29 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -2136,19 +2136,12 @@ int audit_log_task_context(struct audit_buffer *ab)
char *ctx = NULL;
unsigned len;
int error;
-   u32 sid;
struct lsmblob blob;
 
-   security_task_getsecid(current, &sid);
-   if (!sid)
+   security_task_getsecid(current, &blob);
+   if (!lsmblob_is_set(&blob))
return 0;
 
-   /*
-* lsmblob_init sets all values in the lsmblob to sid.
-* This is temporary until security_task_getsecid is converted
-* to use a lsmblob, which happens later in this patch set.
-*/
-   lsmblob_init(&blob, sid);
error = security_secid_to_secctx(&blob, &ctx, &len);
if (error) {
if (error != -EINVAL)
@@ -2356,6 +2349,7 @@ int audit_set_loginuid(kuid_t loginuid)
 int audit_signal_info(int sig, struct task_struct *t)
 {
kuid_t uid = current_uid(), auid;
+   struct lsmblob blob;
 
if (auditd_test_task(t) &&
(sig == SIGTERM || sig == SIGHUP ||
@@ -2366,7 +2360,9 @@ int audit_signal_info(int sig, struct task_struct *t)
audit_sig_uid = auid;
else
audit_sig_uid = uid;
-   security_task_getsecid(current, &audit_sig_sid);
+   security_task_getsecid(current, &blob);
+   /* scaf

[PATCH v22 13/23] LSM: Ensure the correct LSM context releaser

2020-11-04 Thread Casey Schaufler
Add a new lsmcontext data structure to hold all the information
about a "security context", including the string, its size and
which LSM allocated the string. The allocation information is
necessary because LSMs have different policies regarding the
lifecycle of these strings. SELinux allocates and destroys
them on each use, whereas Smack provides a pointer to an entry
in a list that never goes away.

Reviewed-by: Kees Cook 
Reviewed-by: John Johansen 
Acked-by: Stephen Smalley 
Signed-off-by: Casey Schaufler 
Cc: linux-integr...@vger.kernel.org
Cc: netdev@vger.kernel.org
Cc: linux-au...@redhat.com
---
 drivers/android/binder.c| 10 ---
 fs/ceph/xattr.c |  6 -
 fs/nfs/nfs4proc.c   |  8 --
 fs/nfsd/nfs4xdr.c   |  7 +++--
 include/linux/security.h| 35 +++--
 include/net/scm.h   |  5 +++-
 kernel/audit.c  | 14 +++---
 kernel/auditsc.c| 12 ++---
 net/ipv4/ip_sockglue.c  |  4 ++-
 net/netfilter/nf_conntrack_netlink.c|  4 ++-
 net/netfilter/nf_conntrack_standalone.c |  4 ++-
 net/netfilter/nfnetlink_queue.c | 13 ++---
 net/netlabel/netlabel_unlabeled.c   | 19 +++---
 net/netlabel/netlabel_user.c|  4 ++-
 security/security.c | 11 
 15 files changed, 121 insertions(+), 35 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 08737a07f997..05266b064c38 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2838,6 +2838,7 @@ static void binder_transaction(struct binder_proc *proc,
int t_debug_id = atomic_inc_return(&binder_last_id);
char *secctx = NULL;
u32 secctx_sz = 0;
+   struct lsmcontext scaff; /* scaffolding */
 
e = binder_transaction_log_add(&binder_transaction_log);
e->debug_id = t_debug_id;
@@ -3140,7 +3141,8 @@ static void binder_transaction(struct binder_proc *proc,
t->security_ctx = 0;
WARN_ON(1);
}
-   security_release_secctx(secctx, secctx_sz);
+   lsmcontext_init(&scaff, secctx, secctx_sz, 0);
+   security_release_secctx(&scaff);
secctx = NULL;
}
t->buffer->debug_id = t->debug_id;
@@ -3473,8 +3475,10 @@ static void binder_transaction(struct binder_proc *proc,
binder_alloc_free_buf(&target_proc->alloc, t->buffer);
 err_binder_alloc_buf_failed:
 err_bad_extra_size:
-   if (secctx)
-   security_release_secctx(secctx, secctx_sz);
+   if (secctx) {
+   lsmcontext_init(&scaff, secctx, secctx_sz, 0);
+   security_release_secctx(&scaff);
+   }
 err_get_secctx_failed:
kfree(tcomplete);
binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c
index 197cb1234341..5dfd08357dc3 100644
--- a/fs/ceph/xattr.c
+++ b/fs/ceph/xattr.c
@@ -1273,12 +1273,16 @@ int ceph_security_init_secctx(struct dentry *dentry, 
umode_t mode,
 
 void ceph_release_acl_sec_ctx(struct ceph_acl_sec_ctx *as_ctx)
 {
+#ifdef CONFIG_CEPH_FS_SECURITY_LABEL
+   struct lsmcontext scaff; /* scaffolding */
+#endif
 #ifdef CONFIG_CEPH_FS_POSIX_ACL
posix_acl_release(as_ctx->acl);
posix_acl_release(as_ctx->default_acl);
 #endif
 #ifdef CONFIG_CEPH_FS_SECURITY_LABEL
-   security_release_secctx(as_ctx->sec_ctx, as_ctx->sec_ctxlen);
+   lsmcontext_init(&scaff, as_ctx->sec_ctx, as_ctx->sec_ctxlen, 0);
+   security_release_secctx(&scaff);
 #endif
if (as_ctx->pagelist)
ceph_pagelist_release(as_ctx->pagelist);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 9e0ca9b2b210..4b03a3e596e9 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -139,8 +139,12 @@ nfs4_label_init_security(struct inode *dir, struct dentry 
*dentry,
 static inline void
 nfs4_label_release_security(struct nfs4_label *label)
 {
-   if (label)
-   security_release_secctx(label->label, label->len);
+   struct lsmcontext scaff; /* scaffolding */
+
+   if (label) {
+   lsmcontext_init(&scaff, label->label, label->len, 0);
+   security_release_secctx(&scaff);
+   }
 }
 static inline u32 *nfs4_bitmask(struct nfs_server *server, struct nfs4_label 
*label)
 {
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 833a2c64dfe8..4ae7e156ea87 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2717,6 +2717,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh 
*fhp,
int err;
struct nfs4_acl *acl = NULL;
 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
+   struct lsmcontext scaff; /* scaffolding */
void *context = NULL;

[PATCH v22 14/23] LSM: Use lsmcontext in security_secid_to_secctx

2020-11-04 Thread Casey Schaufler
Replace the (secctx,seclen) pointer pair with a single
lsmcontext pointer to allow return of the LSM identifier
along with the context and context length. This allows
security_release_secctx() to know how to release the
context. Callers have been modified to use or save the
returned data from the new structure.

Reviewed-by: Kees Cook 
Acked-by: Stephen Smalley 
Acked-by: Paul Moore 
Signed-off-by: Casey Schaufler 
Cc: netdev@vger.kernel.org
Cc: linux-au...@redhat.com
---
 drivers/android/binder.c| 26 +++-
 include/linux/security.h|  4 +--
 include/net/scm.h   |  9 ++
 kernel/audit.c  | 39 +++-
 kernel/auditsc.c| 31 +++
 net/ipv4/ip_sockglue.c  |  8 ++---
 net/netfilter/nf_conntrack_netlink.c| 18 +--
 net/netfilter/nf_conntrack_standalone.c |  7 ++---
 net/netfilter/nfnetlink_queue.c |  5 +++-
 net/netlabel/netlabel_unlabeled.c   | 40 -
 net/netlabel/netlabel_user.c|  7 ++---
 security/security.c | 10 +--
 12 files changed, 81 insertions(+), 123 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 05266b064c38..a75ffcd0270a 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2836,9 +2836,7 @@ static void binder_transaction(struct binder_proc *proc,
binder_size_t last_fixup_min_off = 0;
struct binder_context *context = proc->context;
int t_debug_id = atomic_inc_return(&binder_last_id);
-   char *secctx = NULL;
-   u32 secctx_sz = 0;
-   struct lsmcontext scaff; /* scaffolding */
+   struct lsmcontext lsmctx = { };
 
e = binder_transaction_log_add(&binder_transaction_log);
e->debug_id = t_debug_id;
@@ -3092,14 +3090,14 @@ static void binder_transaction(struct binder_proc *proc,
size_t added_size;
 
security_task_getsecid(proc->tsk, &blob);
-   ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz);
+   ret = security_secid_to_secctx(&blob, &lsmctx);
if (ret) {
return_error = BR_FAILED_REPLY;
return_error_param = ret;
return_error_line = __LINE__;
goto err_get_secctx_failed;
}
-   added_size = ALIGN(secctx_sz, sizeof(u64));
+   added_size = ALIGN(lsmctx.len, sizeof(u64));
extra_buffers_size += added_size;
if (extra_buffers_size < added_size) {
/* integer overflow of extra_buffers_size */
@@ -3126,24 +3124,22 @@ static void binder_transaction(struct binder_proc *proc,
t->buffer = NULL;
goto err_binder_alloc_buf_failed;
}
-   if (secctx) {
+   if (lsmctx.context) {
int err;
size_t buf_offset = ALIGN(tr->data_size, sizeof(void *)) +
ALIGN(tr->offsets_size, sizeof(void *)) +
ALIGN(extra_buffers_size, sizeof(void *)) -
-   ALIGN(secctx_sz, sizeof(u64));
+   ALIGN(lsmctx.len, sizeof(u64));
 
t->security_ctx = (uintptr_t)t->buffer->user_data + buf_offset;
err = binder_alloc_copy_to_buffer(&target_proc->alloc,
  t->buffer, buf_offset,
- secctx, secctx_sz);
+ lsmctx.context, lsmctx.len);
if (err) {
t->security_ctx = 0;
WARN_ON(1);
}
-   lsmcontext_init(&scaff, secctx, secctx_sz, 0);
-   security_release_secctx(&scaff);
-   secctx = NULL;
+   security_release_secctx(&lsmctx);
}
t->buffer->debug_id = t->debug_id;
t->buffer->transaction = t;
@@ -3199,7 +3195,7 @@ static void binder_transaction(struct binder_proc *proc,
off_end_offset = off_start_offset + tr->offsets_size;
sg_buf_offset = ALIGN(off_end_offset, sizeof(void *));
sg_buf_end_offset = sg_buf_offset + extra_buffers_size -
-   ALIGN(secctx_sz, sizeof(u64));
+   ALIGN(lsmctx.len, sizeof(u64));
off_min = 0;
for (buffer_offset = off_start_offset; buffer_offset < off_end_offset;
 buffer_offset += sizeof(binder_size_t)) {
@@ -3475,10 +3471,8 @@ static void binder_transaction(struct binder_proc *proc,
binder_alloc_free_buf(&target_proc->alloc, t->buffer);
 err_binder_alloc_buf_failed:
 err_bad_extra_size:
-   if (s

[PATCH v22 05/23] LSM: Use lsmblob in security_secctx_to_secid

2020-11-04 Thread Casey Schaufler
Change the security_secctx_to_secid interface to use a lsmblob
structure in place of the single u32 secid in support of
module stacking. Change its callers to do the same.

The security module hook is unchanged, still passing back a secid.
The infrastructure passes the correct entry from the lsmblob.

Signed-off-by: Casey Schaufler 
Cc: netdev@vger.kernel.org
---
 include/linux/security.h  | 26 ++--
 kernel/cred.c |  4 +---
 net/netfilter/nft_meta.c  | 10 
 net/netfilter/xt_SECMARK.c|  7 +-
 net/netlabel/netlabel_unlabeled.c | 23 +++---
 security/security.c   | 40 ++-
 6 files changed, 85 insertions(+), 25 deletions(-)

diff --git a/include/linux/security.h b/include/linux/security.h
index 948d12a5eb25..0766725a6b21 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -191,6 +191,27 @@ static inline bool lsmblob_equal(struct lsmblob *bloba, 
struct lsmblob *blobb)
return !memcmp(bloba, blobb, sizeof(*bloba));
 }
 
+/**
+ * lsmblob_value - find the first non-zero value in an lsmblob structure.
+ * @blob: Pointer to the data
+ *
+ * This needs to be used with extreme caution, as the cases where
+ * it is appropriate are rare.
+ *
+ * Return the first secid value set in the lsmblob.
+ * There should only be one.
+ */
+static inline u32 lsmblob_value(const struct lsmblob *blob)
+{
+   int i;
+
+   for (i = 0; i < LSMBLOB_ENTRIES; i++)
+   if (blob->secid[i])
+   return blob->secid[i];
+
+   return 0;
+}
+
 /* These functions are in security/commoncap.c */
 extern int cap_capable(const struct cred *cred, struct user_namespace *ns,
   int cap, unsigned int opts);
@@ -508,7 +529,8 @@ int security_setprocattr(const char *lsm, const char *name, 
void *value,
 int security_netlink_send(struct sock *sk, struct sk_buff *skb);
 int security_ismaclabel(const char *name);
 int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
-int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
+int security_secctx_to_secid(const char *secdata, u32 seclen,
+struct lsmblob *blob);
 void security_release_secctx(char *secdata, u32 seclen);
 void security_inode_invalidate_secctx(struct inode *inode);
 int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
@@ -1335,7 +1357,7 @@ static inline int security_secid_to_secctx(u32 secid, 
char **secdata, u32 *secle
 
 static inline int security_secctx_to_secid(const char *secdata,
   u32 seclen,
-  u32 *secid)
+  struct lsmblob *blob)
 {
return -EOPNOTSUPP;
 }
diff --git a/kernel/cred.c b/kernel/cred.c
index 22e0e7cbefde..848306c7d823 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -757,14 +757,12 @@ EXPORT_SYMBOL(set_security_override);
 int set_security_override_from_ctx(struct cred *new, const char *secctx)
 {
struct lsmblob blob;
-   u32 secid;
int ret;
 
-   ret = security_secctx_to_secid(secctx, strlen(secctx), &secid);
+   ret = security_secctx_to_secid(secctx, strlen(secctx), &blob);
if (ret < 0)
return ret;
 
-   lsmblob_init(&blob, secid);
return set_security_override(new, &blob);
 }
 EXPORT_SYMBOL(set_security_override_from_ctx);
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index b37bd02448d8..f1b9b0021414 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -811,21 +811,21 @@ 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 lsmblob blob;
int err;
 
-   err = security_secctx_to_secid(priv->ctx, strlen(priv->ctx), 
&tmp_secid);
+   err = security_secctx_to_secid(priv->ctx, strlen(priv->ctx), &blob);
if (err)
return err;
 
-   if (!tmp_secid)
+   if (!lsmblob_is_set(&blob))
return -ENOENT;
 
-   err = security_secmark_relabel_packet(tmp_secid);
+   err = security_secmark_relabel_packet(lsmblob_value(&blob));
if (err)
return err;
 
-   priv->secid = tmp_secid;
+   priv->secid = lsmblob_value(&blob);
return 0;
 }
 
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c
index 75625d13e976..9845d98e6b77 100644
--- a/net/netfilter/xt_SECMARK.c
+++ b/net/netfilter/xt_SECMARK.c
@@ -43,13 +43,14 @@ secmark_tg(struct sk_buff *skb, const struct 
xt_action_param *par)
 
 static int checkentry_lsm(struct xt_secmark_target_info *info)
 {
+   struct lsmblob blob;
int err;
 
info->secctx[SECMARK_SECCTX_MAX - 1] = '\0';

  1   2   >