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

morrysnow pushed a commit to branch branch-3.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-3.1 by this push:
     new 39ee46938cc branch-3.1: [fix](mysql) Fix SSL unwrap infinite loop on 
handshake failure #57364 (#57599)
39ee46938cc is described below

commit 39ee46938cc83a8a5579af22323413576daf8cf5
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Mon Nov 3 11:32:59 2025 +0800

    branch-3.1: [fix](mysql) Fix SSL unwrap infinite loop on handshake failure 
#57364 (#57599)
    
    Cherry-picked from #57364
    
    Co-authored-by: abmdocrt <[email protected]>
---
 .../java/org/apache/doris/mysql/MysqlChannel.java  |  6 +-
 .../org/apache/doris/mysql/MysqlSslContext.java    |  7 +-
 .../org/apache/doris/mysql/SslEngineHelper.java    | 75 ++++++++++++++++++++++
 3 files changed, 81 insertions(+), 7 deletions(-)

diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/MysqlChannel.java 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/MysqlChannel.java
index 34494aa4296..87a9ac83d88 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/mysql/MysqlChannel.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/MysqlChannel.java
@@ -597,7 +597,7 @@ public class MysqlChannel implements BytesChannel {
             case OK:
                 return true;
             case CLOSED:
-                sslEngine.closeOutbound();
+                SslEngineHelper.checkClosedProgress("wrap", sslEngineResult, 
sslEngine, false);
                 return true;
             case BUFFER_OVERFLOW:
                 // Could attempt to drain the serverNetData buffer of any 
already obtained
@@ -615,13 +615,13 @@ public class MysqlChannel implements BytesChannel {
         }
     }
 
-    private boolean handleUnwrapResult(SSLEngineResult sslEngineResult) {
+    private boolean handleUnwrapResult(SSLEngineResult sslEngineResult) throws 
SSLException {
         switch (sslEngineResult.getStatus()) {
             // normal status.
             case OK:
                 return true;
             case CLOSED:
-                sslEngine.closeOutbound();
+                SslEngineHelper.checkClosedProgress("unwrap", sslEngineResult, 
sslEngine, true);
                 return true;
             case BUFFER_OVERFLOW:
                 // Could attempt to drain the clientAppData buffer of any 
already obtained
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/MysqlSslContext.java 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/MysqlSslContext.java
index b59b493ceaf..6283e795cfe 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/mysql/MysqlSslContext.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/MysqlSslContext.java
@@ -227,14 +227,13 @@ public class MysqlSslContext {
         }
     }
 
-
     private boolean handleWrapResult(SSLEngineResult sslEngineResult) throws 
SSLException {
         switch (sslEngineResult.getStatus()) {
             // normal status.
             case OK:
                 return true;
             case CLOSED:
-                sslEngine.closeOutbound();
+                SslEngineHelper.checkClosedProgress("wrap", sslEngineResult, 
sslEngine, false);
                 return true;
             case BUFFER_OVERFLOW:
                 // Could attempt to drain the serverNetData buffer of any 
already obtained
@@ -252,13 +251,13 @@ public class MysqlSslContext {
         }
     }
 
-    private boolean handleUnwrapResult(SSLEngineResult sslEngineResult) {
+    private boolean handleUnwrapResult(SSLEngineResult sslEngineResult) throws 
SSLException {
         switch (sslEngineResult.getStatus()) {
             // normal status.
             case OK:
                 return true;
             case CLOSED:
-                sslEngine.closeOutbound();
+                SslEngineHelper.checkClosedProgress("unwrap", sslEngineResult, 
sslEngine, true);
                 return true;
             case BUFFER_OVERFLOW:
                 // Could attempt to drain the clientAppData buffer of any 
already obtained
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/SslEngineHelper.java 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/SslEngineHelper.java
new file mode 100644
index 00000000000..816088d1f2a
--- /dev/null
+++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/SslEngineHelper.java
@@ -0,0 +1,75 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.mysql;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLException;
+
+/**
+ * Helper class for SSL engine operations.
+ */
+public class SslEngineHelper {
+    private static final Logger LOG = 
LogManager.getLogger(SslEngineHelper.class);
+
+    /**
+     * Check if SSL engine operation has made progress when closed.
+     * @param operation operation name for logging ("wrap" or "unwrap")
+     * @param sslEngineResult the SSL engine result to check
+     * @param sslEngine the SSL engine instance
+     * @param closeInbound whether to close inbound (true for unwrap, false 
for wrap)
+     * @throws SSLException if no progress was made
+     */
+    public static void checkClosedProgress(String operation, SSLEngineResult 
sslEngineResult,
+                                           SSLEngine sslEngine, boolean 
closeInbound) throws SSLException {
+        int consumed = sslEngineResult.bytesConsumed();
+        int produced = sslEngineResult.bytesProduced();
+        if (consumed == 0 && produced == 0) {
+            LOG.warn("SSLEngine {} closed with no progress. status={}, 
handshake={}, "
+                    + "bytesConsumed={}, bytesProduced={}", operation,
+                    sslEngineResult.getStatus(), 
sslEngineResult.getHandshakeStatus(),
+                    consumed, produced);
+            if (closeInbound) {
+                try {
+                    sslEngine.closeInbound();
+                } catch (SSLException e) {
+                    LOG.warn("Error when closing SSL inbound during " + 
operation, e);
+                }
+            }
+            sslEngine.closeOutbound();
+            throw new SSLException("SSL " + operation + " closed with no 
progress (handshakeStatus="
+                    + sslEngineResult.getHandshakeStatus() + ", bytesConsumed="
+                    + consumed + ", bytesProduced=" + produced + ")");
+        }
+        if (closeInbound) {
+            try {
+                sslEngine.closeInbound();
+            } catch (SSLException e) {
+                LOG.debug("closeInbound on normal " + operation + " close 
failed", e);
+            }
+        }
+        LOG.debug("SSLEngine {} closed normally. status={}, handshake={}, "
+                + "bytesConsumed={}, bytesProduced={}", operation,
+                sslEngineResult.getStatus(), 
sslEngineResult.getHandshakeStatus(),
+                consumed, produced);
+        sslEngine.closeOutbound();
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to