summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/ipv6.h2
-rw-r--r--net/ipv4/ping.c3
-rw-r--r--net/ipv6/datagram.c10
-rw-r--r--net/ipv6/ping.c2
-rw-r--r--net/ipv6/raw.c6
-rw-r--r--net/l2tp/l2tp_ip6.c3
6 files changed, 24 insertions, 2 deletions
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 78d3d5124918..4f541f11ce63 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -783,6 +783,8 @@ int compat_ipv6_getsockopt(struct sock *sk, int level, int optname,
783 char __user *optval, int __user *optlen); 783 char __user *optval, int __user *optlen);
784 784
785int ip6_datagram_connect(struct sock *sk, struct sockaddr *addr, int addr_len); 785int ip6_datagram_connect(struct sock *sk, struct sockaddr *addr, int addr_len);
786int ip6_datagram_connect_v6_only(struct sock *sk, struct sockaddr *addr,
787 int addr_len);
786 788
787int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, 789int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len,
788 int *addr_len); 790 int *addr_len);
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index 4a9e4266a0c3..2d11c094296e 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -320,6 +320,9 @@ static int ping_check_bind_addr(struct sock *sk, struct inet_sock *isk,
320 if (addr_len < sizeof(*addr)) 320 if (addr_len < sizeof(*addr))
321 return -EINVAL; 321 return -EINVAL;
322 322
323 if (addr->sin6_family != AF_INET6)
324 return -EINVAL;
325
323 pr_debug("ping_check_bind_addr(sk=%p,addr=%pI6c,port=%d)\n", 326 pr_debug("ping_check_bind_addr(sk=%p,addr=%pI6c,port=%d)\n",
324 sk, addr->sin6_addr.s6_addr, ntohs(addr->sin6_port)); 327 sk, addr->sin6_addr.s6_addr, ntohs(addr->sin6_port));
325 328
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index cd8699bd2e6b..2f5e2f154d21 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -205,6 +205,16 @@ out:
205} 205}
206EXPORT_SYMBOL_GPL(ip6_datagram_connect); 206EXPORT_SYMBOL_GPL(ip6_datagram_connect);
207 207
208int ip6_datagram_connect_v6_only(struct sock *sk, struct sockaddr *uaddr,
209 int addr_len)
210{
211 DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, uaddr);
212 if (sin6->sin6_family != AF_INET6)
213 return -EAFNOSUPPORT;
214 return ip6_datagram_connect(sk, uaddr, addr_len);
215}
216EXPORT_SYMBOL_GPL(ip6_datagram_connect_v6_only);
217
208void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, 218void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
209 __be16 port, u32 info, u8 *payload) 219 __be16 port, u32 info, u8 *payload)
210{ 220{
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c
index 94a3d04c3200..fb9beb78f00b 100644
--- a/net/ipv6/ping.c
+++ b/net/ipv6/ping.c
@@ -31,7 +31,7 @@ struct proto pingv6_prot = {
31 .owner = THIS_MODULE, 31 .owner = THIS_MODULE,
32 .init = ping_init_sock, 32 .init = ping_init_sock,
33 .close = ping_close, 33 .close = ping_close,
34 .connect = ip6_datagram_connect, 34 .connect = ip6_datagram_connect_v6_only,
35 .disconnect = udp_disconnect, 35 .disconnect = udp_disconnect,
36 .setsockopt = ipv6_setsockopt, 36 .setsockopt = ipv6_setsockopt,
37 .getsockopt = ipv6_getsockopt, 37 .getsockopt = ipv6_getsockopt,
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index b4523117aeae..1f29996e368a 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -250,6 +250,10 @@ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
250 250
251 if (addr_len < SIN6_LEN_RFC2133) 251 if (addr_len < SIN6_LEN_RFC2133)
252 return -EINVAL; 252 return -EINVAL;
253
254 if (addr->sin6_family != AF_INET6)
255 return -EINVAL;
256
253 addr_type = ipv6_addr_type(&addr->sin6_addr); 257 addr_type = ipv6_addr_type(&addr->sin6_addr);
254 258
255 /* Raw sockets are IPv6 only */ 259 /* Raw sockets are IPv6 only */
@@ -1209,7 +1213,7 @@ struct proto rawv6_prot = {
1209 .owner = THIS_MODULE, 1213 .owner = THIS_MODULE,
1210 .close = rawv6_close, 1214 .close = rawv6_close,
1211 .destroy = raw6_destroy, 1215 .destroy = raw6_destroy,
1212 .connect = ip6_datagram_connect, 1216 .connect = ip6_datagram_connect_v6_only,
1213 .disconnect = udp_disconnect, 1217 .disconnect = udp_disconnect,
1214 .ioctl = rawv6_ioctl, 1218 .ioctl = rawv6_ioctl,
1215 .init = rawv6_init_sk, 1219 .init = rawv6_init_sk,
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
index aab5f74e91e6..7704ea9502fd 100644
--- a/net/l2tp/l2tp_ip6.c
+++ b/net/l2tp/l2tp_ip6.c
@@ -371,6 +371,9 @@ static int l2tp_ip6_connect(struct sock *sk, struct sockaddr *uaddr,
371 if (addr_len < sizeof(*lsa)) 371 if (addr_len < sizeof(*lsa))
372 return -EINVAL; 372 return -EINVAL;
373 373
374 if (usin->sin6_family != AF_INET6)
375 return -EINVAL;
376
374 addr_type = ipv6_addr_type(&usin->sin6_addr); 377 addr_type = ipv6_addr_type(&usin->sin6_addr);
375 if (addr_type & IPV6_ADDR_MULTICAST) 378 if (addr_type & IPV6_ADDR_MULTICAST)
376 return -EINVAL; 379 return -EINVAL;