This is an automated email from the ASF dual-hosted git repository.

remm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/master by this push:
     new 6367351  Improve handling of overflow
6367351 is described below

commit 63673514f29c60dfbaa72665a676c2ce92b6bf75
Author: remm <r...@apache.org>
AuthorDate: Fri Mar 8 11:30:36 2019 +0100

    Improve handling of overflow
    
    Attempt to use the main read buffer as overflow for decrypted data.
    Although I could modify the OpenSSL engine to hold it, the default JSSE
    engine doesn't want to do it either, so it is not an option. I don't
    think this will create thread safety problems, but if it does, will
    revert back to requiring additional space in the destination buffers.
---
 java/org/apache/coyote/http2/Http2AsyncParser.java |  6 +----
 .../apache/tomcat/util/net/SecureNio2Channel.java  | 29 +++++++++++++++++++---
 webapps/docs/changelog.xml                         |  3 ++-
 3 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/java/org/apache/coyote/http2/Http2AsyncParser.java 
b/java/org/apache/coyote/http2/Http2AsyncParser.java
index 7bd24df..92531bf 100644
--- a/java/org/apache/coyote/http2/Http2AsyncParser.java
+++ b/java/org/apache/coyote/http2/Http2AsyncParser.java
@@ -42,11 +42,7 @@ class Http2AsyncParser extends Http2Parser {
         socketWrapper.getSocketBufferHandler().expand(input.getMaxFrameSize());
         this.upgradeHandler = upgradeHandler;
         header = ByteBuffer.allocate(9);
-        int frameBufferSize = input.getMaxFrameSize();
-        if (socketWrapper.isSecure()) {
-            frameBufferSize += 16676;
-        }
-        framePaylod = ByteBuffer.allocate(frameBufferSize);
+        framePaylod = ByteBuffer.allocate(input.getMaxFrameSize());
     }
 
 
diff --git a/java/org/apache/tomcat/util/net/SecureNio2Channel.java 
b/java/org/apache/tomcat/util/net/SecureNio2Channel.java
index 4ae2509..8c70991 100644
--- a/java/org/apache/tomcat/util/net/SecureNio2Channel.java
+++ b/java/org/apache/tomcat/util/net/SecureNio2Channel.java
@@ -1008,11 +1008,15 @@ public class SecureNio2Channel extends Nio2Channel  {
                         long read = 0;
                         //the SSL engine result
                         SSLEngineResult unwrap;
+                        ByteBuffer[] dsts2 = dsts;
+                        int length2 = length;
+                        boolean processOverflow = false;
                         do {
+                            processOverflow = false;
                             //prepare the buffer
                             netInBuffer.flip();
                             //unwrap the data
-                            unwrap = sslEngine.unwrap(netInBuffer, dsts, 
offset, length);
+                            unwrap = sslEngine.unwrap(netInBuffer, dsts2, 
offset, length2);
                             //compact the buffer
                             netInBuffer.compact();
                             if (unwrap.getStatus() == Status.OK || 
unwrap.getStatus() == Status.BUFFER_UNDERFLOW) {
@@ -1038,9 +1042,28 @@ public class SecureNio2Channel extends Nio2Channel  {
                                 //here we should trap BUFFER_OVERFLOW and call 
expand on the buffer
                                 //for now, throw an exception, as we 
initialized the buffers
                                 //in the constructor
-                                throw new 
IOException(sm.getString("channel.nio.ssl.unwrapFail", unwrap.getStatus()));
+                                ByteBuffer readBuffer = 
getBufHandler().getReadBuffer();
+                                boolean found = false;
+                                for (ByteBuffer buffer : dsts2) {
+                                    if (buffer == readBuffer) {
+                                        found = true;
+                                    }
+                                }
+                                if (found) {
+                                    throw new 
IOException(sm.getString("channel.nio.ssl.unwrapFail", unwrap.getStatus()));
+                                } else {
+                                    // Add the main read buffer in the 
destinations and try again
+                                    dsts2 = new ByteBuffer[dsts.length + 1];
+                                    for (int i = 0; i < dsts.length; i++) {
+                                        dsts2[i] = dsts[i];
+                                    }
+                                    dsts2[dsts.length] = readBuffer;
+                                    length2 = length + 1;
+                                    
getBufHandler().configureReadBufferForWrite();
+                                    processOverflow = true;
+                                }
                             }
-                        } while (netInBuffer.position() != 0); //continue to 
unwrapping as long as the input buffer has stuff
+                        } while ((netInBuffer.position() != 0) || 
processOverflow); //continue to unwrapping as long as the input buffer has stuff
                         int capacity = 0;
                         final int endOffset = offset + length;
                         for (int i = offset; i < endOffset; i++) {
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index db7a05f..3269e92 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -135,7 +135,8 @@
         currently active HTTP/2 streams. (markt)
       </fix>
       <fix>
-        Ensure enough buffer space when using TLS with NIO2 and HTTP/2. (remm)
+        Ensure enough buffer space when using TLS with NIO2 by using the main
+        read buffer to store additional decrypted data. (remm)
       </fix>
     </changelog>
   </subsection>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to