summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorBenjamin Poirier <bpoirier@suse.de>2013-04-29 11:42:12 +0000
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 368f9c3f9dc..99c4f525b1d 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,
skb_queue_walk(queue, skb) {
*peeked = skb->peeked;
if (flags & MSG_PEEK) {
- if (*off >= skb->len && skb->len) {
+ if (*off >= skb->len && (skb->len || *off ||
+ skb->peeked)) {
*off -= skb->len;
continue;
}