diff mbox series

[net-next] packet: allow MSG_NOSIGNAL in recvmsg

Message ID 20230224071745.20717-1-equinox@diac24.net (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series [net-next] packet: allow MSG_NOSIGNAL in recvmsg | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for net-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Single patches do not need cover letters
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 2 this patch: 2
netdev/cc_maintainers warning 2 maintainers not CCed: pabeni@redhat.com kuba@kernel.org
netdev/build_clang success Errors and warnings before: 0 this patch: 0
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 2 this patch: 2
netdev/checkpatch warning CHECK: spaces preferred around that '|' (ctx:VxV) WARNING: line length of 97 exceeds 80 columns
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

David Lamparter Feb. 24, 2023, 7:17 a.m. UTC
packet_recvmsg() whitelists a bunch of MSG_* flags, which notably does
not include MSG_NOSIGNAL.  Unfortunately, io_uring always sets
MSG_NOSIGNAL, meaning AF_PACKET sockets can't be used in io_uring
recvmsg().

As AF_PACKET sockets never generate SIGPIPE to begin with, MSG_NOSIGNAL
is a no-op and can simply be ignored.

Signed-off-by: David Lamparter <equinox@diac24.net>
Cc: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
---
 net/packet/af_packet.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Eric Dumazet Feb. 24, 2023, 10:26 a.m. UTC | #1
On Fri, Feb 24, 2023 at 8:18 AM David Lamparter <equinox@diac24.net> wrote:
>
> packet_recvmsg() whitelists a bunch of MSG_* flags, which notably does
> not include MSG_NOSIGNAL.  Unfortunately, io_uring always sets
> MSG_NOSIGNAL, meaning AF_PACKET sockets can't be used in io_uring
> recvmsg().
>
> As AF_PACKET sockets never generate SIGPIPE to begin with, MSG_NOSIGNAL
> is a no-op and can simply be ignored.
>
> Signed-off-by: David Lamparter <equinox@diac24.net>
> Cc: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
> ---
>  net/packet/af_packet.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>

This is odd... I think MSG_NOSIGNAL flag has a meaning for sendmsg()
(or write sides in general)

EPIPE is not supposed to be generated at the receiving side ?

So I would rather make io_uring slightly faster :


diff --git a/io_uring/net.c b/io_uring/net.c
index cbd4b725f58c98e5bc5bf88d5707db5c8302e071..b7f190ca528e6e259eb2b072d7a16aaba98848cb
100644
--- a/io_uring/net.c
+++ b/io_uring/net.c
@@ -567,7 +567,7 @@ int io_recvmsg_prep(struct io_kiocb *req, const
struct io_uring_sqe *sqe)
        sr->flags = READ_ONCE(sqe->ioprio);
        if (sr->flags & ~(RECVMSG_FLAGS))
                return -EINVAL;
-       sr->msg_flags = READ_ONCE(sqe->msg_flags) | MSG_NOSIGNAL;
+       sr->msg_flags = READ_ONCE(sqe->msg_flags);
        if (sr->msg_flags & MSG_DONTWAIT)
                req->flags |= REQ_F_NOWAIT;
        if (sr->msg_flags & MSG_ERRQUEUE)
David Lamparter Feb. 24, 2023, 12:01 p.m. UTC | #2
On Fri, Feb 24, 2023 at 11:26:27AM +0100, Eric Dumazet wrote:
> On Fri, Feb 24, 2023 at 8:18 AM David Lamparter <equinox@diac24.net> wrote:
[...]
> > packet_recvmsg() whitelists a bunch of MSG_* flags, which notably does
> > not include MSG_NOSIGNAL.  Unfortunately, io_uring always sets
> > MSG_NOSIGNAL, meaning AF_PACKET sockets can't be used in io_uring
> > recvmsg().
> 
> This is odd... I think MSG_NOSIGNAL flag has a meaning for sendmsg()
> (or write sides in general)
> 
> EPIPE is not supposed to be generated at the receiving side ?

I would agree, but then again the behavior is inconsistent between
socket types.  (AF_INET6, SOCK_RAW, ...) works fine with
io_uring/MSG_NOSIGNAL, meanwhile setting MSG_NOSIGNAL on (AF_PACKET,
SOCK_RAW, ...) gives EINVAL.

Just to get consistency, MSG_NOSIGNAL might be worth ignoring in
AF_PACKET recvmsg?  Independent of dropping it from io_uring...

> So I would rather make io_uring slightly faster :
[...]
> -       sr->msg_flags = READ_ONCE(sqe->msg_flags) | MSG_NOSIGNAL;
> +       sr->msg_flags = READ_ONCE(sqe->msg_flags);
Eric Dumazet Feb. 24, 2023, 1:01 p.m. UTC | #3
On Fri, Feb 24, 2023 at 1:02 PM David Lamparter <equinox@diac24.net> wrote:
>
> On Fri, Feb 24, 2023 at 11:26:27AM +0100, Eric Dumazet wrote:
> > On Fri, Feb 24, 2023 at 8:18 AM David Lamparter <equinox@diac24.net> wrote:
> [...]
> > > packet_recvmsg() whitelists a bunch of MSG_* flags, which notably does
> > > not include MSG_NOSIGNAL.  Unfortunately, io_uring always sets
> > > MSG_NOSIGNAL, meaning AF_PACKET sockets can't be used in io_uring
> > > recvmsg().
> >
> > This is odd... I think MSG_NOSIGNAL flag has a meaning for sendmsg()
> > (or write sides in general)
> >
> > EPIPE is not supposed to be generated at the receiving side ?
>
> I would agree, but then again the behavior is inconsistent between
> socket types.  (AF_INET6, SOCK_RAW, ...) works fine with
> io_uring/MSG_NOSIGNAL, meanwhile setting MSG_NOSIGNAL on (AF_PACKET,
> SOCK_RAW, ...) gives EINVAL.
>
> Just to get consistency, MSG_NOSIGNAL might be worth ignoring in
> AF_PACKET recvmsg?  Independent of dropping it from io_uring...
>

Probably because rawv6_recvmsg() never bothered to reject unknown flags.
(Maybe the reason for that was that RAW sockets were privileged ones
back in linux-2.6)
It is too late to add a check there, it might break some applications
mistakenly adding MSG_NOSIGNAL (or any currently ignored bits)

Consistency would be to make sure no recvmsg() handler pretends
MSG_NOSIGNAL has a meaning.

Your patch would prevent us using this bit for a future purpose in af_packet.


> > So I would rather make io_uring slightly faster :
> [...]
> > -       sr->msg_flags = READ_ONCE(sqe->msg_flags) | MSG_NOSIGNAL;
> > +       sr->msg_flags = READ_ONCE(sqe->msg_flags);
Jens Axboe Feb. 24, 2023, 2:32 p.m. UTC | #4
On 2/24/23 3:26 AM, Eric Dumazet wrote:
> On Fri, Feb 24, 2023 at 8:18 AM David Lamparter <equinox@diac24.net> wrote:
>>
>> packet_recvmsg() whitelists a bunch of MSG_* flags, which notably does
>> not include MSG_NOSIGNAL.  Unfortunately, io_uring always sets
>> MSG_NOSIGNAL, meaning AF_PACKET sockets can't be used in io_uring
>> recvmsg().
>>
>> As AF_PACKET sockets never generate SIGPIPE to begin with, MSG_NOSIGNAL
>> is a no-op and can simply be ignored.
>>
>> Signed-off-by: David Lamparter <equinox@diac24.net>
>> Cc: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
>> ---
>>  net/packet/af_packet.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
> 
> This is odd... I think MSG_NOSIGNAL flag has a meaning for sendmsg()
> (or write sides in general)
> 
> EPIPE is not supposed to be generated at the receiving side ?
> 
> So I would rather make io_uring slightly faster :
> 
> 
> diff --git a/io_uring/net.c b/io_uring/net.c
> index cbd4b725f58c98e5bc5bf88d5707db5c8302e071..b7f190ca528e6e259eb2b072d7a16aaba98848cb
> 100644
> --- a/io_uring/net.c
> +++ b/io_uring/net.c
> @@ -567,7 +567,7 @@ int io_recvmsg_prep(struct io_kiocb *req, const
> struct io_uring_sqe *sqe)
>         sr->flags = READ_ONCE(sqe->ioprio);
>         if (sr->flags & ~(RECVMSG_FLAGS))
>                 return -EINVAL;
> -       sr->msg_flags = READ_ONCE(sqe->msg_flags) | MSG_NOSIGNAL;
> +       sr->msg_flags = READ_ONCE(sqe->msg_flags);
>         if (sr->msg_flags & MSG_DONTWAIT)
>                 req->flags |= REQ_F_NOWAIT;
>         if (sr->msg_flags & MSG_ERRQUEUE)

This looks fine to me. Do you want to send a "proper" patch for
this?
Eric Dumazet Feb. 24, 2023, 2:54 p.m. UTC | #5
On Fri, Feb 24, 2023 at 3:32 PM Jens Axboe <axboe@kernel.dk> wrote:
>
> This looks fine to me. Do you want to send a "proper" patch for
> this?

Sure, or perhaps David wanted to take care of this.

Thanks.
diff mbox series

Patch

diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index d4e76e2ae153..67c0a57e6dd8 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -3410,7 +3410,7 @@  static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 	unsigned int origlen = 0;
 
 	err = -EINVAL;
-	if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT|MSG_ERRQUEUE))
+	if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT|MSG_ERRQUEUE|MSG_NOSIGNAL))
 		goto out;
 
 #if 0