* [PATCH v2] net: ping: Return EAFNOSUPPORT when appropriate.
@ 2015-03-03 14:16 Lorenzo Colitti
2015-03-04 20:47 ` David Miller
0 siblings, 1 reply; 3+ messages in thread
From: Lorenzo Colitti @ 2015-03-03 14:16 UTC (permalink / raw)
To: netdev; +Cc: hannes, davem, Lorenzo Colitti
1. For an IPv4 ping socket, ping_check_bind_addr does not check
the family of the socket address that's passed in. Instead,
make it behave like inet_bind, which enforces either that the
address family is AF_INET, or that the family is AF_UNSPEC and
the address is 0.0.0.0.
2. For an IPv6 ping socket, ping_check_bind_addr returns EINVAL
if the socket family is not AF_INET6. Return EAFNOSUPPORT
instead, for consistency with inet6_bind.
3. Make ping_v4_sendmsg and ping_v6_sendmsg return EAFNOSUPPORT
instead of EINVAL if an incorrect socket address structure is
passed in.
4. Make IPv6 ping sockets be IPv6-only. The code does not support
IPv4, and it cannot easily be made to support IPv4 because
the protocol numbers for ICMP and ICMPv6 are different. This
makes connect(::ffff:192.0.2.1) fail with EAFNOSUPPORT instead
of making the socket unusable.
Among other things, this fixes an oops that can be triggered by:
int s = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
struct sockaddr_in6 sin6 = {
.sin6_family = AF_INET6,
.sin6_addr = in6addr_any,
};
bind(s, (struct sockaddr *) &sin6, sizeof(sin6));
Change-Id: If06ca86d9f1e4593c0d6df174caca3487c57a241
Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
---
net/ipv4/ping.c | 12 ++++++++++--
net/ipv6/ping.c | 5 +++--
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index 3648e7f..fd88f86 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -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));
@@ -715,7 +723,7 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
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 {
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c
index fee25c0..263a516 100644
--- a/net/ipv6/ping.c
+++ b/net/ipv6/ping.c
@@ -101,9 +101,10 @@ int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
if (msg->msg_name) {
DECLARE_SOCKADDR(struct sockaddr_in6 *, u, msg->msg_name);
- if (msg->msg_namelen < sizeof(struct sockaddr_in6) ||
- u->sin6_family != AF_INET6) {
+ if (msg->msg_namelen < sizeof(*u))
return -EINVAL;
+ if (u->sin6_family != AF_INET6) {
+ return -EAFNOSUPPORT;
}
if (sk->sk_bound_dev_if &&
sk->sk_bound_dev_if != u->sin6_scope_id) {
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v2] net: ping: Return EAFNOSUPPORT when appropriate.
2015-03-03 14:16 [PATCH v2] net: ping: Return EAFNOSUPPORT when appropriate Lorenzo Colitti
@ 2015-03-04 20:47 ` David Miller
0 siblings, 0 replies; 3+ messages in thread
From: David Miller @ 2015-03-04 20:47 UTC (permalink / raw)
To: lorenzo; +Cc: netdev, hannes
From: Lorenzo Colitti <lorenzo@google.com>
Date: Tue, 3 Mar 2015 23:16:16 +0900
> 1. For an IPv4 ping socket, ping_check_bind_addr does not check
> the family of the socket address that's passed in. Instead,
> make it behave like inet_bind, which enforces either that the
> address family is AF_INET, or that the family is AF_UNSPEC and
> the address is 0.0.0.0.
> 2. For an IPv6 ping socket, ping_check_bind_addr returns EINVAL
> if the socket family is not AF_INET6. Return EAFNOSUPPORT
> instead, for consistency with inet6_bind.
> 3. Make ping_v4_sendmsg and ping_v6_sendmsg return EAFNOSUPPORT
> instead of EINVAL if an incorrect socket address structure is
> passed in.
> 4. Make IPv6 ping sockets be IPv6-only. The code does not support
> IPv4, and it cannot easily be made to support IPv4 because
> the protocol numbers for ICMP and ICMPv6 are different. This
> makes connect(::ffff:192.0.2.1) fail with EAFNOSUPPORT instead
> of making the socket unusable.
>
> Among other things, this fixes an oops that can be triggered by:
>
> int s = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
> struct sockaddr_in6 sin6 = {
> .sin6_family = AF_INET6,
> .sin6_addr = in6addr_any,
> };
> bind(s, (struct sockaddr *) &sin6, sizeof(sin6));
>
> Change-Id: If06ca86d9f1e4593c0d6df174caca3487c57a241
> Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
Applied and queued up for -stable, thanks.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v2] net: ping: Return EAFNOSUPPORT when appropriate.
[not found] <1425387387-22874-1-git-send-email-lorenzo@google.com>
@ 2015-03-04 8:58 ` Erik Kline
0 siblings, 0 replies; 3+ messages in thread
From: Erik Kline @ 2015-03-04 8:58 UTC (permalink / raw)
To: Lorenzo Colitti; +Cc: netdev, Hannes Frederic Sowa, David Miller
> @@ -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;
> +
Aside: I would be all in favor of deprecating this legacy "bind to \0
and gee whiz it just works (for IPv4)" kind of behaviour. But
anyway...
Acked-by: Erik Kline <ek@google.com>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2015-03-04 20:47 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-03 14:16 [PATCH v2] net: ping: Return EAFNOSUPPORT when appropriate Lorenzo Colitti
2015-03-04 20:47 ` David Miller
[not found] <1425387387-22874-1-git-send-email-lorenzo@google.com>
2015-03-04 8:58 ` Erik Kline
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.