|
@@ -1271,6 +1271,7 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock,
|
|
int peeked, off = 0;
|
|
int peeked, off = 0;
|
|
int err;
|
|
int err;
|
|
int is_udplite = IS_UDPLITE(sk);
|
|
int is_udplite = IS_UDPLITE(sk);
|
|
|
|
+ bool checksum_valid = false;
|
|
bool slow;
|
|
bool slow;
|
|
|
|
|
|
if (flags & MSG_ERRQUEUE)
|
|
if (flags & MSG_ERRQUEUE)
|
|
@@ -1296,11 +1297,12 @@ try_again:
|
|
*/
|
|
*/
|
|
|
|
|
|
if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) {
|
|
if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) {
|
|
- if (udp_lib_checksum_complete(skb))
|
|
|
|
|
|
+ checksum_valid = !udp_lib_checksum_complete(skb);
|
|
|
|
+ if (!checksum_valid)
|
|
goto csum_copy_err;
|
|
goto csum_copy_err;
|
|
}
|
|
}
|
|
|
|
|
|
- if (skb_csum_unnecessary(skb))
|
|
|
|
|
|
+ if (checksum_valid || skb_csum_unnecessary(skb))
|
|
err = skb_copy_datagram_msg(skb, sizeof(struct udphdr),
|
|
err = skb_copy_datagram_msg(skb, sizeof(struct udphdr),
|
|
msg, copied);
|
|
msg, copied);
|
|
else {
|
|
else {
|