This patch provides the missing NetLabel support to the secid reconciliation
patchset.

Signed-off-by: Paul Moore <[EMAIL PROTECTED]>
---
 security/selinux/hooks.c                    |   51 ++++++++++++++++++++--------
 security/selinux/include/objsec.h           |    1 
 security/selinux/include/selinux_netlabel.h |   16 +++++++-
 security/selinux/ss/mls.c                   |    2 -
 security/selinux/ss/services.c              |   42 ++++++++++++++++-------
 5 files changed, 82 insertions(+), 30 deletions(-)

Index: net-2.6/security/selinux/hooks.c
===================================================================
--- net-2.6.orig/security/selinux/hooks.c
+++ net-2.6/security/selinux/hooks.c
@@ -3440,6 +3440,10 @@ static int selinux_sock_rcv_skb_compat(s
                        goto out;
        }
 
+       err = selinux_netlbl_sock_rcv_skb(sock_sid, sock_class, skb, ad);
+       if (err)
+               goto out;
+
        err = selinux_xfrm_sock_rcv_skb(sock_sid, skb, ad);
 
 out:
@@ -3476,10 +3480,7 @@ static int selinux_socket_sock_rcv_skb(s
        else
                err = avc_has_perm(sksec->sid, skb->secmark, SECCLASS_PACKET,
                                   PACKET__RECV, &ad);
-       if (err)
-               goto out;
 
-       err = selinux_netlbl_sock_rcv_skb(sksec, skb, &ad);
 out:   
        return err;
 }
@@ -3654,13 +3655,14 @@ static void selinux_req_classify_flow(co
 
 static int selinux_skb_flow_in(struct sk_buff *skb, unsigned short family)
 {
-       u32 xfrm_sid, trans_sid;
+       u32 xfrm_sid;
+       u32 nlbl_sid;
        int err;
 
        if (selinux_compat_net)
                return 1;
 
-       /* xfrm/cipso inapplicable for loopback traffic */
+       /* allow all loopback traffic */
        if (skb->dev == &loopback_dev)
                return 1;
 
@@ -3672,16 +3674,20 @@ static int selinux_skb_flow_in(struct sk
        if (err)
                goto out;
 
-       if (xfrm_sid) {
-               err = security_transition_sid(xfrm_sid, skb->secmark,
-                                               SECCLASS_PACKET, &trans_sid);
-               if (err)
-                       goto out;
+       if (xfrm_sid)
+               skb->secmark = xfrm_sid;
 
-               skb->secmark = trans_sid;
-       }
+       err = selinux_netlbl_skb_sid(skb, skb->secmark, &nlbl_sid);
+       if (err)
+               goto out;
 
-       /* See if CIPSO can flow in thru the current secmark here */
+       err = avc_has_perm(nlbl_sid, skb->secmark, SECCLASS_PACKET,
+                                       PACKET__FLOW_IN, NULL);
+       if (err)
+               goto out;
+
+       if (nlbl_sid)
+               skb->secmark = nlbl_sid;
 
 out:
        return err ? 0 : 1;
@@ -3689,7 +3695,6 @@ out:
 
 static int selinux_skb_flow_out(struct sk_buff *skb, u32 nf_secid)
 {
-       u32 trans_sid;
        int err;
 
        if (selinux_compat_net)
@@ -3697,6 +3702,7 @@ static int selinux_skb_flow_out(struct s
 
        if (!skb->secmark) {
                u32 xfrm_sid;
+               u32 nlbl_sid;
 
                selinux_skb_xfrm_sid(skb, &xfrm_sid);
 
@@ -3706,6 +3712,13 @@ static int selinux_skb_flow_out(struct s
                        struct sk_security_struct *sksec = skb->sk->sk_security;
                        skb->secmark = sksec->sid;
                }
+
+               err = selinux_netlbl_skb_sid(skb, skb->secmark, &nlbl_sid);
+               if (err)
+                       goto out;
+
+               if (nlbl_sid)
+                       skb->secmark = nlbl_sid;
        }
 
        err = avc_has_perm(skb->secmark, nf_secid, SECCLASS_PACKET,
@@ -3861,6 +3874,7 @@ static unsigned int selinux_ip_postroute
        else {
                if (!skb->secmark) {
                        u32 xfrm_sid;
+                       u32 nlbl_sid;
 
                        selinux_skb_xfrm_sid(skb, &xfrm_sid);
 
@@ -3871,6 +3885,15 @@ static unsigned int selinux_ip_postroute
                                                skb->sk->sk_security;
                                skb->secmark = sksec->sid;
                        }
+
+                       err = selinux_netlbl_skb_sid(skb,
+                                                    skb->secmark,
+                                                    &nlbl_sid);
+                       if (err)
+                               goto out;
+
+                       if (nlbl_sid)
+                               skb->secmark = nlbl_sid;
                }
                err = avc_has_perm(skb->secmark, SECINITSID_UNLABELED,
                                   SECCLASS_PACKET, PACKET__FLOW_OUT, &ad);
Index: net-2.6/security/selinux/include/objsec.h
===================================================================
--- net-2.6.orig/security/selinux/include/objsec.h
+++ net-2.6/security/selinux/include/objsec.h
@@ -102,7 +102,6 @@ struct sk_security_struct {
        u32 sid;                        /* SID of this object */
        u32 peer_sid;                   /* SID of peer */
 #ifdef CONFIG_NETLABEL
-       u16 sclass;                     /* sock security class */
        enum {                          /* NetLabel state */
                NLBL_UNSET = 0,
                NLBL_REQUIRE,
Index: net-2.6/security/selinux/include/selinux_netlabel.h
===================================================================
--- net-2.6.orig/security/selinux/include/selinux_netlabel.h
+++ net-2.6/security/selinux/include/selinux_netlabel.h
@@ -43,7 +43,8 @@ int selinux_netlbl_socket_post_create(st
                                      u32 sid);
 void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock);
 u32 selinux_netlbl_inet_conn_request(struct sk_buff *skb, u32 sock_sid);
-int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
+int selinux_netlbl_sock_rcv_skb(u32 sock_sid,
+                               u16 sock_class,
                                struct sk_buff *skb,
                                struct avc_audit_data *ad);
 u32 selinux_netlbl_socket_getpeersec_stream(struct socket *sock);
@@ -53,6 +54,7 @@ void selinux_netlbl_sk_security_init(str
 void selinux_netlbl_sk_clone_security(struct sk_security_struct *ssec,
                                      struct sk_security_struct *newssec);
 int selinux_netlbl_inode_permission(struct inode *inode, int mask);
+int selinux_netlbl_skb_sid(struct sk_buff *skb, u32 base_sid, u32 *sid);
 #else
 static inline void selinux_netlbl_cache_invalidate(void)
 {
@@ -78,7 +80,8 @@ static inline u32 selinux_netlbl_inet_co
        return SECSID_NULL;
 }
 
-static inline int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
+static inline int selinux_netlbl_sock_rcv_skb(u32 sock_sid,
+                                             u16 sock_class,
                                              struct sk_buff *skb,
                                              struct avc_audit_data *ad)
 {
@@ -114,6 +117,15 @@ static inline int selinux_netlbl_inode_p
 {
        return 0;
 }
+
+static inline int selinux_netlbl_skb_sid(struct sk_buff *skb,
+                                        u32 base_sid,
+                                        u32 *sid)
+{
+       *sid = SECINITSID_UNLABELED;
+       return 0;
+}
+
 #endif /* CONFIG_NETLABEL */
 
 #endif
Index: net-2.6/security/selinux/ss/mls.c
===================================================================
--- net-2.6.orig/security/selinux/ss/mls.c
+++ net-2.6/security/selinux/ss/mls.c
@@ -547,7 +547,7 @@ int mls_compute_sid(struct context *scon
                                                     &rtr->target_range);
                        }
                }
-               else if (tclass == SECCLASS_PACKET)
+               if (tclass == SECCLASS_PACKET)
                        return mls_copy_context(newcontext, scontext);
                /* Fallthrough */
        case AVTAB_CHANGE:
Index: net-2.6/security/selinux/ss/services.c
===================================================================
--- net-2.6.orig/security/selinux/ss/services.c
+++ net-2.6/security/selinux/ss/services.c
@@ -2456,7 +2456,6 @@ void selinux_netlbl_sk_security_init(str
 void selinux_netlbl_sk_clone_security(struct sk_security_struct *ssec,
                                      struct sk_security_struct *newssec)
 {
-       newssec->sclass = ssec->sclass;
        if (ssec->nlbl_state != NLBL_UNSET)
                newssec->nlbl_state = NLBL_REQUIRE;
        else
@@ -2478,11 +2477,8 @@ int selinux_netlbl_socket_post_create(st
                                      int sock_family,
                                      u32 sid)
 {
-       struct inode_security_struct *isec = SOCK_INODE(sock)->i_security;
        struct sk_security_struct *sksec = sock->sk->sk_security;
 
-       sksec->sclass = isec->sclass;
-
        if (sock_family != PF_INET)
                return 0;
 
@@ -2502,13 +2498,10 @@ int selinux_netlbl_socket_post_create(st
  */
 void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock)
 {
-       struct inode_security_struct *isec = SOCK_INODE(sock)->i_security;
        struct sk_security_struct *sksec = sk->sk_security;
        struct netlbl_lsm_secattr secattr;
        u32 nlbl_peer_sid;
 
-       sksec->sclass = isec->sclass;
-
        if (sk->sk_family != PF_INET)
                return;
 
@@ -2595,7 +2588,8 @@ int selinux_netlbl_inode_permission(stru
 
 /**
  * selinux_netlbl_sock_rcv_skb - Do an inbound access check using NetLabel
- * @sksec: the sock's sk_security_struct
+ * @sock_sid: the socket's SID
+ * @sock_class: the socket's class
  * @skb: the packet
  * @ad: the audit data
  *
@@ -2605,7 +2599,8 @@ int selinux_netlbl_inode_permission(stru
  * error.
  *
  */
-int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
+int selinux_netlbl_sock_rcv_skb(u32 sock_sid,
+                               u16 sock_class,
                                struct sk_buff *skb,
                                struct avc_audit_data *ad)
 {
@@ -2620,7 +2615,7 @@ int selinux_netlbl_sock_rcv_skb(struct s
        if (netlbl_sid == SECINITSID_UNLABELED)
                return 0;
 
-       switch (sksec->sclass) {
+       switch (sock_class) {
        case SECCLASS_UDP_SOCKET:
                recv_perm = UDP_SOCKET__RECVFROM;
                break;
@@ -2631,9 +2626,9 @@ int selinux_netlbl_sock_rcv_skb(struct s
                recv_perm = RAWIP_SOCKET__RECVFROM;
        }
 
-       rc = avc_has_perm(sksec->sid,
+       rc = avc_has_perm(sock_sid,
                          netlbl_sid,
-                         sksec->sclass,
+                         sock_class,
                          recv_perm,
                          ad);
        if (rc == 0)
@@ -2688,4 +2683,27 @@ u32 selinux_netlbl_socket_getpeersec_dgr
 
        return peer_sid;
 }
+
+/**
+ * selinux_netlbl_skb_sid - Calculate the NetLabel SID of a packet
+ * @skb: the packet
+ * @base_sid: the SELinux SID to use as a context for MLS only attributes
+ * @sid: the SID
+ *
+ * Description:
+ * Call the NetLabel mechanism to get the security attributes of the given
+ * packet and use those attributes to determine the correct context/SID to
+ * assign to the packet.  Returns zero on success, negative values on failure.
+ *
+ */
+int selinux_netlbl_skb_sid(struct sk_buff *skb, u32 base_sid, u32 *sid)
+{
+       int rc;
+
+       rc = selinux_netlbl_skbuff_getsid(skb, base_sid, sid);
+       if (rc == 0 && *sid == SECINITSID_UNLABELED)
+               *sid = 0;
+
+       return rc;
+}
 #endif /* CONFIG_NETLABEL */

--
paul moore
linux security @ hp
-
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

Reply via email to