Greg Kroah-Hartman <gre...@linuxfoundation.org> writes:
> 3.10-stable review patch.  If anyone has any objections, please let me
> know.

Since there's apparently little hope that you kindly stop spamming me
with this any time soon: The objection to this is still that the
non-blocking call shouldn't ever block (and hence, maintain the undocumented
property whose loss apparently wasn't noticed by anyone in the last
three years(!) as a side effect). That's arguably at least partially my
fault because I didn't think about the implications for non-blocking
case in 2011. For an example how this should be implemented, have a
look at pipe.c (summary: lock uninterruptibly, check state, unlock, go
to sleep or return EAGAIN, relock after sleep [if applicable]).

However, if there are actually applications depending on this behaviour,
this workaround is surely sensible for dealing with them.

>
> ------------------
>
> From: Eric Dumazet <eduma...@google.com>
>
> [ Upstream commit de1443916791d75fdd26becb116898277bb0273f ]
>
> Some applications didn't expect recvmsg() on a non blocking socket
> could return -EINTR. This possibility was added as a side effect
> of commit b3ca9b02b00704 ("net: fix multithreaded signal handling in
> unix recv routines").
>
> To hit this bug, you need to be a bit unlucky, as the u->readlock
> mutex is usually held for very small periods.
>
> Fixes: b3ca9b02b00704 ("net: fix multithreaded signal handling in unix recv 
> routines")
> Signed-off-by: Eric Dumazet <eduma...@google.com>
> Cc: Rainer Weikusat <rweiku...@mobileactivedefense.com>
> Signed-off-by: David S. Miller <da...@davemloft.net>
> Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
> ---
>  net/unix/af_unix.c |   17 ++++++++++++-----
>  1 file changed, 12 insertions(+), 5 deletions(-)
>
> --- a/net/unix/af_unix.c
> +++ b/net/unix/af_unix.c
> @@ -1792,8 +1792,11 @@ static int unix_dgram_recvmsg(struct kio
>               goto out;
>  
>       err = mutex_lock_interruptible(&u->readlock);
> -     if (err) {
> -             err = sock_intr_errno(sock_rcvtimeo(sk, noblock));
> +     if (unlikely(err)) {
> +             /* recvmsg() in non blocking mode is supposed to return -EAGAIN
> +              * sk_rcvtimeo is not honored by mutex_lock_interruptible()
> +              */
> +             err = noblock ? -EAGAIN : -ERESTARTSYS;
>               goto out;
>       }
>  
> @@ -1913,6 +1916,7 @@ static int unix_stream_recvmsg(struct ki
>       struct unix_sock *u = unix_sk(sk);
>       struct sockaddr_un *sunaddr = msg->msg_name;
>       int copied = 0;
> +     int noblock = flags & MSG_DONTWAIT;
>       int check_creds = 0;
>       int target;
>       int err = 0;
> @@ -1928,7 +1932,7 @@ static int unix_stream_recvmsg(struct ki
>               goto out;
>  
>       target = sock_rcvlowat(sk, flags&MSG_WAITALL, size);
> -     timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT);
> +     timeo = sock_rcvtimeo(sk, noblock);
>  
>       /* Lock the socket to prevent queue disordering
>        * while sleeps in memcpy_tomsg
> @@ -1940,8 +1944,11 @@ static int unix_stream_recvmsg(struct ki
>       }
>  
>       err = mutex_lock_interruptible(&u->readlock);
> -     if (err) {
> -             err = sock_intr_errno(timeo);
> +     if (unlikely(err)) {
> +             /* recvmsg() in non blocking mode is supposed to return -EAGAIN
> +              * sk_rcvtimeo is not honored by mutex_lock_interruptible()
> +              */
> +             err = noblock ? -EAGAIN : -ERESTARTSYS;
>               goto out;
>       }
>  
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to