https://bz.apache.org/bugzilla/show_bug.cgi?id=61998
Bug ID: 61998 Summary: tomcat: dead loop in the processing of SSL handshake Product: Tomcat 8 Version: 8.5.15 Hardware: PC OS: Linux Status: NEW Severity: critical Priority: P2 Component: Util Assignee: dev@tomcat.apache.org Reporter: mycatc...@163.com Target Milestone: ---- During our https attack test, a dead loop has happened in org.apache.tomcat.util.net.SecureNioChannel#handshake. A lot of(million) packets were sent during the test so it's extremely hard to find which one caused the problem. The dead loop didn't stop even after we had stopped the test. I've debugged tomcat using jdb. The results are as follows. while (!handshakeComplete) { switch ( handshakeStatus ) { //handshakeStatus = NEED_UNWRAP //... case NEED_UNWRAP: { //perform the unwrap function handshake = handshakeUnwrap(read); //handshake.getStatus() = Status.BUFFER_OVERFLOW if ( handshake.getStatus() == Status.OK ) { if (handshakeStatus == HandshakeStatus.NEED_TASK) handshakeStatus = tasks(); } else if ( handshake.getStatus() == Status.BUFFER_UNDERFLOW ){ //read more data, reregister for OP_READ return SelectionKey.OP_READ; } else if (handshake.getStatus() == Status.BUFFER_OVERFLOW) { getBufHandler().configureReadBufferForWrite(); } else { throw new IOException(sm.getString("channel.nio.ssl.unexpectedStatusDuringWrap", handshakeStatus)); }//switch break; } case NEED_TASK: { handshakeStatus = tasks(); break; } default: throw new IllegalStateException(sm.getString("channel.nio.ssl.invalidStatus", handshakeStatus)); } } protected SSLEngineResult handshakeUnwrap(boolean doread) throws IOException { if (netInBuffer.position() == netInBuffer.limit()) { //clear the buffer if we have emptied it out on data netInBuffer.clear(); } /** Value of netInBuffer here. https-jsse-nio-20000-exec-38[1] dump netInBuffer netInBuffer = { java.nio.ByteBuffer.hb: instance of byte[16921] (id=9332) java.nio.ByteBuffer.offset: 0 java.nio.ByteBuffer.isReadOnly: false java.nio.ByteBuffer.bigEndian: true java.nio.ByteBuffer.nativeByteOrder: false java.nio.Buffer.SPLITERATOR_CHARACTERISTICS: 16464 java.nio.Buffer.mark: -1 java.nio.Buffer.position: 16 java.nio.Buffer.limit: 16921 java.nio.Buffer.capacity: 16921 java.nio.Buffer.address: 0 } * / if ( doread ) { //if we have data to read, read it int read = sc.read(netInBuffer); //read = 0 if (read == -1) throw new IOException(sm.getString("channel.nio.ssl.eofDuringHandshake")); } SSLEngineResult result; boolean cont = false; //loop while we can perform pure SSLEngine data do { //prepare the buffer with the incoming data netInBuffer.flip(); //call unwrap getBufHandler().configureReadBufferForWrite(); result = sslEngine.unwrap(netInBuffer, getBufHandler().getReadBuffer()); //result: "Status = BUFFER_OVERFLOW HandshakeStatus = NEED_UNWRAP bytesConsumed = 0 bytesProduced = 0" //compact the buffer, this is an optional method, wonder what would happen if we didn't netInBuffer.compact(); //read in the status handshakeStatus = result.getHandshakeStatus(); if ( result.getStatus() == SSLEngineResult.Status.OK && result.getHandshakeStatus() == HandshakeStatus.NEED_TASK ) { //execute tasks if we need to handshakeStatus = tasks(); } //perform another unwrap? cont = result.getStatus() == SSLEngineResult.Status.OK && handshakeStatus == HandshakeStatus.NEED_UNWRAP; }while ( cont ); return result; } Since sc.read(netInBuffer) returns 0, I'm wondering configuring timeout, keepalive or something else to avoid the problem. I'd appreciated if you can confirm if there is a bug or have any suggestions to avoid the problem. Thanks a lot. -- You are receiving this mail because: You are the assignee for the bug. --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org