aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
authorVenkat Yekkirala <vyekkirala@trustedcs.com>2006-11-08 18:04:26 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-12-03 00:21:34 -0500
commit67f83cbf081a70426ff667e8d14f94e13ed3bdca (patch)
tree776a40733eacb9071478f865e6791daa3f6fd602 /security/selinux/hooks.c
parent6b877699c6f1efede4545bcecc367786a472eedb (diff)
SELinux: 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 }; Signed-off-by: Venkat Yekkirala <vyekkirala@TrustedCS.com> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 5bbd599a4471..956137baf3e7 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2889,7 +2889,8 @@ static void selinux_task_to_inode(struct task_struct *p,
2889} 2889}
2890 2890
2891/* Returns error only if unable to parse addresses */ 2891/* Returns error only if unable to parse addresses */
2892static int selinux_parse_skb_ipv4(struct sk_buff *skb, struct avc_audit_data *ad) 2892static int selinux_parse_skb_ipv4(struct sk_buff *skb,
2893 struct avc_audit_data *ad, u8 *proto)
2893{ 2894{
2894 int offset, ihlen, ret = -EINVAL; 2895 int offset, ihlen, ret = -EINVAL;
2895 struct iphdr _iph, *ih; 2896 struct iphdr _iph, *ih;
@@ -2907,6 +2908,9 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb, struct avc_audit_data *ad
2907 ad->u.net.v4info.daddr = ih->daddr; 2908 ad->u.net.v4info.daddr = ih->daddr;
2908 ret = 0; 2909 ret = 0;
2909 2910
2911 if (proto)
2912 *proto = ih->protocol;
2913
2910 switch (ih->protocol) { 2914 switch (ih->protocol) {
2911 case IPPROTO_TCP: { 2915 case IPPROTO_TCP: {
2912 struct tcphdr _tcph, *th; 2916 struct tcphdr _tcph, *th;
@@ -2950,7 +2954,8 @@ out:
2950#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 2954#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
2951 2955
2952/* Returns error only if unable to parse addresses */ 2956/* Returns error only if unable to parse addresses */
2953static int selinux_parse_skb_ipv6(struct sk_buff *skb, struct avc_audit_data *ad) 2957static int selinux_parse_skb_ipv6(struct sk_buff *skb,
2958 struct avc_audit_data *ad, u8 *proto)
2954{ 2959{
2955 u8 nexthdr; 2960 u8 nexthdr;
2956 int ret = -EINVAL, offset; 2961 int ret = -EINVAL, offset;
@@ -2971,6 +2976,9 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb, struct avc_audit_data *ad
2971 if (offset < 0) 2976 if (offset < 0)
2972 goto out; 2977 goto out;
2973 2978
2979 if (proto)
2980 *proto = nexthdr;
2981
2974 switch (nexthdr) { 2982 switch (nexthdr) {
2975 case IPPROTO_TCP: { 2983 case IPPROTO_TCP: {
2976 struct tcphdr _tcph, *th; 2984 struct tcphdr _tcph, *th;
@@ -3007,13 +3015,13 @@ out:
3007#endif /* IPV6 */ 3015#endif /* IPV6 */
3008 3016
3009static int selinux_parse_skb(struct sk_buff *skb, struct avc_audit_data *ad, 3017static int selinux_parse_skb(struct sk_buff *skb, struct avc_audit_data *ad,
3010 char **addrp, int *len, int src) 3018 char **addrp, int *len, int src, u8 *proto)
3011{ 3019{
3012 int ret = 0; 3020 int ret = 0;
3013 3021
3014 switch (ad->u.net.family) { 3022 switch (ad->u.net.family) {
3015 case PF_INET: 3023 case PF_INET:
3016 ret = selinux_parse_skb_ipv4(skb, ad); 3024 ret = selinux_parse_skb_ipv4(skb, ad, proto);
3017 if (ret || !addrp) 3025 if (ret || !addrp)
3018 break; 3026 break;
3019 *len = 4; 3027 *len = 4;
@@ -3023,7 +3031,7 @@ static int selinux_parse_skb(struct sk_buff *skb, struct avc_audit_data *ad,
3023 3031
3024#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 3032#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3025 case PF_INET6: 3033 case PF_INET6:
3026 ret = selinux_parse_skb_ipv6(skb, ad); 3034 ret = selinux_parse_skb_ipv6(skb, ad, proto);
3027 if (ret || !addrp) 3035 if (ret || !addrp)
3028 break; 3036 break;
3029 *len = 16; 3037 *len = 16;
@@ -3494,7 +3502,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
3494 ad.u.net.netif = skb->dev ? skb->dev->name : "[unknown]"; 3502 ad.u.net.netif = skb->dev ? skb->dev->name : "[unknown]";
3495 ad.u.net.family = family; 3503 ad.u.net.family = family;
3496 3504
3497 err = selinux_parse_skb(skb, &ad, &addrp, &len, 1); 3505 err = selinux_parse_skb(skb, &ad, &addrp, &len, 1, NULL);
3498 if (err) 3506 if (err)
3499 goto out; 3507 goto out;
3500 3508
@@ -3820,6 +3828,7 @@ static unsigned int selinux_ip_postroute_last(unsigned int hooknum,
3820 struct avc_audit_data ad; 3828 struct avc_audit_data ad;
3821 struct net_device *dev = (struct net_device *)out; 3829 struct net_device *dev = (struct net_device *)out;
3822 struct sk_security_struct *sksec; 3830 struct sk_security_struct *sksec;
3831 u8 proto;
3823 3832
3824 sk = skb->sk; 3833 sk = skb->sk;
3825 if (!sk) 3834 if (!sk)
@@ -3831,7 +3840,7 @@ static unsigned int selinux_ip_postroute_last(unsigned int hooknum,
3831 ad.u.net.netif = dev->name; 3840 ad.u.net.netif = dev->name;
3832 ad.u.net.family = family; 3841 ad.u.net.family = family;
3833 3842
3834 err = selinux_parse_skb(skb, &ad, &addrp, &len, 0); 3843 err = selinux_parse_skb(skb, &ad, &addrp, &len, 0, &proto);
3835 if (err) 3844 if (err)
3836 goto out; 3845 goto out;
3837 3846
@@ -3845,7 +3854,7 @@ static unsigned int selinux_ip_postroute_last(unsigned int hooknum,
3845 if (err) 3854 if (err)
3846 goto out; 3855 goto out;
3847 3856
3848 err = selinux_xfrm_postroute_last(sksec->sid, skb, &ad); 3857 err = selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto);
3849out: 3858out:
3850 return err ? NF_DROP : NF_ACCEPT; 3859 return err ? NF_DROP : NF_ACCEPT;
3851} 3860}
@@ -4764,7 +4773,6 @@ static struct security_operations selinux_ops = {
4764 .xfrm_state_delete_security = selinux_xfrm_state_delete, 4773 .xfrm_state_delete_security = selinux_xfrm_state_delete,
4765 .xfrm_policy_lookup = selinux_xfrm_policy_lookup, 4774 .xfrm_policy_lookup = selinux_xfrm_policy_lookup,
4766 .xfrm_state_pol_flow_match = selinux_xfrm_state_pol_flow_match, 4775 .xfrm_state_pol_flow_match = selinux_xfrm_state_pol_flow_match,
4767 .xfrm_flow_state_match = selinux_xfrm_flow_state_match,
4768 .xfrm_decode_session = selinux_xfrm_decode_session, 4776 .xfrm_decode_session = selinux_xfrm_decode_session,
4769#endif 4777#endif
4770 4778