]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Jan 2014 21:51:49 +0000 (13:51 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Jan 2014 21:51:49 +0000 (13:51 -0800)
added patches:
selinux-look-for-ipsec-labels-on-both-inbound-and-outbound-packets.patch
selinux-process-labeled-ipsec-tcp-syn-ack-packets-properly-in-selinux_ip_postroute.patch

queue-3.4/selinux-look-for-ipsec-labels-on-both-inbound-and-outbound-packets.patch [new file with mode: 0644]
queue-3.4/selinux-process-labeled-ipsec-tcp-syn-ack-packets-properly-in-selinux_ip_postroute.patch [new file with mode: 0644]
queue-3.4/series

diff --git a/queue-3.4/selinux-look-for-ipsec-labels-on-both-inbound-and-outbound-packets.patch b/queue-3.4/selinux-look-for-ipsec-labels-on-both-inbound-and-outbound-packets.patch
new file mode 100644 (file)
index 0000000..6292c4c
--- /dev/null
@@ -0,0 +1,135 @@
+From 817eff718dca4e54d5721211ddde0914428fbb7c Mon Sep 17 00:00:00 2001
+From: Paul Moore <pmoore@redhat.com>
+Date: Tue, 10 Dec 2013 14:57:54 -0500
+Subject: selinux: look for IPsec labels on both inbound and outbound packets
+
+From: Paul Moore <pmoore@redhat.com>
+
+commit 817eff718dca4e54d5721211ddde0914428fbb7c upstream.
+
+Previously selinux_skb_peerlbl_sid() would only check for labeled
+IPsec security labels on inbound packets, this patch enables it to
+check both inbound and outbound traffic for labeled IPsec security
+labels.
+
+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>
+
+---
+ security/selinux/hooks.c        |    2 -
+ security/selinux/include/xfrm.h |    9 +++---
+ security/selinux/xfrm.c         |   53 +++++++++++++++++++++++++++++++---------
+ 3 files changed, 48 insertions(+), 16 deletions(-)
+
+--- a/security/selinux/hooks.c
++++ b/security/selinux/hooks.c
+@@ -3720,7 +3720,7 @@ static int selinux_skb_peerlbl_sid(struc
+       u32 nlbl_sid;
+       u32 nlbl_type;
+-      selinux_skb_xfrm_sid(skb, &xfrm_sid);
++      selinux_xfrm_skb_sid(skb, &xfrm_sid);
+       selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid);
+       err = security_net_peersid_resolve(nlbl_sid, nlbl_type, xfrm_sid, sid);
+--- a/security/selinux/include/xfrm.h
++++ b/security/selinux/include/xfrm.h
+@@ -47,6 +47,7 @@ int selinux_xfrm_sock_rcv_skb(u32 sid, s
+ int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb,
+                       struct common_audit_data *ad, u8 proto);
+ int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall);
++int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid);
+ static inline void selinux_xfrm_notify_policyload(void)
+ {
+@@ -79,12 +80,12 @@ static inline int selinux_xfrm_decode_se
+ static inline void selinux_xfrm_notify_policyload(void)
+ {
+ }
+-#endif
+-static inline void selinux_skb_xfrm_sid(struct sk_buff *skb, u32 *sid)
++static inline int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid)
+ {
+-      int err = selinux_xfrm_decode_session(skb, sid, 0);
+-      BUG_ON(err);
++      *sid = SECSID_NULL;
++      return 0;
+ }
++#endif
+ #endif /* _SELINUX_XFRM_H_ */
+--- a/security/selinux/xfrm.c
++++ b/security/selinux/xfrm.c
+@@ -152,21 +152,13 @@ int selinux_xfrm_state_pol_flow_match(st
+       return rc;
+ }
+-/*
+- * LSM hook implementation that checks and/or returns the xfrm sid for the
+- * incoming packet.
+- */
+-
+-int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
++static int selinux_xfrm_skb_sid_ingress(struct sk_buff *skb,
++                                      u32 *sid, int ckall)
+ {
+-      struct sec_path *sp;
++      struct sec_path *sp = skb->sp;
+       *sid = SECSID_NULL;
+-      if (skb == NULL)
+-              return 0;
+-
+-      sp = skb->sp;
+       if (sp) {
+               int i, sid_set = 0;
+@@ -190,6 +182,45 @@ int selinux_xfrm_decode_session(struct s
+       return 0;
+ }
++static u32 selinux_xfrm_skb_sid_egress(struct sk_buff *skb)
++{
++      struct dst_entry *dst = skb_dst(skb);
++      struct xfrm_state *x;
++
++      if (dst == NULL)
++              return SECSID_NULL;
++      x = dst->xfrm;
++      if (x == NULL || !selinux_authorizable_xfrm(x))
++              return SECSID_NULL;
++
++      return x->security->ctx_sid;
++}
++
++/*
++ * LSM hook implementation that checks and/or returns the xfrm sid for the
++ * incoming packet.
++ */
++
++int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
++{
++      if (skb == NULL) {
++              *sid = SECSID_NULL;
++              return 0;
++      }
++      return selinux_xfrm_skb_sid_ingress(skb, sid, ckall);
++}
++
++int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid)
++{
++      int rc;
++
++      rc = selinux_xfrm_skb_sid_ingress(skb, sid, 0);
++      if (rc == 0 && *sid == SECSID_NULL)
++              *sid = selinux_xfrm_skb_sid_egress(skb);
++
++      return rc;
++}
++
+ /*
+  * Security blob allocation for xfrm_policy and xfrm_state
+  * CTX does not have a meaningful value on input
diff --git a/queue-3.4/selinux-process-labeled-ipsec-tcp-syn-ack-packets-properly-in-selinux_ip_postroute.patch b/queue-3.4/selinux-process-labeled-ipsec-tcp-syn-ack-packets-properly-in-selinux_ip_postroute.patch
new file mode 100644 (file)
index 0000000..8e07804
--- /dev/null
@@ -0,0 +1,90 @@
+From c0828e50485932b7e019df377a6b0a8d1ebd3080 Mon Sep 17 00:00:00 2001
+From: Paul Moore <pmoore@redhat.com>
+Date: Tue, 10 Dec 2013 14:58:01 -0500
+Subject: selinux: process labeled IPsec TCP SYN-ACK packets properly in selinux_ip_postroute()
+
+From: Paul Moore <pmoore@redhat.com>
+
+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>
+
+---
+ security/selinux/hooks.c |   43 ++++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 36 insertions(+), 7 deletions(-)
+
+--- a/security/selinux/hooks.c
++++ b/security/selinux/hooks.c
+@@ -4729,22 +4729,32 @@ static unsigned int selinux_ip_postroute
+        * as fast and as clean as possible. */
+       if (!selinux_policycap_netpeer)
+               return selinux_ip_postroute_compat(skb, ifindex, family);
++
++      secmark_active = selinux_secmark_enabled();
++      peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled();
++      if (!secmark_active && !peerlbl_active)
++              return NF_ACCEPT;
++
++      sk = skb->sk;
++
+ #ifdef CONFIG_XFRM
+       /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec
+        * packet transformation so allow the packet to pass without any checks
+        * since we'll have another chance to perform access control checks
+        * when the packet is on it's final way out.
+        * NOTE: there appear to be some IPv6 multicast cases where skb->dst
+-       *       is NULL, in this case go ahead and apply access control. */
+-      if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL)
++       *       is NULL, in this case go ahead and apply access control.
++       *       is NULL, in this case go ahead and apply access control.
++       * NOTE: if this is a local socket (skb->sk != NULL) that is in the
++       *       TCP listening state we cannot wait until the XFRM processing
++       *       is done as we will miss out on the SA label if we do;
++       *       unfortunately, this means more work, but it is only once per
++       *       connection. */
++      if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL &&
++          !(sk != NULL && sk->sk_state == TCP_LISTEN))
+               return NF_ACCEPT;
+ #endif
+-      secmark_active = selinux_secmark_enabled();
+-      peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled();
+-      if (!secmark_active && !peerlbl_active)
+-              return NF_ACCEPT;
+-      sk = skb->sk;
+       if (sk == NULL) {
+               /* Without an associated socket the packet is either coming
+                * from the kernel or it is being forwarded; check the packet
+@@ -4772,6 +4782,25 @@ static unsigned int selinux_ip_postroute
+               struct sk_security_struct *sksec = sk->sk_security;
+               if (selinux_skb_peerlbl_sid(skb, family, &skb_sid))
+                       return NF_DROP;
++              /* At this point, if the returned skb peerlbl is SECSID_NULL
++               * and the packet has been through at least one XFRM
++               * transformation then we must be dealing with the "final"
++               * form of labeled IPsec packet; since we've already applied
++               * all of our access controls on this packet we can safely
++               * pass the packet. */
++              if (skb_sid == SECSID_NULL) {
++                      switch (family) {
++                      case PF_INET:
++                              if (IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED)
++                                      return NF_ACCEPT;
++                              break;
++                      case PF_INET6:
++                              if (IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED)
++                                      return NF_ACCEPT;
++                      default:
++                              return NF_DROP_ERR(-ECONNREFUSED);
++                      }
++              }
+               if (selinux_conn_sid(sksec->sid, skb_sid, &peer_sid))
+                       return NF_DROP;
+               secmark_perm = PACKET__SEND;
index 44a8e5b897636ccc992f1dcb984af9189afb4a2a..c94106041aff367c9f77d6ffa9417f0600161bb0 100644 (file)
@@ -38,3 +38,5 @@ jbd2-don-t-bug-but-return-enospc-if-a-handle-runs-out-of-space.patch
 gpio-msm-fix-irq-mask-unmask-by-writing-bits-instead-of-numbers.patch
 sched-avoid-throttle_cfs_rq-racing-with-period_timer-stopping.patch
 sh-always-link-in-helper-functions-extracted-from-libgcc.patch
+selinux-look-for-ipsec-labels-on-both-inbound-and-outbound-packets.patch
+selinux-process-labeled-ipsec-tcp-syn-ack-packets-properly-in-selinux_ip_postroute.patch