Reading from a closed socket: different behavior between Linux and other operating systems

David Lloyd david.lloyd at redhat.com
Fri Jan 3 13:53:25 UTC 2020


This is, AFAICT, expected based on the differences between the socket
layers of the various operating systems involved and their handling of
closed sockets.  If you write a similar test program in C using OS specific
APIs, I believe you will see similar results.  I don't think this is a
problem with the JDK, nor is it likely to be something that can be fixed in
the JDK (since the error reported by the OS is, as far as I know, unlikely
to be universally sufficient to extrapolate the exact cause of failure).

On Thu, Jan 2, 2020 at 9:14 AM Sean Mullan <sean.mullan at oracle.com> wrote:

> Cross-posting to security-dev as SSL is involved.
>
> --Sean
>
> On 12/29/19 4:01 PM, Dawid Weiss wrote:
> > Hello,
> >
> > I am a committer to the Apache Lucene project. We have been looking
> > into a problem in which SSL connections were handled differently in
> > tests on different operating systems and narrowed it down to
> > essentially the following scenario (full repro code at [1]):
> >
> > Server side:
> >
> >    try (ServerSocketChannel serverChannel = ServerSocketChannel.open()) {
> >      SocketChannel clientChannel = serverChannel.accept();
> >      clientChannel.close();
> >    }
> >
> > Client side:
> >
> >    Socket socket = new Socket();
> >    socket.connect(target);
> >    // ... server closes the socket here.
> >    // Queue some data for writing to the closed socket. This succeeds.
> >    socket.getOutputStream().write("will succeed?!".getBytes("UTF-8"));
> >    // Try to read something from the closed socket.
> >    socket.getInputStream().read(new byte[100]);
> >
> > The last line of the client results in different behavior between
> > operating systems.
> >
> > 1) Linux, JDK 11, 13, 14: succeeds with -1 (EOF).
> > 2) Windows, JDK 11: SocketException ("recv failed") is thrown
> > 3) Windows, JDK 13, 14: SocketException (localized message) is thrown
> > 4) FreeBSD: SocketException (connection reset) is thrown
> > 5) Mac OS X: SocketException (connection reset) is thrown
> >
> > I admit my original thinking on the Lucene issue (see full  discussion
> > at [2]) was that it was Windows that was off here (due to
> > WSAECONNRESET not being handled at all in SocketInputStream.c [3].
> > Since then (JDK11) the underlying socket implementation has changed
> > due to JEP 353 [4] (which Alan Bateman kindly pointed out to me).
> >
> > But the difference in runtime behavior between Linux and other
> > operating systems still exists on both the old and the new
> > implementation. I don't know whether it's something that should be
> > qualified as platform-specific but it causes additional problems when
> > it triggers somewhere deep inside the SSL handling layer -- then the
> > application-level code receives a different exception depending on
> > where it's run (an SSLException with a suppressed SocketException or a
> > SocketException directly).
> >
> > I don't have any ideas about what a "good" fix for this is but I'm
> > curious what others think.
> >
> > Dawid
> >
> > [1]
> https://issues.apache.org/jira/secure/attachment/12989538/RecvRepro.java
> > [2] https://issues.apache.org/jira/browse/SOLR-13778
> > [3]
> https://github.com/openjdk/jdk14/blob/f58a8cbed2ba984ceeb9a1ea59f917e3f9530f1e/src/java.base/windows/native/libnet/SocketInputStream.c#L120-L154
> > [4] https://openjdk.java.net/jeps/353
> >
>
>

-- 
- DML
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/security-dev/attachments/20200103/5fb89e4b/attachment.htm>


More information about the security-dev mailing list