aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorBenjamin Poirier <bpoirier@suse.de>2013-04-29 07:42:12 -0400
committerDavid S. Miller <davem@davemloft.net>2013-04-30 00:43:54 -0400
commitadd05ad4e9f5c4efee9b98535db5efa32b0d0492 (patch)
tree02e1a52c30f67fa5951ebf38944eff6351672149 /net
parente5195c1f31f399289347e043d6abf3ffa80f0005 (diff)
unix/dgram: peek beyond 0-sized skbs
"77c1090 net: fix infinite loop in __skb_recv_datagram()" (v3.8) introduced a regression: After that commit, recv can no longer peek beyond a 0-sized skb in the queue. __skb_recv_datagram() instead stops at the first skb with len == 0 and results in the system call failing with -EFAULT via skb_copy_datagram_iovec(). When peeking at an offset with 0-sized skb(s), each one of those is received only once, in sequence. The offset starts moving forward again after receiving datagrams with len > 0. Signed-off-by: Benjamin Poirier <bpoirier@suse.de> Acked-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/core/datagram.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/net/core/datagram.c b/net/core/datagram.c
index 368f9c3f9dc6..99c4f525b1d9 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -187,7 +187,8 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags,
187 skb_queue_walk(queue, skb) { 187 skb_queue_walk(queue, skb) {
188 *peeked = skb->peeked; 188 *peeked = skb->peeked;
189 if (flags & MSG_PEEK) { 189 if (flags & MSG_PEEK) {
190 if (*off >= skb->len && skb->len) { 190 if (*off >= skb->len && (skb->len || *off ||
191 skb->peeked)) {
191 *off -= skb->len; 192 *off -= skb->len;
192 continue; 193 continue;
193 } 194 }