<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:#0563C1;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:#954F72;
        text-decoration:underline;}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
        {mso-style-priority:34;
        margin-top:0cm;
        margin-right:0cm;
        margin-bottom:0cm;
        margin-left:36.0pt;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
span.EmailStyle18
        {mso-style-type:personal;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
span.EmailStyle19
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
/* List Definitions */
@list l0
        {mso-list-id:2130391784;
        mso-list-type:hybrid;
        mso-list-template-ids:2007638736 67567639 67567641 67567643 67567631 67567641 67567643 67567631 67567641 67567643;}
@list l0:level1
        {mso-level-number-format:alpha-lower;
        mso-level-text:"%1\)";
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l0:level2
        {mso-level-number-format:alpha-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l0:level3
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        text-indent:-9.0pt;}
@list l0:level4
        {mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l0:level5
        {mso-level-number-format:alpha-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l0:level6
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        text-indent:-9.0pt;}
@list l0:level7
        {mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l0:level8
        {mso-level-number-format:alpha-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l0:level9
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        text-indent:-9.0pt;}
ol
        {margin-bottom:0cm;}
ul
        {margin-bottom:0cm;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="DE" link="#0563C1" vlink="#954F72">
<div class="WordSection1">
<p class="MsoNormal"><span style="color:#1F497D">Hi,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="color:#1F497D">I think I’ve found a way to fix the issue which looks quite reasonable to me. Would you please comment/review it? I’ve also included a test to reproduce the issue.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="color:#1F497D">Webrev:</span><span lang="EN-US" style="color:black">
</span><span style="color:#1F497D"><a href="http://cr.openjdk.java.net/~clanger/webrevs/8149169.1/"><span lang="EN-US">http://cr.openjdk.java.net/~clanger/webrevs/8149169.1/</span></a></span><span lang="EN-US" style="color:#1F497D"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="color:#1F497D">Bug: <a href="https://bugs.openjdk.java.net/browse/JDK-8149169">
https://bugs.openjdk.java.net/browse/JDK-8149169</a><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="color:#1F497D">Thanks and best regards<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="color:#1F497D">Christoph<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0cm 0cm 0cm 4.0pt">
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal"><b><span lang="EN-US" style="mso-fareast-language:DE">From:</span></b><span lang="EN-US" style="mso-fareast-language:DE"> Langer, Christoph
<br>
<b>Sent:</b> Dienstag, 15. März 2016 23:00<br>
<b>To:</b> security-dev@openjdk.java.net<br>
<b>Subject:</b> Regarding JDK-8149169 - SSLSocketInputRecord.decodeInputRecord buffer overflow<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Hi there,<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><span lang="EN-US">today I did some debugging regarding the TLS exception I’ve seen and reported in JDK-8149169:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">javax.net.ssl.SSLException: java.nio.BufferOverflowException
<br>
        at sun.security.ssl.Alerts.getSSLException(Alerts.java:214) <br>
        at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1948) <br>
        at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1900) <br>
        at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1883)
<br>
        at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1809)
<br>
        at sun.security.ssl.AppInputStream.read(AppInputStream.java:173) <br>
        at java.io.BufferedInputStream.fill(BufferedInputStream.java:246) <br>
        at java.io.BufferedInputStream.read1(BufferedInputStream.java:286) <br>
        at java.io.BufferedInputStream.read(BufferedInputStream.java:345) <br>
        at sun.net.</span><a href="http://www.http.HttpClient.parseHTTPHeader%28HttpClient.java:704%29" title="Follow link"><span lang="EN-US">www.http.HttpClient.parseHTTPHeader(HttpClient.java:704)</span></a><span lang="EN-US">
<br>
        at sun.net.</span><a href="http://www.http.HttpClient.parseHTTP%28HttpClient.java:647%29" title="Follow link"><span lang="EN-US">www.http.HttpClient.parseHTTP(HttpClient.java:647)</span></a><span lang="EN-US">
<br>
        at sun.net.</span><a href="http://www.http.HttpClient.parseHTTP%28HttpClient.java:675%29" title="Follow link"><span lang="EN-US">www.http.HttpClient.parseHTTP(HttpClient.java:675)</span></a><span lang="EN-US">
<br>
        at sun.net.</span><a href="http://www.protocol.http.HttpURLConnection.getInputStream0%28HttpURLConnection.java:1534%29" title="Follow link"><span lang="EN-US">www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1534)</span></a><span lang="EN-US">
<br>
        at sun.net.</span><a href="http://www.protocol.http.HttpURLConnection.getInputStream%28HttpURLConnection.java:1439%29" title="Follow link"><span lang="EN-US">www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1439)</span></a><span lang="EN-US">
<br>
        at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
<br>
        at sun.net.</span><a href="http://www.protocol.https.HttpsURLConnectionImpl.getResponseCode%28HttpsURLConnectionImpl.java:319%29" title="Follow link">www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:319)</a>
<br>
        at com.sap.cl.HttpsURLConnectionTest.sendGETRequest(HttpsURLConnectionTest.java:42)
<br>
        at com.sap.cl.HttpsURLConnectionTest.main(HttpsURLConnectionTest.java:63)
<br>
Caused by: java.nio.BufferOverflowException <br>
        at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:206) <br>
        at sun.security.ssl.SSLSocketInputRecord.decodeInputRecord(SSLSocketInputRecord.java:226)
<br>
        at sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:178)
<br>
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1012) <br>
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:957) <br>
        at sun.security.ssl.AppInputStream.read(AppInputStream.java:159) <br>
        ... 12 more<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><span lang="EN-US">I think the problem is with the logic in sun.security.ssl.AppInputStream. read(byte[] b, int off, int len). The read method calls the readRecord(buffer) method of the socket (SSLSocketImpl) and hands it the buffer to
 be eventually filled by SSLSocketInputRecord.decodeInputRecord(). The buffer is initialized with 4K and before readRecord is called, the packet length is verified (in line 144: int packetLen = socket.bytesInCompletePacket();) and the buffer reallocated if
 the incoming package would be larger than the buffer. However, in my case, the incoming package is a handshake package of a small size, so the buffer won’t be adjusted. Then, after the handshake is done, the real data packet is read, still within SSLSocketImpl.readRecord()
 (e.g. line 1012 of SSLSocketImpl) and this one has a length of more than 4K. So the buffer will be too small in decodeInputRecord and hence the exception is thrown.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">So, basically the issue will appear if the TLS data package following immediately after a server initiated handshake will be larger than the buffer of AppInputStream. I guess that should be easily recreatable in a small
 test case.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Now the question how to fix? I can see 3 options:<o:p></o:p></span></p>
<p class="MsoListParagraph" style="text-indent:-18.0pt;mso-list:l0 level1 lfo2"><![if !supportLists]><span lang="EN-US"><span style="mso-list:Ignore">a)<span style="font:7.0pt "Times New Roman"">     
</span></span></span><![endif]><span lang="EN-US">Just allocate the ByteBuffer in AppInputStream to SSLRecord.maxLargeRecordSize (about 32K) – easiest fix and removing the need to check the length for each record. But I guess this is not desired as the buffer
 is unnecessarily large for most cases?<o:p></o:p></span></p>
<p class="MsoListParagraph" style="text-indent:-18.0pt;mso-list:l0 level1 lfo2"><![if !supportLists]><span lang="EN-US"><span style="mso-list:Ignore">b)<span style="font:7.0pt "Times New Roman"">     
</span></span></span><![endif]><span lang="EN-US">Extend SSLSocketInputRecord somehow to be able to not only read the length of the incoming packet but also the type, e.g. if it is a handshake. In that case the buffer would need to be extended to SSLRecord.maxLargeRecordSize.
 But why not do a) then??<o:p></o:p></span></p>
<p class="MsoListParagraph" style="text-indent:-18.0pt;mso-list:l0 level1 lfo2"><![if !supportLists]><span lang="EN-US"><span style="mso-list:Ignore">c)<span style="font:7.0pt "Times New Roman"">      
</span></span></span><![endif]><span lang="EN-US">Check the volume bytes returned from readRecord and redo the read in case the volume is larger than the buffer capacity<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Which way should I pursue? Do you see another option? Or am I getting something completely wrong running into an illegal case?<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Thanks in advance for your feedback,<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Christoph<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
</div>
</div>
</body>
</html>