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 net-dev
mailing list