Skip to content

Commit

Permalink
Merge branch 'inet-ping-fixes'
Browse files Browse the repository at this point in the history
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: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Oct 12, 2022
2 parents 7e777b1 + 0d24148 commit 4a4462a
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 18 deletions.
23 changes: 6 additions & 17 deletions net/ipv4/ping.c
Original file line number Diff line number Diff line change
Expand Up @@ -617,29 +617,17 @@ int ping_getfrag(void *from, char *to,
{
struct pingfakehdr *pfh = from;

if (offset == 0) {
fraglen -= sizeof(struct icmphdr);
if (fraglen < 0)
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 (!csum_and_copy_from_iter_full(to, fraglen, &pfh->wcheck,
&pfh->msg->msg_iter))
return -EFAULT;

#if IS_ENABLED(CONFIG_IPV6)
/* For IPv6, checksum each skb as we go along, as expected by
* icmpv6_push_pending_frames. For IPv4, accumulate the checksum in
* wcheck, it will be finalized in ping_v4_push_pending_frames.
*/
if (pfh->family == AF_INET6) {
skb->csum = pfh->wcheck;
skb->csum = csum_block_add(skb->csum, pfh->wcheck, odd);
skb->ip_summed = CHECKSUM_NONE;
pfh->wcheck = 0;
}
Expand Down Expand Up @@ -842,7 +830,8 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
pfh.family = AF_INET;

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)
ip_flush_pending_frames(sk);
else
Expand Down
2 changes: 1 addition & 1 deletion net/ipv6/ping.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)

lock_sock(sk);
err = ip6_append_data(sk, ping_getfrag, &pfh, len,
0, &ipc6, &fl6, rt,
sizeof(struct icmp6hdr), &ipc6, &fl6, rt,
MSG_DONTWAIT);

if (err) {
Expand Down

0 comments on commit 4a4462a

Please sign in to comment.