Re: [PATCH] af_unix: Allow Unix sockets to raise SIGURG

2021-01-29 Thread Shoaib Rao



On 1/29/21 1:18 PM, Jakub Kicinski wrote:

On Fri, 29 Jan 2021 12:44:44 -0800 Shoaib Rao wrote:

On 1/29/21 12:18 PM, Jakub Kicinski wrote:

On Fri, 29 Jan 2021 12:10:21 -0800 Shoaib Rao wrote:

The code does not care about the size of data -- All it does is that if
MSG_OOB is set it will deliver the signal to the peer process
irrespective of the length of the data (which can be zero length). Let's
look at the code of unix_stream_sendmsg() It does the following (sent is
initialized to zero)

Okay. Let me try again. AFAICS your code makes it so that data sent
with MSG_OOB is treated like any other data. It just sends a signal.

Correct.

So you're hijacking the MSG_OOB to send a signal, because OOB also
sends a signal.

Correct.

   But there is nothing OOB about the data itself.

Correct.

   So
I'm asking you to make sure that there is no data in the message.

Yes I can do that.

That way when someone wants _actual_ OOB data on UNIX sockets they
can implement it without breaking backwards compatibility of the
kernel uAPI.

I see what you are trying to achieve. However it may not work.

Let's assume that __actual__ OOB data has been implemented. An
application sends a zero length message with MSG_OOB, after that it
sends some data (not suppose to be OOB data). How is the receiver going
to differentiate if the data an OOB or not.

THB I've never written any application which would use OOB, so in
practice IDK. But from kernel code and looking at man pages when
OOBINLINE is not set for OOB data to be received MSG_OOB has to be
set in the recv syscall.


Thinking a little more about your suggestion, I think it can work but 
the application will have to do some more work to differentiate. I would 
prefer it would not have to. Anyways, I will re-submit the patch with 
the zero length check.


Thanks a lot for your comments,

Shoaib




We could use a different flag (MSG_SIGURG) or implement the _actual_ OOB
data semantics (If anyone is interested in it). MSG_SIGURG could be a
generic flag that just sends SIGURG irrespective of the length of the data.

No idea on the SIGURG parts :)


Re: [PATCH] af_unix: Allow Unix sockets to raise SIGURG

2021-01-29 Thread Shoaib Rao



On 1/29/21 12:44 PM, Shoaib Rao wrote:


On 1/29/21 12:18 PM, Jakub Kicinski wrote:

On Fri, 29 Jan 2021 12:10:21 -0800 Shoaib Rao wrote:

On 1/29/21 12:02 PM, Jakub Kicinski wrote:

On Fri, 29 Jan 2021 11:48:15 -0800 Shoaib Rao wrote:

Data was discarded because the flag was not supported, this patch
changes that but does not support any urgent data.

When you say it does not support any urgent data do you mean the
message len must be == 0 because something is checking it, or that
the code does not support its handling?

I'm perfectly fine with the former, just point me at the check, 
please.

The code does not care about the size of data -- All it does is that if
MSG_OOB is set it will deliver the signal to the peer process
irrespective of the length of the data (which can be zero length). 
Let's
look at the code of unix_stream_sendmsg() It does the following 
(sent is

initialized to zero)

Okay. Let me try again. AFAICS your code makes it so that data sent
with MSG_OOB is treated like any other data. It just sends a signal.

Correct.

So you're hijacking the MSG_OOB to send a signal, because OOB also
sends a signal.

Correct.

  But there is nothing OOB about the data itself.

Correct.

  So
I'm asking you to make sure that there is no data in the message.

Yes I can do that.

That way when someone wants _actual_ OOB data on UNIX sockets they
can implement it without breaking backwards compatibility of the
kernel uAPI.


I see what you are trying to achieve. However it may not work.

Let's assume that __actual__ OOB data has been implemented. An 
application sends a zero length message with MSG_OOB, after that it 
sends some data (not suppose to be OOB data). How is the receiver 
going to differentiate if the data an OOB or not.


We could use a different flag (MSG_SIGURG) or implement the _actual_ 
OOB data semantics (If anyone is interested in it). MSG_SIGURG could 
be a generic flag that just sends SIGURG irrespective of the length of 
the data.


Shoaib


There is a relevant issue that I want to point out, Is it acceptable to 
send SIGURG without the receiver having any means to know what the 
urgent condition is?


Shoaib






while (sent < len) {
      size = len - sent;
<..>

}

      if (msg->msg_flags & MSG_OOB)
      sk_send_sigurg(other);

Before the patch there was a check above the while loop that checked 
the

flag and returned and error, that has been removed.


Re: [PATCH] af_unix: Allow Unix sockets to raise SIGURG

2021-01-29 Thread Shoaib Rao



On 1/29/21 12:18 PM, Jakub Kicinski wrote:

On Fri, 29 Jan 2021 12:10:21 -0800 Shoaib Rao wrote:

On 1/29/21 12:02 PM, Jakub Kicinski wrote:

On Fri, 29 Jan 2021 11:48:15 -0800 Shoaib Rao wrote:

Data was discarded because the flag was not supported, this patch
changes that but does not support any urgent data.

When you say it does not support any urgent data do you mean the
message len must be == 0 because something is checking it, or that
the code does not support its handling?

I'm perfectly fine with the former, just point me at the check, please.

The code does not care about the size of data -- All it does is that if
MSG_OOB is set it will deliver the signal to the peer process
irrespective of the length of the data (which can be zero length). Let's
look at the code of unix_stream_sendmsg() It does the following (sent is
initialized to zero)

Okay. Let me try again. AFAICS your code makes it so that data sent
with MSG_OOB is treated like any other data. It just sends a signal.

Correct.

So you're hijacking the MSG_OOB to send a signal, because OOB also
sends a signal.

Correct.

  But there is nothing OOB about the data itself.

Correct.

  So
I'm asking you to make sure that there is no data in the message.

Yes I can do that.

That way when someone wants _actual_ OOB data on UNIX sockets they
can implement it without breaking backwards compatibility of the
kernel uAPI.


I see what you are trying to achieve. However it may not work.

Let's assume that __actual__ OOB data has been implemented. An 
application sends a zero length message with MSG_OOB, after that it 
sends some data (not suppose to be OOB data). How is the receiver going 
to differentiate if the data an OOB or not.


We could use a different flag (MSG_SIGURG) or implement the _actual_ OOB 
data semantics (If anyone is interested in it). MSG_SIGURG could be a 
generic flag that just sends SIGURG irrespective of the length of the data.


Shoaib




while (sent < len) {
      size = len - sent;
<..>

}

      if (msg->msg_flags & MSG_OOB)
      sk_send_sigurg(other);

Before the patch there was a check above the while loop that checked the
flag and returned and error, that has been removed.


Re: [PATCH] af_unix: Allow Unix sockets to raise SIGURG

2021-01-29 Thread Shoaib Rao



On 1/29/21 12:02 PM, Jakub Kicinski wrote:

On Fri, 29 Jan 2021 11:48:15 -0800 Shoaib Rao wrote:

SO_OOBINLINE does not control the delivery of signal, It controls how
OOB Byte is delivered. It may not be obvious but this change does not
deliver any Byte, just a signal. So, as long as sendmsg flag contains
MSG_OOB, signal will be delivered just like it happens for TCP.

Not as far as I can read this code. If MSG_OOB is set the data from the
message used to be discarded, and EOPNOTSUPP returned. Now the data gets
queued to the socket, and will be read inline.

Data was discarded because the flag was not supported, this patch
changes that but does not support any urgent data.

When you say it does not support any urgent data do you mean the
message len must be == 0 because something is checking it, or that
the code does not support its handling?

I'm perfectly fine with the former, just point me at the check, please.


The code does not care about the size of data -- All it does is that if 
MSG_OOB is set it will deliver the signal to the peer process 
irrespective of the length of the data (which can be zero length). Let's 
look at the code of unix_stream_sendmsg() It does the following (sent is 
initialized to zero)


while (sent < len) {
    size = len - sent;
<..>

}

    if (msg->msg_flags & MSG_OOB)
    sk_send_sigurg(other);

Before the patch there was a check above the while loop that checked the 
flag and returned and error, that has been removed.


Shoaib




OOB data has some semantics that would have to be followed and if we
support SO_OOBINLINE we would have to support NOT SO_OOBINLINE.

One can argue that we add a socket option to allow this OR just do what
TCP does.


Re: [PATCH] af_unix: Allow Unix sockets to raise SIGURG

2021-01-29 Thread Shoaib Rao



On 1/29/21 11:54 AM, Shoaib Rao wrote:


On 1/29/21 11:19 AM, Matthew Wilcox wrote:

On Fri, Jan 29, 2021 at 09:56:48AM -0800, Shoaib Rao wrote:

On 1/25/21 3:36 PM, Jakub Kicinski wrote:

On Fri, 22 Jan 2021 15:06:37 + Matthew Wilcox (Oracle) wrote:

From: Rao Shoaib 

TCP sockets allow SIGURG to be sent to the process holding the other
end of the socket.  Extend Unix sockets to have the same ability.

The API is the same in that the sender uses sendmsg() with MSG_OOB to
raise SIGURG.  Unix sockets behave in the same way as TCP sockets 
with

SO_OOBINLINE set.
Noob question, if we only want to support the inline mode, why 
don't we

require SO_OOBINLINE to have been called on @other? Wouldn't that
provide more consistent behavior across address families?

With the current implementation the receiver will also not see MSG_OOB
set in msg->msg_flags, right?

SO_OOBINLINE does not control the delivery of signal, It controls how
OOB Byte is delivered. It may not be obvious but this change does not
deliver any Byte, just a signal. So, as long as sendmsg flag contains
MSG_OOB, signal will be delivered just like it happens for TCP.

I don't think that's the question Jakub is asking.  As I understand it,
if you send a MSG_OOB on a TCP socket and the receiver calls recvmsg(),
it will see MSG_OOB set, even if SO_OOBINLINE is set.

No it wont. Application just gets a signal.

   That wouldn't
happen with Unix sockets.  I'm OK with that difference in behaviour,
because MSG_OOB on Unix sockets _is not_ for sending out of band data.
It's just for sending an urgent signal.

That is what I just explained in my email


As you say, MSG_OOB does not require data to be sent for unix sockets
(unlike TCP which always requires at least one byte), but one can
choose to send data as part of a message which has MSG_OOB set. It
won't be tagged in any special way.

To Jakub's other question, we could require SO_OOBINLINE to be set.
That'd provide another layer of insurance against applications being
surprised by a SIGURG they weren't expecting.  I don't know that it's
really worth it though.


SO_OOBINLINE has a meaning, that the urgent byte is part of the stream 
and using SO_OOBLINE to allow signalling would be wrong/confusing. We 
could add a socket option on the receiver to indicate if it supports 
or wants the signal.




One thing I wasn't clear about, and maybe you know, if we send a 
MSG_OOB,

does this patch cause this part of the tcp(7) manpage to be true for
unix sockets too?

    When out-of-band data is present, select(2) indicates the 
file descrip‐
    tor as having an exceptional condition and poll (2) indicates 
a POLLPRI

    event.


No because there is no data involved. Poll is associated with data not 
signals.


Shoaib


SO_OOBINLINE implies there is urgent data inline -- This patch will send 
a signal even if there is no data.


Shoaib







Re: [PATCH] af_unix: Allow Unix sockets to raise SIGURG

2021-01-29 Thread Shoaib Rao



On 1/29/21 11:19 AM, Matthew Wilcox wrote:

On Fri, Jan 29, 2021 at 09:56:48AM -0800, Shoaib Rao wrote:

On 1/25/21 3:36 PM, Jakub Kicinski wrote:

On Fri, 22 Jan 2021 15:06:37 + Matthew Wilcox (Oracle) wrote:

From: Rao Shoaib 

TCP sockets allow SIGURG to be sent to the process holding the other
end of the socket.  Extend Unix sockets to have the same ability.

The API is the same in that the sender uses sendmsg() with MSG_OOB to
raise SIGURG.  Unix sockets behave in the same way as TCP sockets with
SO_OOBINLINE set.

Noob question, if we only want to support the inline mode, why don't we
require SO_OOBINLINE to have been called on @other? Wouldn't that
provide more consistent behavior across address families?

With the current implementation the receiver will also not see MSG_OOB
set in msg->msg_flags, right?

SO_OOBINLINE does not control the delivery of signal, It controls how
OOB Byte is delivered. It may not be obvious but this change does not
deliver any Byte, just a signal. So, as long as sendmsg flag contains
MSG_OOB, signal will be delivered just like it happens for TCP.

I don't think that's the question Jakub is asking.  As I understand it,
if you send a MSG_OOB on a TCP socket and the receiver calls recvmsg(),
it will see MSG_OOB set, even if SO_OOBINLINE is set.

No it wont. Application just gets a signal.

   That wouldn't
happen with Unix sockets.  I'm OK with that difference in behaviour,
because MSG_OOB on Unix sockets _is not_ for sending out of band data.
It's just for sending an urgent signal.

That is what I just explained in my email


As you say, MSG_OOB does not require data to be sent for unix sockets
(unlike TCP which always requires at least one byte), but one can
choose to send data as part of a message which has MSG_OOB set.  It
won't be tagged in any special way.

To Jakub's other question, we could require SO_OOBINLINE to be set.
That'd provide another layer of insurance against applications being
surprised by a SIGURG they weren't expecting.  I don't know that it's
really worth it though.


SO_OOBINLINE has a meaning, that the urgent byte is part of the stream and 
using SO_OOBLINE to allow signalling would be wrong/confusing. We could add a 
socket option on the receiver to indicate if it supports or wants the signal.



One thing I wasn't clear about, and maybe you know, if we send a MSG_OOB,
does this patch cause this part of the tcp(7) manpage to be true for
unix sockets too?

When out-of-band data is present, select(2) indicates the file descrip‐
tor as having an exceptional condition and poll (2) indicates a POLLPRI
event.


No because there is no data involved. Poll is associated with data not 
signals.


Shoaib





Re: [PATCH] af_unix: Allow Unix sockets to raise SIGURG

2021-01-29 Thread Shoaib Rao



On 1/29/21 11:06 AM, Jakub Kicinski wrote:

On Fri, 29 Jan 2021 09:56:48 -0800 Shoaib Rao wrote:

On 1/25/21 3:36 PM, Jakub Kicinski wrote:

On Fri, 22 Jan 2021 15:06:37 + Matthew Wilcox (Oracle) wrote:

From: Rao Shoaib 

TCP sockets allow SIGURG to be sent to the process holding the other
end of the socket.  Extend Unix sockets to have the same ability.

The API is the same in that the sender uses sendmsg() with MSG_OOB to
raise SIGURG.  Unix sockets behave in the same way as TCP sockets with
SO_OOBINLINE set.

Noob question, if we only want to support the inline mode, why don't we
require SO_OOBINLINE to have been called on @other? Wouldn't that
provide more consistent behavior across address families?

With the current implementation the receiver will also not see MSG_OOB
set in msg->msg_flags, right?

SO_OOBINLINE does not control the delivery of signal, It controls how
OOB Byte is delivered. It may not be obvious but this change does not
deliver any Byte, just a signal. So, as long as sendmsg flag contains
MSG_OOB, signal will be delivered just like it happens for TCP.

Not as far as I can read this code. If MSG_OOB is set the data from the
message used to be discarded, and EOPNOTSUPP returned. Now the data gets
queued to the socket, and will be read inline.


Data was discarded because the flag was not supported, this patch 
changes that but does not support any urgent data.


OOB data has some semantics that would have to be followed and if we 
support SO_OOBINLINE we would have to support NOT SO_OOBINLINE.


One can argue that we add a socket option to allow this OR just do what 
TCP does.


Shoaib




Sure, you also add firing of the signal, which is fine. The removal of
the error check is the code I'm pointing at, so to speak.

That is the change in behavior that this change is making.



SIGURG is ignored by default, so applications which do not know about this
feature will be unaffected.  In addition to installing a SIGURG handler,
the receiving application must call F_SETOWN or F_SETOWN_EX to indicate
which process or thread should receive the signal.

Signed-off-by: Rao Shoaib 
Signed-off-by: Matthew Wilcox (Oracle) 
---
   net/unix/af_unix.c | 5 +++--
   1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 41c3303c3357..849dff688c2c 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1837,8 +1837,6 @@ static int unix_stream_sendmsg(struct socket *sock, 
struct msghdr *msg,
return err;
   
   	err = -EOPNOTSUPP;

-   if (msg->msg_flags&MSG_OOB)
-   goto out_err;
   
   	if (msg->msg_namelen) {

err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP;
@@ -1903,6 +1901,9 @@ static int unix_stream_sendmsg(struct socket *sock, 
struct msghdr *msg,
sent += size;
}
   
+	if (msg->msg_flags & MSG_OOB)

+   sk_send_sigurg(other);
+
scm_destroy(&scm);
   
   	return sent;


Re: [PATCH] af_unix: Allow Unix sockets to raise SIGURG

2021-01-29 Thread Shoaib Rao



On 1/25/21 3:36 PM, Jakub Kicinski wrote:

On Fri, 22 Jan 2021 15:06:37 + Matthew Wilcox (Oracle) wrote:

From: Rao Shoaib 

TCP sockets allow SIGURG to be sent to the process holding the other
end of the socket.  Extend Unix sockets to have the same ability.

The API is the same in that the sender uses sendmsg() with MSG_OOB to
raise SIGURG.  Unix sockets behave in the same way as TCP sockets with
SO_OOBINLINE set.

Noob question, if we only want to support the inline mode, why don't we
require SO_OOBINLINE to have been called on @other? Wouldn't that
provide more consistent behavior across address families?

With the current implementation the receiver will also not see MSG_OOB
set in msg->msg_flags, right?


SO_OOBINLINE does not control the delivery of signal, It controls how OOB Byte 
is delivered. It may not be obvious but this change does not deliver any Byte, 
just a signal. So, as long as sendmsg flag contains MSG_OOB, signal will be 
delivered just like it happens for TCP.

Shoaib




SIGURG is ignored by default, so applications which do not know about this
feature will be unaffected.  In addition to installing a SIGURG handler,
the receiving application must call F_SETOWN or F_SETOWN_EX to indicate
which process or thread should receive the signal.

Signed-off-by: Rao Shoaib 
Signed-off-by: Matthew Wilcox (Oracle) 
---
  net/unix/af_unix.c | 5 +++--
  1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 41c3303c3357..849dff688c2c 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1837,8 +1837,6 @@ static int unix_stream_sendmsg(struct socket *sock, 
struct msghdr *msg,
return err;
  
  	err = -EOPNOTSUPP;

-   if (msg->msg_flags&MSG_OOB)
-   goto out_err;
  
  	if (msg->msg_namelen) {

err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP;
@@ -1903,6 +1901,9 @@ static int unix_stream_sendmsg(struct socket *sock, 
struct msghdr *msg,
sent += size;
}
  
+	if (msg->msg_flags & MSG_OOB)

+   sk_send_sigurg(other);
+
scm_destroy(&scm);
  
  	return sent;