lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Mon, 19 Oct 2015 16:33:04 -0700
From:	Eric Dumazet <eric.dumazet@...il.com>
To:	Stephen Hemminger <stephen@...workplumber.org>
Cc:	netdev@...r.kernel.org, Alan.Burlison@...cle.com
Subject: Re: Fw: [Bug 106241] New: shutdown(3)/close(3) behaviour is
 incorrect for sockets in accept(3)

On Mon, 2015-10-19 at 09:59 -0700, Stephen Hemminger wrote:
> This looks like corner case, but worth forwarding.
> 
> Begin forwarded message:
> 
> Date: Mon, 19 Oct 2015 13:21:33 +0000
> From: "bugzilla-daemon@...zilla.kernel.org" <bugzilla-daemon@...zilla.kernel.org>
> To: "shemminger@...ux-foundation.org" <shemminger@...ux-foundation.org>
> Subject: [Bug 106241] New: shutdown(3)/close(3) behaviour is incorrect for sockets in accept(3)
> 
> 
> https://bugzilla.kernel.org/show_bug.cgi?id=106241
> 
>             Bug ID: 106241
>            Summary: shutdown(3)/close(3) behaviour is incorrect for
>                     sockets in accept(3)
>            Product: Networking
>            Version: 2.5
>     Kernel Version: 3.10.0-229.14.1.el7.x86_64
>           Hardware: All
>                 OS: Linux
>               Tree: Mainline
>             Status: NEW
>           Severity: normal
>           Priority: P1
>          Component: IPV4
>           Assignee: shemminger@...ux-foundation.org
>           Reporter: Alan.Burlison@...cle.com
>         Regression: No
> 
> Created attachment 190501
>   --> https://bugzilla.kernel.org/attachment.cgi?id=190501&action=edit
> Test program illustrating the problem
> 
> The Linux behaviour in the current scenario is incorrect:
> 
> 1. ThreadA opens, binds, listens and accepts on a socket, waiting for
> connections.
> 
> 2. Some time later ThreadB calls shutdown on the socket ThreadA is waiting in
> accept on.
> 
> Here is what happens:
> 
> On Linux, the shutdown call in ThreadB succeeds and the accept call in ThreadA
> returns with EINVAL.
> 
> On Solaris, the shutdown call in ThreadB fails and returns ENOTCONN. ThreadA
> continues to wait in accept.
> 
> Relevant POSIX manpages:
> 
> http://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html
> http://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html
> 
> The POSIX shutdown manpage says:
> 
> "The shutdown() function shall cause all or part of a full-duplex connection on
> the socket associated with the file descriptor socket to be shut down."
> ...
> "[ENOTCONN] The socket is not connected."
> 
> Page 229 & 303 of "UNIX System V Network Programming" say:
> 
> "shutdown can only be called on sockets that have been previously connected"
> 
> "The socket [passed to accept that] fd refers to does not participate in the
> connection. It remains available to receive further connect indications"
> 
> That is pretty clear, sockets being waited on with accept are not connected by
> definition. Nor is it the accept socket connected when a client connects to it,
> it is the socket returned by accept that is connected to the client. Therefore
> the Solaris behaviour of failing the shutdown call is correct.
> 
> In order to get the required behaviour of ThreadB causing ThreadA to exit the
> accept call with an error, the correct way is for ThreadB to call close on the
> socket that ThreadA is waiting on in accept.
> 
> On Solaris, calling close in ThreadB succeeds, and the accept call in ThreadA
> fails and returns EBADF.
> 
> On Linux, calling close in ThreadB succeeds but ThreadA continues to wait in
> accept until there is an incoming connection. That accept returns successfully.
> However subsequent accept calls on the same socket return EBADF.
> 
> The Linux behaviour is fundamentally broken in three places:
> 
> 1. Allowing shutdown to succeed on an unconnected socket is incorrect.  
> 
> 2. Returning a successful accept on a closed file descriptor is incorrect,
> especially as future accept calls on the same socket fail.
> 
> 3. Once shutdown has been called on the socket, calling close on the socket
> fails with EBADF. That is incorrect, shutdown should just prevent further IO on
> the socket, it should not close it.
> 

It looks it is a long standing problem, right ?

inet_shutdown() has this very specific comment from beginning of git
tree :

        switch (sk->sk_state) {
...
        /* Remaining two branches are temporary solution for missing
         * close() in multithreaded environment. It is _not_ a good idea,
         * but we have no choice until close() is repaired at VFS level.
         */
        case TCP_LISTEN:
                if (!(how & RCV_SHUTDOWN))
                        break;
                /* Fall through */
        case TCP_SYN_SENT:
                err = sk->sk_prot->disconnect(sk, O_NONBLOCK);
                sock->state = err ? SS_DISCONNECTING : SS_UNCONNECTED;
                break;
        }

Claiming Solaris does it differently is kind of moot.
linux is not Solaris.

Unless proven a real problem (and not only by trying to backport from Solaris to linux),
we'll probably wont change this.


--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ