udp: do not expect udp headers in recv cmsg IP_CMSG_CHECKSUM
On udp sockets, recv cmsg IP_CMSG_CHECKSUM returns a checksum over the packet payload. Since commite6afc8ace6
pulled the headers, taking skb->data as the start of transport header is incorrect. Use the transport header pointer. Also, when peeking at an offset from the start of the packet, only return a checksum from the start of the peeked data. Note that the cmsg does not subtract a tail checkum when reading truncated data. Fixes:e6afc8ace6
("udp: remove headers from UDP packets before queueing") Signed-off-by: Willem de Bruijn <willemb@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
9f9a45beaa
commit
31c2e4926f
|
@ -106,7 +106,8 @@ static void ip_cmsg_recv_checksum(struct msghdr *msg, struct sk_buff *skb,
|
|||
return;
|
||||
|
||||
if (offset != 0)
|
||||
csum = csum_sub(csum, csum_partial(skb->data, offset, 0));
|
||||
csum = csum_sub(csum, csum_partial(skb_transport_header(skb),
|
||||
offset, 0));
|
||||
|
||||
put_cmsg(msg, SOL_IP, IP_CHECKSUM, sizeof(__wsum), &csum);
|
||||
}
|
||||
|
|
|
@ -1375,7 +1375,7 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock,
|
|||
*addr_len = sizeof(*sin);
|
||||
}
|
||||
if (inet->cmsg_flags)
|
||||
ip_cmsg_recv_offset(msg, skb, sizeof(struct udphdr));
|
||||
ip_cmsg_recv_offset(msg, skb, sizeof(struct udphdr) + off);
|
||||
|
||||
err = copied;
|
||||
if (flags & MSG_TRUNC)
|
||||
|
|
Loading…
Reference in New Issue