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

Sean Mullan sean.mullan at oracle.com
Thu Jan 2 15:12:45 UTC 2020


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
> 


More information about the security-dev mailing list