JDK-8259847 : Don't wrap SocketExceptions into SSLExceptions in SSLSocketImpl
  • Type: CSR
  • Component: security-libs
  • Sub-Component: javax.net.ssl
  • Priority: P4
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 8-pool,11-pool,13-pool,15-pool,16-pool,17
  • Submitted: 2021-01-15
  • Updated: 2021-08-19
  • Resolved: 2021-02-19
Related Reports
CSR :  
CSR :  
CSR :  
Description
## Summary 

Change the behavior of the TLS stack to pass through `SocketException` instead of wrapping it into an SSLException.

## Problem

OpenJDK 8 (up to 8u265 for OpenJDK and 8u251 for Oracle JDK), 9 and 10 imposed the following contract between the `sun.security.ssl.SSLSocketImpl` class and its clients (see [SSLSocketImpl.java#l69](http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/9204e03217f7/src/share/classes/sun/security/ssl/SSLSocketImpl.java#l69)): 

```
     * ERROR HANDLING GUIDELINES
     * (which exceptions to throw and catch and which not to throw and catch)
     *
     * . if there is an IOException (SocketException) when accessing the     
     *   underlying Socket, pass it through     
     *     
     * . do not throw IOExceptions, throw SSLExceptions (or a subclass)     
```

The TLS stack would pass through `SocketException`s unchanged but would wrap other `IOException`s into `SSLException`s. 

However, this contract was changed without notice in OpenJDK 11 by the new TLS1.3 stack [JDK-8196584](https://bugs.openjdk.java.net/browse/JDK-8196584). The new implementation now started wrapping **all** `IOException`s including `SocketException`s into `SSLException`s. 

The error handling guidelines present in the OpenJDK implementations before 11 were used by the application layer to determine how to react to the exception. The application layer (e.g the popular [Apache HTTPClient library](https://hc.apache.org/httpcomponents-client-ga/httpclient/project-reports.html)) would consider `SocketException`s to be retry-able and retry the request. Starting with JDK 11, such applications started  seeing unhandled "`SSLException: Broken Pipe`" exceptions because now `SocketException`s were converted to `SSLException`s. Apache HTTPClient for example reported this as "[HTTPCLIENT-2032: Sometimes get a broken pipe error in Java 11..](https://issues.apache.org/jira/browse/HTTPCLIENT-2032)".

The general problem with the new implementation is that application are now unable to determine if a failure was due to a retry-able `SocketException` or a more permanent `SSLException`. The blast radius of this behavioural change became a lot wider after the new TLS 1.3 stack was downported to jdk 8.

"[JDK-8214339: SSLSocketImpl erroneously wraps SocketException](https://bugs.openjdk.java.net/browse/JDK-8214339)" attempted to fix this issue, however, it was still wrapping `SocketException`s and passing them to the application layer as `SSLException`s. Consequently, the new issue "[JDK-8237578: JDK-8214339 (SSLSocketImpl wraps SocketException)" appears to not be fully fixed"](https://bugs.openjdk.java.net/browse/JDK-8237578) was raised which was finally fixed for jdk 17 but unfortunately had to be backed out immediately because it had missed to update some tests. During the backout discussion the initial reviewers came to the conclusion that a CSR should have been raised for JDK-8237578. Finally, this CSR has been created for [JDK-8259662](https://bugs.openjdk.java.net/browse/JDK-8259662) which is the redo of JDK-8237578.

## Solution

 - Change the implementation of `SSLSocketImpl` in the new TLS 1.3 stack back to the old error handling protocol defined in JDK 8 (see [PR-2057](https://git.openjdk.java.net/jdk/pull/2057)).  
 - Add a comment back to `SSLSocketImpl` class which documents this behaviour:

```
    /*
     * ERROR HANDLING GUIDELINES
     * (which exceptions to throw and catch and which not to throw and catch)
     *
     * - if there is an IOException (SocketException) when accessing the     
     *   underlying Socket, pass it through     
     *     
     * - do not throw IOExceptions, throw SSLExceptions (or a subclass)
     */
```

## Specification 

No specification change. 

Comments
[~cverghese] and [~simonis], please complete work on the JDK 17 release note JDK-8262053; thanks.
19-08-2021

Thanks, Joe!
22-02-2021

I've marked the parent issue as requiring a release note and assigned the release note subtask JDK-8262053 to [~cverghese]. [~cverghese], please write a paragraph or two describing the change. The backports to other releases should get similar release note treatment. Moving to Approved.
19-02-2021

Hi Joe, thank you for explaining why you moved the CSR back to Pended. I didn't realized that some parts were still missing. What do we have to do for the release note? I think that can only be written by Oracle, right? So can I re-finalize the CSR already or do we have to wait until the Release note has been completed. Thank you and best regards, Volker
16-02-2021

Marking this request as pended since it omits required sections of the CSR. All the sections included in the default CSR are required, in order: Summary Problem Solution Specification If there are no specification change, the Specification section should state that. It does not appear that the text in SSLSocketImpl is a spec change per se since that class is not included in the doc bundle. Please correct the CSR form and re-Finalize. Additionally, I think this change merits a release note.
12-02-2021

A CSR is "ready to be approved" after the CSR chair reviews it, not because of the evaluation one of the CSR's advocates.
09-02-2021

This CSR (as well as the corresponding change https://github.com/openjdk/jdk/pull/2057) has now been reviewed and is ready for approval.
09-02-2021

If the change will not make it into 16 we'll have to downport it to 16u. The initial bug was P4 so it will be probably hard to justify it for RDP 2.
29-01-2021

Moving to Provisional. Note as JDK 16 is in ramp down 2, additional procedures are in place for bug fixes going into that release: http://openjdk.java.net/jeps/3#Fix-Request-Process
28-01-2021

Correcting fixVersion to pool values for already shipped releases. Moving this request back to draft. [~xuelei], please review this request. After review, [~cverghese], please re-propose the request.
27-01-2021