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

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
Loading
Loading
Loading
Loading
+6 −17
Original line number Diff line number Diff line
@@ -617,21 +617,9 @@ 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 IS_ENABLED(CONFIG_IPV6)
	/* For IPv6, checksum each skb as we go along, as expected by
@@ -639,7 +627,7 @@ int ping_getfrag(void *from, char *to,
	 * 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;
	}
@@ -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
+1 −1
Original line number Diff line number Diff line
@@ -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) {