aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/udp.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-12-01 14:12:55 -0500
committerDavid S. Miller <davem@davemloft.net>2011-12-01 14:12:55 -0500
commit59c2cdae2791c0b2ee13d148edc6b771e7e7953f (patch)
tree1e1a9d09a881a0283d991e91f39a36d6de045d54 /net/ipv6/udp.c
parentb03b6dd58cef7d15b7c46a6729b83dd535ef08ab (diff)
Revert "udp: remove redundant variable"
This reverts commit 81d54ec8479a2c695760da81f05b5a9fb2dbe40a. If we take the "try_again" goto, due to a checksum error, the 'len' has already been truncated. So we won't compute the same values as the original code did. Reported-by: paul bilke <fsmail@conspiracy.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/udp.c')
-rw-r--r--net/ipv6/udp.c15
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