From: Rao Shoaib <rao.shoaib@oracle.com>
To: Kuniyuki Iwashima <kuniyu@amazon.com>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>
Cc: Kuniyuki Iwashima <kuni1840@gmail.com>, netdev@vger.kernel.org
Subject: Re: [PATCH v2 net 2/2] af_unix: Don't peek OOB data without MSG_OOB.
Date: Tue, 16 Apr 2024 13:11:09 -0700 [thread overview]
Message-ID: <3e4ba1b4-ded8-4dd9-9112-a4fb354e1f55@oracle.com> (raw)
In-Reply-To: <20240410171016.7621-3-kuniyu@amazon.com>
[-- Attachment #1: Type: text/plain, Size: 2624 bytes --]
The proposed fix is not the correct fix as among other things it does
not allow going pass the OOB if data is present. TCP allows that.
I have attached a patch that fixes this issue and other issues that I
encountered in my testing. I compared TCP.
Shoaib
On 4/10/24 10:10, Kuniyuki Iwashima wrote:
> Currently, we can read OOB data without MSG_OOB by using MSG_PEEK
> when OOB data is sitting on the front row, which is apparently
> wrong.
>
> >>> from socket import *
> >>> c1, c2 = socketpair(AF_UNIX, SOCK_STREAM)
> >>> c1.send(b'a', MSG_OOB)
> 1
> >>> c2.recv(1, MSG_PEEK | MSG_DONTWAIT)
> b'a'
>
> If manage_oob() is called when no data has been copied, we only
> check if the socket enables SO_OOBINLINE or MSG_PEEK is not used.
> Otherwise, the skb is returned as is.
>
> However, here we should return NULL if MSG_PEEK is set and no data
> has been copied.
>
> Also, in such a case, we should not jump to the redo label because
> we will be caught in the loop and hog the CPU until normal data
> comes in.
>
> Then, we need to handle skb == NULL case with the if-clause below
> the manage_oob() block.
>
> With this patch:
>
> >>> from socket import *
> >>> c1, c2 = socketpair(AF_UNIX, SOCK_STREAM)
> >>> c1.send(b'a', MSG_OOB)
> 1
> >>> c2.recv(1, MSG_PEEK | MSG_DONTWAIT)
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> BlockingIOError: [Errno 11] Resource temporarily unavailable
>
> Fixes: 314001f0bf92 ("af_unix: Add OOB support")
> Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
> ---
> net/unix/af_unix.c | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
> index f297320438bf..9a6ad5974dff 100644
> --- a/net/unix/af_unix.c
> +++ b/net/unix/af_unix.c
> @@ -2663,7 +2663,9 @@ static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk,
> WRITE_ONCE(u->oob_skb, NULL);
> consume_skb(skb);
> }
> - } else if (!(flags & MSG_PEEK)) {
> + } else if (flags & MSG_PEEK) {
> + skb = NULL;
> + } else {
> skb_unlink(skb, &sk->sk_receive_queue);
> WRITE_ONCE(u->oob_skb, NULL);
> if (!WARN_ON_ONCE(skb_unref(skb)))
> @@ -2745,11 +2747,9 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state,
> #if IS_ENABLED(CONFIG_AF_UNIX_OOB)
> if (skb) {
> skb = manage_oob(skb, sk, flags, copied);
> - if (!skb) {
> + if (!skb && copied) {
> unix_state_unlock(sk);
> - if (copied)
> - break;
> - goto redo;
> + break;
> }
> }
> #endif
[-- Attachment #2: 0001-AF_UNIX-Fix-handling-of-OOB-Data.patch --]
[-- Type: text/x-patch, Size: 2772 bytes --]
From bf541423b785ae14ee2c7015d96dba6ac368358c Mon Sep 17 00:00:00 2001
From: Rao Shoaib <Rao.Shoaib@oracle.com>
Date: Tue, 16 Apr 2024 12:39:54 -0700
Subject: [PATCH] AF_UNIX: Fix handling of OOB Data
This patch fixes corner cases in reading when there is a
pending OOB and MSG_PEEK flag is set.
Since there is no standard for handling MSG_OOB and MSG_PEEK,
behavior of TCP is used as a reference.
First byte in the read queue is OOB byte
First byte in the read queue is OOB byte followed by normal data
New OOB arrives before the previous one was consumed
Signed-off-by: Rao Shoaib <Rao.Shoaib@oracle.com>
---
net/unix/af_unix.c | 32 ++++++++++++++++++++------------
1 file changed, 20 insertions(+), 12 deletions(-)
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index d032eb5fa6df..50cae03a1f98 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -2217,8 +2217,13 @@ static int queue_oob(struct socket *sock, struct msghdr *msg, struct sock *other
maybe_add_creds(skb, sock, other);
skb_get(skb);
- if (ousk->oob_skb)
- consume_skb(ousk->oob_skb);
+ if (ousk->oob_skb) {
+ skb_unref(ousk->oob_skb);
+ if (!sock_flag(other, SOCK_URGINLINE)) {
+ skb_unlink(ousk->oob_skb, &other->sk_receive_queue);
+ consume_skb(ousk->oob_skb);
+ }
+ }
WRITE_ONCE(ousk->oob_skb, skb);
@@ -2658,17 +2663,20 @@ static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk,
if (skb == u->oob_skb) {
if (copied) {
skb = NULL;
- } else if (sock_flag(sk, SOCK_URGINLINE)) {
- if (!(flags & MSG_PEEK)) {
+ } else if (!(flags & MSG_PEEK)) {
+ if (sock_flag(sk, SOCK_URGINLINE)) {
WRITE_ONCE(u->oob_skb, NULL);
consume_skb(skb);
+ } else {
+ skb_unlink(skb, &sk->sk_receive_queue);
+ WRITE_ONCE(u->oob_skb, NULL);
+ if (!WARN_ON_ONCE(skb_unref(skb)))
+ kfree_skb(skb);
+ skb = skb_peek(&sk->sk_receive_queue);
}
- } else if (!(flags & MSG_PEEK)) {
- skb_unlink(skb, &sk->sk_receive_queue);
- WRITE_ONCE(u->oob_skb, NULL);
- if (!WARN_ON_ONCE(skb_unref(skb)))
- kfree_skb(skb);
- skb = skb_peek(&sk->sk_receive_queue);
+ } else {
+ if (!sock_flag(sk, SOCK_URGINLINE))
+ skb = skb_peek_next(skb, &sk->sk_receive_queue);
}
}
}
@@ -2741,18 +2749,18 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state,
last = skb = skb_peek(&sk->sk_receive_queue);
last_len = last ? last->len : 0;
+again:
#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
if (skb) {
skb = manage_oob(skb, sk, flags, copied);
if (!skb) {
unix_state_unlock(sk);
- if (copied)
+ if (copied || (flags & MSG_PEEK))
break;
goto redo;
}
}
#endif
-again:
if (skb == NULL) {
if (copied >= target)
goto unlock;
--
2.39.3
next prev parent reply other threads:[~2024-04-16 20:11 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-10 17:10 [PATCH v2 net 0/2] af_unix: Fix MSG_OOB bugs with MSG_PEEK Kuniyuki Iwashima
2024-04-10 17:10 ` [PATCH v2 net 1/2] af_unix: Call manage_oob() for every skb in unix_stream_read_generic() Kuniyuki Iwashima
2024-04-15 2:26 ` Rao Shoaib
2024-04-10 17:10 ` [PATCH v2 net 2/2] af_unix: Don't peek OOB data without MSG_OOB Kuniyuki Iwashima
2024-04-16 20:11 ` Rao Shoaib [this message]
2024-04-16 20:51 ` Kuniyuki Iwashima
2024-04-16 21:34 ` Rao Shoaib
2024-04-16 21:47 ` Kuniyuki Iwashima
2024-04-16 22:01 ` Rao Shoaib
2024-04-16 22:10 ` Kuniyuki Iwashima
2024-04-17 4:37 ` Rao Shoaib
2024-04-13 2:10 ` [PATCH v2 net 0/2] af_unix: Fix MSG_OOB bugs with MSG_PEEK patchwork-bot+netdevbpf
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=3e4ba1b4-ded8-4dd9-9112-a4fb354e1f55@oracle.com \
--to=rao.shoaib@oracle.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=kuba@kernel.org \
--cc=kuni1840@gmail.com \
--cc=kuniyu@amazon.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.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).