Commit 4a4462a0 authored by David S. Miller's avatar David S. Miller

Merge branch 'inet-ping-fixes'

Eric Dumazet says:

====================
inet: ping: give ping some care

First patch fixes an ipv6 ping bug that has been there forever,
for large sizes.

Second patch fixes a recent and elusive bug, that can potentially
crash the host. This is what I mentioned privately to Paolo and
Jakub at LPC in Dublin.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 7e777b1b 0d24148b
...@@ -617,21 +617,9 @@ int ping_getfrag(void *from, char *to, ...@@ -617,21 +617,9 @@ int ping_getfrag(void *from, char *to,
{ {
struct pingfakehdr *pfh = from; struct pingfakehdr *pfh = from;
if (offset == 0) { if (!csum_and_copy_from_iter_full(to, fraglen, &pfh->wcheck,
fraglen -= sizeof(struct icmphdr); &pfh->msg->msg_iter))
if (fraglen < 0) return -EFAULT;
BUG();
if (!csum_and_copy_from_iter_full(to + sizeof(struct icmphdr),
fraglen, &pfh->wcheck,
&pfh->msg->msg_iter))
return -EFAULT;
} else if (offset < sizeof(struct icmphdr)) {
BUG();
} else {
if (!csum_and_copy_from_iter_full(to, fraglen, &pfh->wcheck,
&pfh->msg->msg_iter))
return -EFAULT;
}
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
/* For IPv6, checksum each skb as we go along, as expected by /* For IPv6, checksum each skb as we go along, as expected by
...@@ -639,7 +627,7 @@ int ping_getfrag(void *from, char *to, ...@@ -639,7 +627,7 @@ int ping_getfrag(void *from, char *to,
* wcheck, it will be finalized in ping_v4_push_pending_frames. * wcheck, it will be finalized in ping_v4_push_pending_frames.
*/ */
if (pfh->family == AF_INET6) { if (pfh->family == AF_INET6) {
skb->csum = pfh->wcheck; skb->csum = csum_block_add(skb->csum, pfh->wcheck, odd);
skb->ip_summed = CHECKSUM_NONE; skb->ip_summed = CHECKSUM_NONE;
pfh->wcheck = 0; pfh->wcheck = 0;
} }
...@@ -842,7 +830,8 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -842,7 +830,8 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
pfh.family = AF_INET; pfh.family = AF_INET;
err = ip_append_data(sk, &fl4, ping_getfrag, &pfh, len, err = ip_append_data(sk, &fl4, ping_getfrag, &pfh, len,
0, &ipc, &rt, msg->msg_flags); sizeof(struct icmphdr), &ipc, &rt,
msg->msg_flags);
if (err) if (err)
ip_flush_pending_frames(sk); ip_flush_pending_frames(sk);
else else
......
...@@ -179,7 +179,7 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -179,7 +179,7 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
lock_sock(sk); lock_sock(sk);
err = ip6_append_data(sk, ping_getfrag, &pfh, len, err = ip6_append_data(sk, ping_getfrag, &pfh, len,
0, &ipc6, &fl6, rt, sizeof(struct icmp6hdr), &ipc6, &fl6, rt,
MSG_DONTWAIT); MSG_DONTWAIT);
if (err) { if (err) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment