|
@@ -259,6 +259,9 @@ int ping_init_sock(struct sock *sk)
|
|
|
kgid_t low, high;
|
|
|
int ret = 0;
|
|
|
|
|
|
+ if (sk->sk_family == AF_INET6)
|
|
|
+ sk->sk_ipv6only = 1;
|
|
|
+
|
|
|
inet_get_ping_group_range_net(net, &low, &high);
|
|
|
if (gid_lte(low, group) && gid_lte(group, high))
|
|
|
return 0;
|
|
@@ -305,6 +308,11 @@ static int ping_check_bind_addr(struct sock *sk, struct inet_sock *isk,
|
|
|
if (addr_len < sizeof(*addr))
|
|
|
return -EINVAL;
|
|
|
|
|
|
+ if (addr->sin_family != AF_INET &&
|
|
|
+ !(addr->sin_family == AF_UNSPEC &&
|
|
|
+ addr->sin_addr.s_addr == htonl(INADDR_ANY)))
|
|
|
+ return -EAFNOSUPPORT;
|
|
|
+
|
|
|
pr_debug("ping_check_bind_addr(sk=%p,addr=%pI4,port=%d)\n",
|
|
|
sk, &addr->sin_addr.s_addr, ntohs(addr->sin_port));
|
|
|
|
|
@@ -330,7 +338,7 @@ static int ping_check_bind_addr(struct sock *sk, struct inet_sock *isk,
|
|
|
return -EINVAL;
|
|
|
|
|
|
if (addr->sin6_family != AF_INET6)
|
|
|
- return -EINVAL;
|
|
|
+ return -EAFNOSUPPORT;
|
|
|
|
|
|
pr_debug("ping_check_bind_addr(sk=%p,addr=%pI6c,port=%d)\n",
|
|
|
sk, addr->sin6_addr.s6_addr, ntohs(addr->sin6_port));
|
|
@@ -716,7 +724,7 @@ static int ping_v4_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
|
|
|
if (msg->msg_namelen < sizeof(*usin))
|
|
|
return -EINVAL;
|
|
|
if (usin->sin_family != AF_INET)
|
|
|
- return -EINVAL;
|
|
|
+ return -EAFNOSUPPORT;
|
|
|
daddr = usin->sin_addr.s_addr;
|
|
|
/* no remote port */
|
|
|
} else {
|