aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Moore <pmoore@redhat.com>2013-12-10 14:58:01 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-01-09 15:24:24 -0500
commit0fdb9385a5909c218fa2cf0cf62896ebe0fcf30e (patch)
tree7cfeda1086e30884e1a5ffe6c2a44084eac5c5aa
parent070357081f37bb70ff1a09630c50529188846280 (diff)
selinux: process labeled IPsec TCP SYN-ACK packets properly in selinux_ip_postroute()
commit c0828e50485932b7e019df377a6b0a8d1ebd3080 upstream. Due to difficulty in arriving at the proper security label for TCP SYN-ACK packets in selinux_ip_postroute(), we need to check packets while/before they are undergoing XFRM transforms instead of waiting until afterwards so that we can determine the correct security label. Reported-by: Janak Desai <Janak.Desai@gtri.gatech.edu> Signed-off-by: Paul Moore <pmoore@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--security/selinux/hooks.c43
1 files changed, 36 insertions, 7 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index ec39490ec8fd..57f14185cf18 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -4742,22 +4742,32 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
4742 * as fast and as clean as possible. */ 4742 * as fast and as clean as possible. */
4743 if (!selinux_policycap_netpeer) 4743 if (!selinux_policycap_netpeer)
4744 return selinux_ip_postroute_compat(skb, ifindex, family); 4744 return selinux_ip_postroute_compat(skb, ifindex, family);
4745
4746 secmark_active = selinux_secmark_enabled();
4747 peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled();
4748 if (!secmark_active && !peerlbl_active)
4749 return NF_ACCEPT;
4750
4751 sk = skb->sk;
4752
4745#ifdef CONFIG_XFRM 4753#ifdef CONFIG_XFRM
4746 /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec 4754 /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec
4747 * packet transformation so allow the packet to pass without any checks 4755 * packet transformation so allow the packet to pass without any checks
4748 * since we'll have another chance to perform access control checks 4756 * since we'll have another chance to perform access control checks
4749 * when the packet is on it's final way out. 4757 * when the packet is on it's final way out.
4750 * NOTE: there appear to be some IPv6 multicast cases where skb->dst 4758 * NOTE: there appear to be some IPv6 multicast cases where skb->dst
4751 * is NULL, in this case go ahead and apply access control. */ 4759 * is NULL, in this case go ahead and apply access control.
4752 if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL) 4760 * is NULL, in this case go ahead and apply access control.
4761 * NOTE: if this is a local socket (skb->sk != NULL) that is in the
4762 * TCP listening state we cannot wait until the XFRM processing
4763 * is done as we will miss out on the SA label if we do;
4764 * unfortunately, this means more work, but it is only once per
4765 * connection. */
4766 if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL &&
4767 !(sk != NULL && sk->sk_state == TCP_LISTEN))
4753 return NF_ACCEPT; 4768 return NF_ACCEPT;
4754#endif 4769#endif
4755 secmark_active = selinux_secmark_enabled();
4756 peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled();
4757 if (!secmark_active && !peerlbl_active)
4758 return NF_ACCEPT;
4759 4770
4760 sk = skb->sk;
4761 if (sk == NULL) { 4771 if (sk == NULL) {
4762 /* Without an associated socket the packet is either coming 4772 /* Without an associated socket the packet is either coming
4763 * from the kernel or it is being forwarded; check the packet 4773 * from the kernel or it is being forwarded; check the packet
@@ -4785,6 +4795,25 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
4785 struct sk_security_struct *sksec = sk->sk_security; 4795 struct sk_security_struct *sksec = sk->sk_security;
4786 if (selinux_skb_peerlbl_sid(skb, family, &skb_sid)) 4796 if (selinux_skb_peerlbl_sid(skb, family, &skb_sid))
4787 return NF_DROP; 4797 return NF_DROP;
4798 /* At this point, if the returned skb peerlbl is SECSID_NULL
4799 * and the packet has been through at least one XFRM
4800 * transformation then we must be dealing with the "final"
4801 * form of labeled IPsec packet; since we've already applied
4802 * all of our access controls on this packet we can safely
4803 * pass the packet. */
4804 if (skb_sid == SECSID_NULL) {
4805 switch (family) {
4806 case PF_INET:
4807 if (IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED)
4808 return NF_ACCEPT;
4809 break;
4810 case PF_INET6:
4811 if (IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED)
4812 return NF_ACCEPT;
4813 default:
4814 return NF_DROP_ERR(-ECONNREFUSED);
4815 }
4816 }
4788 if (selinux_conn_sid(sksec->sid, skb_sid, &peer_sid)) 4817 if (selinux_conn_sid(sksec->sid, skb_sid, &peer_sid))
4789 return NF_DROP; 4818 return NF_DROP;
4790 secmark_perm = PACKET__SEND; 4819 secmark_perm = PACKET__SEND;