labeled-ipsec: Fix SA selection semantics
Subsystems (5)
PATCH 3/3 labeled-ipsec: Fix SA selection semantics
Fix the selection of an SA for an outgoing packet to be at the same context as the originating socket/flow. This eliminates the SELinux policy's ability to use/sendto SAs with contexts other than the socket's.
With this patch applied, the SELinux policy will require one or more of the following for a socket to be able to communicate with/without SAs:
1. To enable a socket to communicate without using labeled-IPSec SAs:
allow socket_t unlabeled_t:association { sendto recvfrom }
2. To enable a socket to communicate with labeled-IPSec SAs:
allow socket_t self:association { sendto }; allow socket_t peer_sa_t:association { recvfrom };
--- include/linux/security.h | 19 ----- net/xfrm/xfrm_policy.c | 3 security/dummy.c | 7 -- security/selinux/hooks.c | 26 +++++-- security/selinux/include/xfrm.h | 7 -- security/selinux/xfrm.c | 101 ++++++++++++++---------------- 6 files changed, 70 insertions(+), 93 deletions(-)
include/linux/security.h +0 -19
@@ -886,11 +886,6 @@ struct request_sock;* @xp contains the policy to check for a match. * @fl contains the flow to check for a match. * Return 1 if there is a match. -* @xfrm_flow_state_match: -* @fl contains the flow key to match. -* @xfrm points to the xfrm_state to match. -* @xp points to the xfrm_policy to match. -* Return 1 if there is a match. * @xfrm_decode_session: * @skb points to skb to decode. * @secid points to the flow key secid to set.
@@ -1388,8 +1383,6 @@ struct security_operations {int (*xfrm_policy_lookup)(struct xfrm_policy *xp,u32 fl_secid,u8 dir);int (*xfrm_state_pol_flow_match)(struct xfrm_state *x,struct xfrm_policy *xp,struct flowi *fl); -int (*xfrm_flow_state_match)(struct flowi *fl,struct xfrm_state *xfrm, -struct xfrm_policy *xp);int (*xfrm_decode_session)(struct sk_buff *skb,u32 *secid,int ckall);#endif /* CONFIG_SECURITY_NETWORK_XFRM */
@@ -3186,12 +3179,6 @@ static inline int security_xfrm_state_poreturn security_ops->xfrm_state_pol_flow_match (x, xp, fl); } -static inline int security_xfrm_flow_state_match (struct flowi *fl, -struct xfrm_state *xfrm,struct xfrm_policy *xp) -{ -return security_ops->xfrm_flow_state_match (fl, xfrm, xp); -} -static inline int security_xfrm_decode_session (struct sk_buff *skb,u32 *secid) {return security_ops->xfrm_decode_session (skb, secid,1 );
@@ -3255,12 +3242,6 @@ static inline int security_xfrm_state_poreturn 1 ; } -static inline int security_xfrm_flow_state_match (struct flowi *fl, -struct xfrm_state *xfrm,struct xfrm_policy *xp) -{ -return 1 ; -} -static inline int security_xfrm_decode_session (struct sk_buff *skb,u32 *secid) {return 0 ;
net/xfrm/xfrm_policy.c +2 -1
@@ -1894,7 +1894,8 @@ int xfrm_bundle_ok(struct xfrm_policy *pif (fl && !xfrm_selector_match (&dst->xfrm->sel, fl, family))return 0 ; -if (fl && !security_xfrm_flow_state_match (fl, dst->xfrm, pol)) +if (fl && pol && + !security_xfrm_state_pol_flow_match (dst->xfrm, pol, fl))return 0 ;if (dst->xfrm->km.state !=XFRM_STATE_VALID )return 0 ;
security/dummy.c +0 -7
@@ -886,12 +886,6 @@ static int dummy_xfrm_state_pol_flow_matreturn 1 ; } -static int dummy_xfrm_flow_state_match (struct flowi *fl,struct xfrm_state *xfrm, -struct xfrm_policy *xp) -{ -return 1 ; -} -static int dummy_xfrm_decode_session (struct sk_buff *skb,u32 *fl,int ckall) {return 0 ;
@@ -1126,7 +1120,6 @@ void security_fixup_ops (struct securityset_to_dummy_if_null (ops, xfrm_state_delete_security);set_to_dummy_if_null (ops, xfrm_policy_lookup);set_to_dummy_if_null (ops, xfrm_state_pol_flow_match); -set_to_dummy_if_null (ops, xfrm_flow_state_match);set_to_dummy_if_null (ops, xfrm_decode_session);#endif /* CONFIG_SECURITY_NETWORK_XFRM */ #ifdef CONFIG_KEYS
security/selinux/include/xfrm.h +2 -5
@@ -19,9 +19,6 @@ int selinux_xfrm_state_delete(struct xfrint selinux_xfrm_policy_lookup (struct xfrm_policy *xp,u32 fl_secid,u8 dir);int selinux_xfrm_state_pol_flow_match (struct xfrm_state *x,struct xfrm_policy *xp,struct flowi *fl); -int selinux_xfrm_flow_state_match (struct flowi *fl,struct xfrm_state *xfrm, -struct xfrm_policy *xp); -/* * Extract the security blob from the sock (it's actually on the socket)
@@ -38,7 +35,7 @@ static inline struct inode_security_struint selinux_xfrm_sock_rcv_skb (u32 sid,struct sk_buff *skb,struct avc_audit_data *ad);int selinux_xfrm_postroute_last (u32 isec_sid,struct sk_buff *skb, -struct avc_audit_data *ad); +struct avc_audit_data *ad,u8 proto);u32 selinux_socket_getpeer_dgram (struct sk_buff *skb);int selinux_xfrm_decode_session (struct sk_buff *skb,u32 *sid,int ckall);#else
@@ -49,7 +46,7 @@ static inline int selinux_xfrm_sock_rcv_ }static inline int selinux_xfrm_postroute_last (u32 isec_sid,struct sk_buff *skb, -struct avc_audit_data *ad) +struct avc_audit_data *ad,u8 proto) {return 0 ; }
security/selinux/hooks.c +17 -9
@@ -2888,7 +2888,8 @@ static void selinux_task_to_inode(struct }/* Returns error only if unable to parse addresses */ -static int selinux_parse_skb_ipv4 (struct sk_buff *skb,struct avc_audit_data *ad) +static int selinux_parse_skb_ipv4 (struct sk_buff *skb, +struct avc_audit_data *ad,u8 *proto) {int offset, ihlen, ret = -EINVAL ;struct iphdr _iph, *ih;
@@ -2906,6 +2907,9 @@ static int selinux_parse_skb_ipv4(struct ad->u.net.v4info.daddr = ih->daddr; ret =0 ; +if (proto) + *proto = ih->protocol; +switch (ih->protocol) {case IPPROTO_TCP : {struct tcphdr _tcph, *th;
@@ -2949,7 +2953,8 @@ out:#if defined(CONFIG_IPV6 ) || defined(CONFIG_IPV6_MODULE )/* Returns error only if unable to parse addresses */ -static int selinux_parse_skb_ipv6 (struct sk_buff *skb,struct avc_audit_data *ad) +static int selinux_parse_skb_ipv6 (struct sk_buff *skb, +struct avc_audit_data *ad,u8 *proto) {u8 nexthdr;int ret = -EINVAL , offset;
@@ -2970,6 +2975,9 @@ static int selinux_parse_skb_ipv6(structif (offset <0 ) goto out; +if (proto) + *proto = nexthdr; +switch (nexthdr) {case IPPROTO_TCP : {struct tcphdr _tcph, *th;
@@ -3006,13 +3014,13 @@ out:#endif /* IPV6 */ static int selinux_parse_skb (struct sk_buff *skb,struct avc_audit_data *ad, -char **addrp,int *len,int src) +char **addrp,int *len,int src,u8 *proto) {int ret =0 ;switch (ad->u.net.family) {case PF_INET : - ret =selinux_parse_skb_ipv4 (skb, ad); + ret =selinux_parse_skb_ipv4 (skb, ad, proto);if (ret || !addrp)break ; *len =4 ;
@@ -3022,7 +3030,7 @@ static int selinux_parse_skb(struct sk_b#if defined(CONFIG_IPV6 ) || defined(CONFIG_IPV6_MODULE )case PF_INET6 : - ret =selinux_parse_skb_ipv6 (skb, ad); + ret =selinux_parse_skb_ipv6 (skb, ad, proto);if (ret || !addrp)break ; *len =16 ;
@@ -3493,7 +3501,7 @@ static int selinux_socket_sock_rcv_skb(s ad.u.net.netif = skb->dev ? skb->dev->name :"[unknown]" ; ad.u.net.family = family; - err =selinux_parse_skb (skb, &ad, &addrp, &len,1 ); + err =selinux_parse_skb (skb, &ad, &addrp, &len,1 ,NULL );if (err) goto out;
@@ -3819,6 +3827,7 @@ static unsigned int selinux_ip_postroutestruct avc_audit_data ad;struct net_device *dev = (struct net_device *)out;struct sk_security_struct *sksec; +u8 proto; sk = skb->sk;if (!sk)
@@ -3830,7 +3839,7 @@ static unsigned int selinux_ip_postroute ad.u.net.netif = dev->name; ad.u.net.family = family; - err =selinux_parse_skb (skb, &ad, &addrp, &len,0 ); + err =selinux_parse_skb (skb, &ad, &addrp, &len,0 , &proto);if (err) goto out;
@@ -3844,7 +3853,7 @@ static unsigned int selinux_ip_postrouteif (err) goto out; - err =selinux_xfrm_postroute_last (sksec->sid, skb, &ad); + err =selinux_xfrm_postroute_last (sksec->sid, skb, &ad, proto); out:return err ?NF_DROP :NF_ACCEPT ; }
@@ -4763,7 +4772,6 @@ static struct security_operations selinu .xfrm_state_delete_security = selinux_xfrm_state_delete, .xfrm_policy_lookup = selinux_xfrm_policy_lookup, .xfrm_state_pol_flow_match = selinux_xfrm_state_pol_flow_match, - .xfrm_flow_state_match = selinux_xfrm_flow_state_match, .xfrm_decode_session = selinux_xfrm_decode_session,#endif
security/selinux/xfrm.c +49 -52
142 lines not on this page · raw message
--
This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.