aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/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/ipv4/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/ipv4/udp.c')
-rw-r--r--net/ipv4/udp.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index ab0966df1e2a..5a65eeac1d29 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1164,7 +1164,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
1164 struct inet_sock *inet = inet_sk(sk); 1164 struct inet_sock *inet = inet_sk(sk);
1165 struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name; 1165 struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
1166 struct sk_buff *skb; 1166 struct sk_buff *skb;
1167 unsigned int ulen; 1167 unsigned int ulen, copied;
1168 int peeked; 1168 int peeked;
1169 int err; 1169 int err;
1170 int is_udplite = IS_UDPLITE(sk); 1170 int is_udplite = IS_UDPLITE(sk);
@@ -1186,9 +1186,10 @@ try_again:
1186 goto out; 1186 goto out;
1187 1187
1188 ulen = skb->len - sizeof(struct udphdr); 1188 ulen = skb->len - sizeof(struct udphdr);
1189 if (len > ulen) 1189 copied = len;
1190 len = ulen; 1190 if (copied > ulen)
1191 else if (len < ulen) 1191 copied = ulen;
1192 else if (copied < ulen)
1192 msg->msg_flags |= MSG_TRUNC; 1193 msg->msg_flags |= MSG_TRUNC;
1193 1194
1194 /* 1195 /*
@@ -1197,14 +1198,14 @@ try_again:
1197 * coverage checksum (UDP-Lite), do it before the copy. 1198 * coverage checksum (UDP-Lite), do it before the copy.
1198 */ 1199 */
1199 1200
1200 if (len < ulen || UDP_SKB_CB(skb)->partial_cov) { 1201 if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) {
1201 if (udp_lib_checksum_complete(skb)) 1202 if (udp_lib_checksum_complete(skb))
1202 goto csum_copy_err; 1203 goto csum_copy_err;
1203 } 1204 }
1204 1205
1205 if (skb_csum_unnecessary(skb)) 1206 if (skb_csum_unnecessary(skb))
1206 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), 1207 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
1207 msg->msg_iov, len); 1208 msg->msg_iov, copied);
1208 else { 1209 else {
1209 err = skb_copy_and_csum_datagram_iovec(skb, 1210 err = skb_copy_and_csum_datagram_iovec(skb,
1210 sizeof(struct udphdr), 1211 sizeof(struct udphdr),
@@ -1233,7 +1234,7 @@ try_again:
1233 if (inet->cmsg_flags) 1234 if (inet->cmsg_flags)
1234 ip_cmsg_recv(msg, skb); 1235 ip_cmsg_recv(msg, skb);
1235 1236
1236 err = len; 1237 err = copied;
1237 if (flags & MSG_TRUNC) 1238 if (flags & MSG_TRUNC)
1238 err = ulen; 1239 err = ulen;
1239 1240