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