aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Moore <paul.moore@hp.com>2008-10-10 10:16:29 -0400
committerPaul Moore <paul.moore@hp.com>2008-10-10 10:16:29 -0400
commitaa86290089a1e57b4bdbbb4720072233f66bd5b2 (patch)
tree9ab16f4d22056297f1571bb7b2b988bff84c8a10
parentaccc609322ef5ed44cba6d2d70c741afc76385fb (diff)
selinux: Correctly handle IPv4 packets on IPv6 sockets in all cases
We did the right thing in a few cases but there were several areas where we determined a packet's address family based on the socket's address family which is not the right thing to do since we can get IPv4 packets on IPv6 sockets. This patch fixes these problems by either taking the address family directly from the packet. Signed-off-by: Paul Moore <paul.moore@hp.com> Acked-by: James Morris <jmorris@namei.org>
-rw-r--r--security/selinux/hooks.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 03fc6a81ae32..223f474bee86 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -4207,10 +4207,12 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *
4207 u32 peer_secid = SECSID_NULL; 4207 u32 peer_secid = SECSID_NULL;
4208 u16 family; 4208 u16 family;
4209 4209
4210 if (sock) 4210 if (skb && skb->protocol == htons(ETH_P_IP))
4211 family = PF_INET;
4212 else if (skb && skb->protocol == htons(ETH_P_IPV6))
4213 family = PF_INET6;
4214 else if (sock)
4211 family = sock->sk->sk_family; 4215 family = sock->sk->sk_family;
4212 else if (skb && skb->sk)
4213 family = skb->sk->sk_family;
4214 else 4216 else
4215 goto out; 4217 goto out;
4216 4218
@@ -4277,10 +4279,15 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
4277{ 4279{
4278 struct sk_security_struct *sksec = sk->sk_security; 4280 struct sk_security_struct *sksec = sk->sk_security;
4279 int err; 4281 int err;
4282 u16 family = sk->sk_family;
4280 u32 newsid; 4283 u32 newsid;
4281 u32 peersid; 4284 u32 peersid;
4282 4285
4283 err = selinux_skb_peerlbl_sid(skb, sk->sk_family, &peersid); 4286 /* handle mapped IPv4 packets arriving via IPv6 sockets */
4287 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
4288 family = PF_INET;
4289
4290 err = selinux_skb_peerlbl_sid(skb, family, &peersid);
4284 if (err) 4291 if (err)
4285 return err; 4292 return err;
4286 if (peersid == SECSID_NULL) { 4293 if (peersid == SECSID_NULL) {
@@ -4318,9 +4325,14 @@ static void selinux_inet_csk_clone(struct sock *newsk,
4318static void selinux_inet_conn_established(struct sock *sk, 4325static void selinux_inet_conn_established(struct sock *sk,
4319 struct sk_buff *skb) 4326 struct sk_buff *skb)
4320{ 4327{
4328 u16 family = sk->sk_family;
4321 struct sk_security_struct *sksec = sk->sk_security; 4329 struct sk_security_struct *sksec = sk->sk_security;
4322 4330
4323 selinux_skb_peerlbl_sid(skb, sk->sk_family, &sksec->peer_sid); 4331 /* handle mapped IPv4 packets arriving via IPv6 sockets */
4332 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
4333 family = PF_INET;
4334
4335 selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid);
4324} 4336}
4325 4337
4326static void selinux_req_classify_flow(const struct request_sock *req, 4338static void selinux_req_classify_flow(const struct request_sock *req,