diff options
Diffstat (limited to 'net/ipv6/udp.c')
-rw-r--r-- | net/ipv6/udp.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 846f4757eb8d..8c2541915183 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -340,7 +340,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
340 | struct ipv6_pinfo *np = inet6_sk(sk); | 340 | struct ipv6_pinfo *np = inet6_sk(sk); |
341 | struct inet_sock *inet = inet_sk(sk); | 341 | struct inet_sock *inet = inet_sk(sk); |
342 | struct sk_buff *skb; | 342 | struct sk_buff *skb; |
343 | unsigned int ulen; | 343 | unsigned int ulen, copied; |
344 | int peeked; | 344 | int peeked; |
345 | int err; | 345 | int err; |
346 | int is_udplite = IS_UDPLITE(sk); | 346 | int is_udplite = IS_UDPLITE(sk); |
@@ -363,9 +363,10 @@ try_again: | |||
363 | goto out; | 363 | goto out; |
364 | 364 | ||
365 | ulen = skb->len - sizeof(struct udphdr); | 365 | ulen = skb->len - sizeof(struct udphdr); |
366 | if (len > ulen) | 366 | copied = len; |
367 | len = ulen; | 367 | if (copied > ulen) |
368 | else if (len < ulen) | 368 | copied = ulen; |
369 | else if (copied < ulen) | ||
369 | msg->msg_flags |= MSG_TRUNC; | 370 | msg->msg_flags |= MSG_TRUNC; |
370 | 371 | ||
371 | is_udp4 = (skb->protocol == htons(ETH_P_IP)); | 372 | is_udp4 = (skb->protocol == htons(ETH_P_IP)); |
@@ -376,14 +377,14 @@ try_again: | |||
376 | * coverage checksum (UDP-Lite), do it before the copy. | 377 | * coverage checksum (UDP-Lite), do it before the copy. |
377 | */ | 378 | */ |
378 | 379 | ||
379 | if (len < ulen || UDP_SKB_CB(skb)->partial_cov) { | 380 | if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) { |
380 | if (udp_lib_checksum_complete(skb)) | 381 | if (udp_lib_checksum_complete(skb)) |
381 | goto csum_copy_err; | 382 | goto csum_copy_err; |
382 | } | 383 | } |
383 | 384 | ||
384 | if (skb_csum_unnecessary(skb)) | 385 | if (skb_csum_unnecessary(skb)) |
385 | err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), | 386 | err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), |
386 | msg->msg_iov,len); | 387 | msg->msg_iov, copied ); |
387 | else { | 388 | else { |
388 | err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov); | 389 | err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov); |
389 | if (err == -EINVAL) | 390 | if (err == -EINVAL) |
@@ -432,7 +433,7 @@ try_again: | |||
432 | datagram_recv_ctl(sk, msg, skb); | 433 | datagram_recv_ctl(sk, msg, skb); |
433 | } | 434 | } |
434 | 435 | ||
435 | err = len; | 436 | err = copied; |
436 | if (flags & MSG_TRUNC) | 437 | if (flags & MSG_TRUNC) |
437 | err = ulen; | 438 | err = ulen; |
438 | 439 | ||