Re: [RFC PATCH v8 18/18] SELinux: Add network ingress and egress control permission checks

2007-12-18 Thread Paul Moore
On Monday 17 December 2007 3:05:37 pm Stephen Smalley wrote:
 On Sun, 2007-12-16 at 11:47 -0500, Paul Moore wrote:
  We should probably have different permissions for the interface and node
  cases.  Take the example of an admin who is only interested in enforcing
  interface controls and not node controls.  They would most likely write
  the following policy rule to nullify the node check ...
 
   allow unlabeled_t peer_t:peer egress;
 
  ... which would end up applying to both the interface and node checks
  because they use the same permission.  I'm thinking we should split the
  permissions like this:
 
   allow netif_t peer_t:peer if_egress;
   allow netnode_t peer_t: peer node_egress;
 
  ... and do something similar for the ingress side.  Thoughts?

 That starts to sound a lot like using netif and node classes instead of
 the peer class.
   allow peer_t netif_t:netif egress;
   allow peer_t netnode_t:node egress;

Thinking about this some more ... egress/ingress make sense from an interface 
point of view but they sound out of place from a node point of view.  After 
all, you are not egressing to a node, to are sending to a node.  The same 
thing applies in the opposite direction, you don't ingress from a node, 
you receive from a node.  With that in mind I'm thinking of going with the 
following:

 allow netif_t peer_t:peer { ingress egress };
 allow netnode_t peer_t:peer { recv_from send_to };

Thoughts?  Should I just forget all this and use the peer label as a subject 
label?

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line unsubscribe 
linux-security-module in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH v8 18/18] SELinux: Add network ingress and egress control permission checks

2007-12-18 Thread Stephen Smalley
On Tue, 2007-12-18 at 08:59 -0500, Paul Moore wrote:
 On Monday 17 December 2007 3:05:37 pm Stephen Smalley wrote:
  On Sun, 2007-12-16 at 11:47 -0500, Paul Moore wrote:
   We should probably have different permissions for the interface and node
   cases.  Take the example of an admin who is only interested in enforcing
   interface controls and not node controls.  They would most likely write
   the following policy rule to nullify the node check ...
  
allow unlabeled_t peer_t:peer egress;
  
   ... which would end up applying to both the interface and node checks
   because they use the same permission.  I'm thinking we should split the
   permissions like this:
  
allow netif_t peer_t:peer if_egress;
allow netnode_t peer_t: peer node_egress;
  
   ... and do something similar for the ingress side.  Thoughts?
 
  That starts to sound a lot like using netif and node classes instead of
  the peer class.
  allow peer_t netif_t:netif egress;
  allow peer_t netnode_t:node egress;
 
 Thinking about this some more ... egress/ingress make sense from an interface 
 point of view but they sound out of place from a node point of view.  After 
 all, you are not egressing to a node, to are sending to a node.  The same 
 thing applies in the opposite direction, you don't ingress from a node, 
 you receive from a node.  With that in mind I'm thinking of going with the 
 following:
 
  allow netif_t peer_t:peer { ingress egress };
  allow netnode_t peer_t:peer { recv_from send_to };

nit:  recvfrom and sendto don't really require an underscore to be
readable, and we've already set a precedent for them in the socket and
association classes.

 Thoughts?  Should I just forget all this and use the peer label as a subject 
 label?

I'm not certain what we gain by using the peer as the object and class
in these checks, and it seems to make their meaning less clear.  It
should be noted that we already use process labels as both subjects
(when the actor) and objects (when the target/recipient of an action, as
in signal delivery or IPC), and that process labels flow to sockets
they create and socket labels flow to packets they send, and socket
labels likewise serve dual roles as subjects (Can this socket send/recv
this packet?) and objects (Can this process send/recv on this socket?). 

In the case of locally generated or destined traffic, we always have a
local socket that we can use as the subject of the check, which I think
is why we end up not using packet/peer as the subject generally - we
essentially have two subjects to choose from, and we favor the local
one.  But in the forwarded case, the packet/peer is the only
subject/actor in view really.

OTOH, I'm not sure your original concern about unlabeled_t is
well-founded now that I think about it; the netif and node type space is
disjoint and they default to discrete initial SIDs and types (netif_t,
node_t), not to unlabeled_t, right?  So the types themselves encode the
class there.

-- 
Stephen Smalley
National Security Agency

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


Re: [RFC PATCH v8 18/18] SELinux: Add network ingress and egress control permission checks

2007-12-18 Thread Paul Moore
On Tuesday 18 December 2007 10:14:41 am Stephen Smalley wrote:
 On Tue, 2007-12-18 at 08:59 -0500, Paul Moore wrote:
  Thoughts?  Should I just forget all this and use the peer label as a
  subject label?

 I'm not certain what we gain by using the peer as the object and class
 in these checks, and it seems to make their meaning less clear.  It
 should be noted that we already use process labels as both subjects
 (when the actor) and objects (when the target/recipient of an action, as
 in signal delivery or IPC), and that process labels flow to sockets
 they create and socket labels flow to packets they send, and socket
 labels likewise serve dual roles as subjects (Can this socket send/recv
 this packet?) and objects (Can this process send/recv on this socket?).

 In the case of locally generated or destined traffic, we always have a
 local socket that we can use as the subject of the check, which I think
 is why we end up not using packet/peer as the subject generally - we
 essentially have two subjects to choose from, and we favor the local
 one.  But in the forwarded case, the packet/peer is the only
 subject/actor in view really.

Yep, I think you are right and I'm just slow to realize it.  As pointed out 
earlier in the discussion, the awkwardness of using the packet's peer label 
as an object should have clued me into the fact that this was a bad idea.

So, my last question is what permissions do we want to use for the netif/node 
object classes?

 allow peer_t netif_t:netif { egress ingress };
 allow peer_t netnode_t:node { sendto/send recvfrom/recv };

What I'd like to avoid if possible is the protocol specific permissions we 
currently have for the netif and node object classes; it requires extra work 
in the kernel, it doesn't work at all for the forwarding case, and I have my 
doubts about the usefulness of the distinction.  I think the ingress/egress 
permissions still make sense when applied to the netif object class but it's 
a bit of a stretch when applied to the node object class.  I personally like 
the sendto/recvfrom permissions but if that is too much of a violation from 
existing precedence I imagine send/recv would work.

Thoughts?

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line unsubscribe 
linux-security-module in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH v8 18/18] SELinux: Add network ingress and egress control permission checks

2007-12-17 Thread Paul Moore
On Monday 17 December 2007 3:05:37 pm Stephen Smalley wrote:
 On Sun, 2007-12-16 at 11:47 -0500, Paul Moore wrote:
  On Friday 14 December 2007 4:51:29 pm Paul Moore wrote:
   This patch implements packet ingress/egress controls for SELinux which
   allow SELinux security policy to control the flow of all IPv4 and IPv6
   packets into and out of the system.  Currently SELinux does not have
   proper control over forwarded packets and this patch corrects this
   problem.
  
   Special thanks to Venkat Yekkirala [EMAIL PROTECTED] whose
   earlier work on this topic eventually led to this patch.
 
  I've been thinking about this over the weekend and realized a few things
  ...
 
  {snip}
 
   +static int selinux_inet_sys_snd_skb(struct sk_buff *skb, int family)
   +{
   + int err = 0;
   +
   + if (!selinux_policycap_netpeer)
   + return 0;
   +
   + if (netlbl_enabled() || selinux_xfrm_enabled()) {
   + u32 if_sid;
   + u32 node_sid;
   + u32 peer_sid;
   + char *addrp;
   + struct avc_audit_data ad;
   +
   + AVC_AUDIT_DATA_INIT(ad, NET);
   + ad.u.net.netif = skb-iif;
   + ad.u.net.family = family;
   + err = selinux_parse_skb(skb, ad, addrp, 0, NULL);
   + if (err)
   + return err;
   +
   + err = selinux_skb_peerlbl_sid(skb, family, peer_sid);
   + if (err)
   + return err;
 
  I realized I made a mistake here: we should check to see if the skb has a
  socket associated with it and if it does get the peer_sid from there
  instead. If there is no socket to be found then do what we are already
  going above.

 In what case do you expect the two SIDs to diverge?

The case of CIPSO immediately springs to mind.  If you query the packet 
directly you will get a SID similar to what you see on incoming packets: 
the netlabel_peer_t type plus the CIPSO MLS sensitivity label.  If you 
query the socket which originated the packet you'll get the original, native 
SELinux label/SID.  In my mind using the socket's label is a shortcut to get 
the full/true/original/etc. label quickly.

There is most likely also a performance advantage in pulling the SID from the 
socket.

 What if we later provide an API to allow a sender to send a datagram
 with a particular label rather than always requiring them to be the same
 as the sending socket?

Then we can transition from using a mix between socket and packet labels to 
just packet labels.  I don't see any _significant_ barriers to that approach 
in the ingress/egress controls as proposed.  If you do, let me know.

   + err = sel_netif_sid(skb-iif, if_sid);
   + if (err)
   + return err;
   + err = avc_has_perm(if_sid, peer_sid,
   +SECCLASS_PEER, PEER__EGRESS, ad);
   + if (err)
   + return err;
   +
   + err = sel_netnode_sid(addrp, family, node_sid);
   + if (err)
   + return err;
   + err = avc_has_perm(node_sid, peer_sid,
   +SECCLASS_PEER, PEER__EGRESS, ad);
 
  We should probably have different permissions for the interface and node
  cases.  Take the example of an admin who is only interested in enforcing
  interface controls and not node controls.  They would most likely write
  the following policy rule to nullify the node check ...
 
   allow unlabeled_t peer_t:peer egress;
 
  ... which would end up applying to both the interface and node checks
  because they use the same permission.  I'm thinking we should split the
  permissions like this:
 
   allow netif_t peer_t:peer if_egress;
   allow netnode_t peer_t: peer node_egress;
 
  ... and do something similar for the ingress side.  Thoughts?

 That starts to sound a lot like using netif and node classes instead of
 the peer class.
   allow peer_t netif_t:netif egress;
   allow peer_t netnode_t:node egress;

I see you noticed that too :)

I've been mulling this over and over in my head for some time and I'm not sure 
which is better.  I'm leaning towards sticking with the peer object class 
just because it reinforces the decision to treat the packet as an object.  
Good or bad, that is how SELinux currently treats packets and I fear that 
using the packet's peer label as the subject here could get confusing.

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line unsubscribe 
linux-security-module in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH v8 18/18] SELinux: Add network ingress and egress control permission checks

2007-12-16 Thread Paul Moore
On Friday 14 December 2007 4:51:29 pm Paul Moore wrote:
 This patch implements packet ingress/egress controls for SELinux which
 allow SELinux security policy to control the flow of all IPv4 and IPv6
 packets into and out of the system.  Currently SELinux does not have proper
 control over forwarded packets and this patch corrects this problem.

 Special thanks to Venkat Yekkirala [EMAIL PROTECTED] whose earlier
 work on this topic eventually led to this patch.

I've been thinking about this over the weekend and realized a few things ...

{snip}

 +static int selinux_inet_sys_snd_skb(struct sk_buff *skb, int family)
 +{
 + int err = 0;
 +
 + if (!selinux_policycap_netpeer)
 + return 0;
 +
 + if (netlbl_enabled() || selinux_xfrm_enabled()) {
 + u32 if_sid;
 + u32 node_sid;
 + u32 peer_sid;
 + char *addrp;
 + struct avc_audit_data ad;
 +
 + AVC_AUDIT_DATA_INIT(ad, NET);
 + ad.u.net.netif = skb-iif;
 + ad.u.net.family = family;
 + err = selinux_parse_skb(skb, ad, addrp, 0, NULL);
 + if (err)
 + return err;
 +
 + err = selinux_skb_peerlbl_sid(skb, family, peer_sid);
 + if (err)
 + return err;

I realized I made a mistake here: we should check to see if the skb has a 
socket associated with it and if it does get the peer_sid from there instead.  
If there is no socket to be found then do what we are already going above.

 + err = sel_netif_sid(skb-iif, if_sid);
 + if (err)
 + return err;
 + err = avc_has_perm(if_sid, peer_sid,
 +SECCLASS_PEER, PEER__EGRESS, ad);
 + if (err)
 + return err;
 +
 + err = sel_netnode_sid(addrp, family, node_sid);
 + if (err)
 + return err;
 + err = avc_has_perm(node_sid, peer_sid,
 +SECCLASS_PEER, PEER__EGRESS, ad);

We should probably have different permissions for the interface and node 
cases.  Take the example of an admin who is only interested in enforcing 
interface controls and not node controls.  They would most likely write the 
following policy rule to nullify the node check ...

 allow unlabeled_t peer_t:peer egress;

... which would end up applying to both the interface and node checks because 
they use the same permission.  I'm thinking we should split the permissions 
like this:

 allow netif_t peer_t:peer if_egress;
 allow netnode_t peer_t: peer node_egress;

... and do something similar for the ingress side.  Thoughts?

 + }
 +
 + return err;
 +}

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line unsubscribe 
linux-security-module in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html