From: Benjamin Poirier <bpoirier@suse.de>
To: "David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Pavel Emelyanov <xemul@parallels.com>
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH net 3/3] unix/stream: fix peeking with an offset larger than data in queue
Date: Thu, 25 Apr 2013 09:47:18 -0400 [thread overview]
Message-ID: <1366897638-21882-3-git-send-email-bpoirier@suse.de> (raw)
In-Reply-To: <1366897638-21882-1-git-send-email-bpoirier@suse.de>
Currently, peeking on a unix stream socket with an offset larger than len of
the data in the sk receive queue returns immediately with bogus data.
This patch fixes this so that the behavior is the same as peeking with no
offset on an empty queue: the caller blocks.
Signed-off-by: Benjamin Poirier <bpoirier@suse.de>
---
net/unix/af_unix.c | 25 ++++++++++++-------------
1 file changed, 12 insertions(+), 13 deletions(-)
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 2db702d..1a02af0 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1859,10 +1859,10 @@ out:
}
/*
- * Sleep until data has arrive. But check for races..
+ * Sleep until more data has arrived. But check for races..
*/
-
-static long unix_stream_data_wait(struct sock *sk, long timeo)
+static long unix_stream_data_wait(struct sock *sk, long timeo,
+ struct sk_buff *last)
{
DEFINE_WAIT(wait);
@@ -1871,7 +1871,7 @@ static long unix_stream_data_wait(struct sock *sk, long timeo)
for (;;) {
prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
- if (!skb_queue_empty(&sk->sk_receive_queue) ||
+ if (skb_peek_tail(&sk->sk_receive_queue) != last ||
sk->sk_err ||
(sk->sk_shutdown & RCV_SHUTDOWN) ||
signal_pending(current) ||
@@ -1890,8 +1890,6 @@ static long unix_stream_data_wait(struct sock *sk, long timeo)
return timeo;
}
-
-
static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t size,
int flags)
@@ -1936,14 +1934,12 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
goto out;
}
- skip = sk_peek_offset(sk, flags);
-
do {
int chunk;
- struct sk_buff *skb;
+ struct sk_buff *skb, *last;
unix_state_lock(sk);
- skb = skb_peek(&sk->sk_receive_queue);
+ last = skb = skb_peek(&sk->sk_receive_queue);
again:
if (skb == NULL) {
unix_sk(sk)->recursion_level = 0;
@@ -1966,7 +1962,7 @@ again:
break;
mutex_unlock(&u->readlock);
- timeo = unix_stream_data_wait(sk, timeo);
+ timeo = unix_stream_data_wait(sk, timeo, last);
if (signal_pending(current)
|| mutex_lock_interruptible(&u->readlock)) {
@@ -1980,10 +1976,13 @@ again:
break;
}
- if (skip >= skb->len) {
+ skip = sk_peek_offset(sk, flags);
+ while (skip >= skb->len) {
skip -= skb->len;
+ last = skb;
skb = skb_peek_next(skb, &sk->sk_receive_queue);
- goto again;
+ if (!skb)
+ goto again;
}
unix_state_unlock(sk);
--
1.7.10.4
next prev parent reply other threads:[~2013-04-25 13:47 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-04-25 13:47 [PATCH net 1/3] unix/dgram: peek beyond 0-sized skbs Benjamin Poirier
2013-04-25 13:47 ` [PATCH net 2/3] unix/dgram: fix peeking with an offset larger than data in queue Benjamin Poirier
2013-04-25 18:58 ` Eric Dumazet
2013-04-25 13:47 ` Benjamin Poirier [this message]
2013-04-25 18:48 ` [PATCH net 1/3] unix/dgram: peek beyond 0-sized skbs Eric Dumazet
2013-04-26 18:35 ` Benjamin Poirier
2013-04-26 18:35 ` [PATCH net v2 2/3] unix/dgram: fix peeking with an offset larger than data in queue Benjamin Poirier
2013-04-29 7:01 ` Cong Wang
2013-04-29 21:42 ` [PATCH v3 1/3] unix/dgram: peek beyond 0-sized skbs Benjamin Poirier
2013-04-29 21:42 ` [PATCH v3 2/3] unix/dgram: fix peeking with an offset larger than data in queue Benjamin Poirier
2013-04-30 0:49 ` Eric Dumazet
2013-04-30 4:44 ` David Miller
2013-04-29 21:42 ` [PATCH v3 3/3] unix/stream: " Benjamin Poirier
2013-04-30 0:51 ` Eric Dumazet
2013-04-30 4:44 ` David Miller
2013-04-30 0:48 ` [PATCH v3 1/3] unix/dgram: peek beyond 0-sized skbs Eric Dumazet
2013-04-30 4:44 ` David Miller
2013-04-26 18:35 ` [PATCH net v2 3/3] unix/stream: fix peeking with an offset larger than data in queue Benjamin Poirier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1366897638-21882-3-git-send-email-bpoirier@suse.de \
--to=bpoirier@suse.de \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=xemul@parallels.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).