diff options
-rw-r--r-- | include/net/ipv6.h | 2 | ||||
-rw-r--r-- | net/ipv4/ping.c | 3 | ||||
-rw-r--r-- | net/ipv6/datagram.c | 10 | ||||
-rw-r--r-- | net/ipv6/ping.c | 2 | ||||
-rw-r--r-- | net/ipv6/raw.c | 6 | ||||
-rw-r--r-- | net/l2tp/l2tp_ip6.c | 3 |
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 | ||
785 | int ip6_datagram_connect(struct sock *sk, struct sockaddr *addr, int addr_len); | 785 | int ip6_datagram_connect(struct sock *sk, struct sockaddr *addr, int addr_len); |
786 | int ip6_datagram_connect_v6_only(struct sock *sk, struct sockaddr *addr, | ||
787 | int addr_len); | ||
786 | 788 | ||
787 | int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, | 789 | int 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 | } |
206 | EXPORT_SYMBOL_GPL(ip6_datagram_connect); | 206 | EXPORT_SYMBOL_GPL(ip6_datagram_connect); |
207 | 207 | ||
208 | int 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 | } | ||
216 | EXPORT_SYMBOL_GPL(ip6_datagram_connect_v6_only); | ||
217 | |||
208 | void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, | 218 | void 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; |