From mboxrd@z Thu Jan 1 00:00:00 1970 From: Eric Dumazet Subject: [PATCH] net: fix infinite loop in __skb_recv_datagram() Date: Tue, 12 Feb 2013 08:16:53 -0800 Message-ID: <1360685813.13993.12.camel@edumazet-glaptop> References: <1360628371.20362.28.camel@edumazet-glaptop> <1360638903.20362.32.camel@edumazet-glaptop> Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit Cc: netdev@vger.kernel.org, Dave Jones , Pavel Emelyanov To: Tommi Rantala , David Miller Return-path: Received: from mail-pa0-f48.google.com ([209.85.220.48]:53432 "EHLO mail-pa0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1761270Ab3BLQQ7 (ORCPT ); Tue, 12 Feb 2013 11:16:59 -0500 Received: by mail-pa0-f48.google.com with SMTP id hz10so168343pad.7 for ; Tue, 12 Feb 2013 08:16:58 -0800 (PST) In-Reply-To: Sender: netdev-owner@vger.kernel.org List-ID: From: Eric Dumazet Tommi was fuzzing with trinity and reported the following problem : commit 3f518bf745 (datagram: Add offset argument to __skb_recv_datagram) missed that a raw socket receive queue can contain skbs with no payload. We can loop in __skb_recv_datagram() with MSG_PEEK mode, because wait_for_packet() is not prepared to skip these skbs. [ 83.541011] INFO: rcu_sched detected stalls on CPUs/tasks: {} (detected by 0, t=26002 jiffies, g=27673, c=27672, q=75) [ 83.541011] INFO: Stall ended before state dump start [ 108.067010] BUG: soft lockup - CPU#0 stuck for 22s! [trinity-child31:2847] ... [ 108.067010] Call Trace: [ 108.067010] [] __skb_recv_datagram+0x1a3/0x3b0 [ 108.067010] [] skb_recv_datagram+0x2d/0x30 [ 108.067010] [] rawv6_recvmsg+0xad/0x240 [ 108.067010] [] sock_common_recvmsg+0x34/0x50 [ 108.067010] [] sock_recvmsg+0xbc/0xf0 [ 108.067010] [] sys_recvfrom+0xde/0x150 [ 108.067010] [] system_call_fastpath+0x16/0x1b Reported-by: Tommi Rantala Tested-by: Tommi Rantala Signed-off-by: Eric Dumazet Cc: Pavel Emelyanov --- net/core/datagram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/datagram.c b/net/core/datagram.c index 0337e2b..368f9c3 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -187,7 +187,7 @@ 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) { + if (*off >= skb->len && skb->len) { *off -= skb->len; continue; }