This is an automated email from the ASF dual-hosted git repository.
gavinchou pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new c757cb88053 [fix](mysql) Fix SSL unwrap infinite loop on handshake
failure (#57364)
c757cb88053 is described below
commit c757cb88053b6c6e56b9dcfb9b9a55d8ccf32e8b
Author: abmdocrt <[email protected]>
AuthorDate: Sat Nov 1 21:41:55 2025 +0800
[fix](mysql) Fix SSL unwrap infinite loop on handshake failure (#57364)
---
.../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 9edcd1c82ee..da3d251ceb5 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]