Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8274524

SSLSocket.close() hangs if it is called during the ssl handshake

    XMLWordPrintable

    Details

      Backports

        Description

        JCK test api/javax_net/ssl/SSLSocket/setUseClientMode.html fails on Linux & NioSocket with "Error. test was interrupted! (timeout?)"

        During TLS handshake socket read operations are not protected by readLock. Here is a stack trace of the read during handshake:
        at java.base/sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:48)
        at java.base/sun.nio.ch.NioSocketImpl.tryRead(NioSocketImpl.java:261)
        at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:312)
        at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:350)
        at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:803)
        at java.base/java.net.Socket$SocketInputStream.read(Socket.java:981)
        at java.base/sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:478)
        at java.base/sun.security.ssl.SSLSocketInputRecord.readFully(SSLSocketInputRecord.java:461)
        at java.base/sun.security.ssl.SSLSocketInputRecord.decodeInputRecord(SSLSocketInputRecord.java:243)
        at java.base/sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:181)
        at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:110)
        at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1491)
        at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1397)
        at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:444)
        at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:415)

        SSLSocket.close() also reads from socket after JDK-8268965:
        at java.base/sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:48)
        at java.base/sun.nio.ch.NioSocketImpl.tryRead(NioSocketImpl.java:261)
        at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:312)
        at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:350)
        at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:803)
        at java.base/java.net.Socket$SocketInputStream.read(Socket.java:981)
        at java.base/java.io.InputStream.skip(InputStream.java:544)
        at java.base/sun.security.ssl.SSLSocketInputRecord.deplete(SSLSocketInputRecord.java:504)
        at java.base/sun.security.ssl.SSLSocketImpl.closeSocket(SSLSocketImpl.java:1762)
        at java.base/sun.security.ssl.SSLSocketImpl.shutdown(SSLSocketImpl.java:1739)
        at java.base/sun.security.ssl.SSLSocketImpl.bruteForceCloseInput(SSLSocketImpl.java:773)
        at java.base/sun.security.ssl.SSLSocketImpl.duplexCloseOutput(SSLSocketImpl.java:638)
        at java.base/sun.security.ssl.SSLSocketImpl.close(SSLSocketImpl.java:570)

        InputStream.skip() is implemented as a simple read from NIO socket without any locks. It is implemented as a loop of read(available()) As result, in case of called concurrently, SSLSocket.close() could hangs trying to read available bytes from socket, while startHandshake() already read them

        The issue does not affect concurrent SSLSocket.close() and application input stream because of SSLSocketInputRecord.deplete() is protected by Application Input Stream read lock.

          Attachments

            Issue Links

              Activity

                People

                Assignee:
                abakhtin Alexey Bakhtin
                Reporter:
                abakhtin Alexey Bakhtin
                Votes:
                0 Vote for this issue
                Watchers:
                12 Start watching this issue

                  Dates

                  Created:
                  Updated:
                  Resolved: