From: Greg Kroah-Hartman Date: Mon, 6 Jan 2014 21:51:49 +0000 (-0800) Subject: 3.4-stable patches X-Git-Tag: v3.4.76~25 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=36b11f3ca82acacfe85be1b8d0d099c46ab26259;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches 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 --- 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 index 00000000000..6292c4c21b9 --- /dev/null +++ b/queue-3.4/selinux-look-for-ipsec-labels-on-both-inbound-and-outbound-packets.patch @@ -0,0 +1,135 @@ +From 817eff718dca4e54d5721211ddde0914428fbb7c Mon Sep 17 00:00:00 2001 +From: Paul Moore +Date: Tue, 10 Dec 2013 14:57:54 -0500 +Subject: selinux: look for IPsec labels on both inbound and outbound packets + +From: Paul Moore + +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 +Signed-off-by: Paul Moore +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..8e07804316a --- /dev/null +++ b/queue-3.4/selinux-process-labeled-ipsec-tcp-syn-ack-packets-properly-in-selinux_ip_postroute.patch @@ -0,0 +1,90 @@ +From c0828e50485932b7e019df377a6b0a8d1ebd3080 Mon Sep 17 00:00:00 2001 +From: Paul Moore +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 + +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 +Signed-off-by: Paul Moore +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-3.4/series b/queue-3.4/series index 44a8e5b8976..c94106041af 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -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