On Sun, 22 Nov 2020 18:27:56 GMT, Christoph Langer <clan...@openjdk.org> wrote:

>> There is a flaw in sun.security.ssl.SSLSocketImpl::close() which leads to 
>> leaking socket resources after JDK-8224829.
>> 
>> The close method calls duplexCloseOutput() and duplexCloseInput(). In case 
>> of an exception in any of these methods, the call to closeSocket() is 
>> bypassed, and the underlying Socket may not be closed.
>> 
>> This manifests in a real life leak after JDK-8224829 has introduced a call 
>> to getSoLinger() on the path of duplexCloseOutput -> closeNotify. If socket 
>> impl / OS socket hadn't been created yet it is done at that place. But then 
>> after duplexCloseOutput eventually fails with a SocketException since the 
>> socket wasn't connected, closing fails to call Socket::close().
>> 
>> This problem can be reproduced by this code:
>>                      SSLSocket sslSocket = 
>> (SSLSocket)SSLSocketFactory.getDefault().createSocket();
>>                      sslSocket.getSSLParameters();
>>                      sslSocket.close();
>> 
>> This is what happens when SSLContext.getDefault().getDefaultSSLParameters() 
>> is called, with close() being eventually called by the finalizer.
>> 
>> I'll open this PR as draft for now to start discussion. I'll create a 
>> testcase to reproduce the issue and add it soon.
>> 
>> I propose to modify the close method such that duplexClose is only done on a 
>> connected/bound socket. Maybe it even suffices to only do it when connected.
>> 
>> Secondly, I'm proposing to improve exception handling a bit. So in case 
>> there's an IOException on the path of duplexClose, it is caught and logged. 
>> But the real close moves to the finally block since it should be done 
>> unconditionally.
>
> Christoph Langer has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   Small test improvement

test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketLeak.java line 57:

> 55:         if ((fds_end - fds_start) > (NUM_TEST_SOCK / 10)) {
> 56:             throw new RuntimeException("Too many open file descriptors. 
> Looks leaky.");
> 57:         }

This test case may be not reliable if there are some other test cases or 
applications running at the same time.  It's a good manual test, but might be 
not suitable for OpenJDK automation regression test if it could be impacted.

test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketLeak.java line 37:

> 35:  *          will not leave leaking socket file descriptors
> 36:  * @library /test/lib
> 37:  * @run main/othervm SSLSocketLeak

See bellow comment, I may suggest to have it as a manual test case if you agree 
the test case could be impacted.
@run main/manual SSLSocketLeak

-------------

PR: https://git.openjdk.java.net/jdk/pull/1363

Reply via email to