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

ptupitsyn pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new c0a134be86b IGNITE-28110 Fix buffer leak in 
ClientInboundMessageHandler on invalid message (#7733)
c0a134be86b is described below

commit c0a134be86bdf1a5cd385dc3fef82621cec28e88
Author: Pavel Tupitsyn <[email protected]>
AuthorDate: Mon Mar 9 17:19:49 2026 +0100

    IGNITE-28110 Fix buffer leak in ClientInboundMessageHandler on invalid 
message (#7733)
---
 .../ignite/client/handler/ItClientHandlerTest.java | 54 ++++++++++++++++++++++
 .../handler/ClientInboundMessageHandler.java       | 38 ++++++++-------
 2 files changed, 76 insertions(+), 16 deletions(-)

diff --git 
a/modules/client-handler/src/integrationTest/java/org/apache/ignite/client/handler/ItClientHandlerTest.java
 
b/modules/client-handler/src/integrationTest/java/org/apache/ignite/client/handler/ItClientHandlerTest.java
index 1d8a197991c..88ecf25bfa8 100644
--- 
a/modules/client-handler/src/integrationTest/java/org/apache/ignite/client/handler/ItClientHandlerTest.java
+++ 
b/modules/client-handler/src/integrationTest/java/org/apache/ignite/client/handler/ItClientHandlerTest.java
@@ -580,6 +580,60 @@ public class ItClientHandlerTest extends 
BaseIgniteAbstractTest {
         }
     }
 
+    @Test
+    void testInvalidHandshakeStateDropsConnection() throws Exception {
+        try (var sock = new Socket("127.0.0.1", serverPort)) {
+            OutputStream out = sock.getOutputStream();
+
+            // Magic: IGNI
+            out.write(MAGIC);
+
+            // Send first handshake.
+            try (var packer1 = MessagePack.newDefaultBufferPacker()) {
+                packer1.packInt(0);
+                packer1.packInt(0);
+                packer1.packInt(0);
+                packer1.packInt(7); // Size.
+
+                packer1.packInt(3); // Major
+                packer1.packInt(0); // Minor
+                packer1.packInt(0); // Patch
+
+                packer1.packInt(2); // Client type: general purpose.
+
+                packer1.packBinaryHeader(0); // Features.
+                packer1.packInt(0); // Extensions.
+
+                out.write(packer1.toByteArray());
+            }
+
+            // Second message before handshake completes.
+            // This should trigger "Unexpected message received before 
handshake completion"
+            try (var packer2 = MessagePack.newDefaultBufferPacker()) {
+                packer2.packInt(0);
+                packer2.packInt(0);
+                packer2.packInt(0);
+                packer2.packInt(7); // Size.
+
+                packer2.packInt(3); // Major
+                packer2.packInt(0); // Minor
+                packer2.packInt(0); // Patch
+
+                packer2.packInt(2); // Client type: general purpose.
+
+                packer2.packBinaryHeader(0); // Features.
+                packer2.packInt(0); // Extensions.
+
+                out.write(packer2.toByteArray());
+            }
+
+            out.flush();
+
+            // Server drops the connection due to invalid message.
+            assertThrows(IOException.class, () -> writeAndFlushLoop(sock));
+        }
+    }
+
     private static void writeAndFlushLoop(Socket socket) throws Exception {
         var stop = System.currentTimeMillis() + 5000;
         var out = socket.getOutputStream();
diff --git 
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/ClientInboundMessageHandler.java
 
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/ClientInboundMessageHandler.java
index 9d63ccd9c41..e1cb98429e8 100644
--- 
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/ClientInboundMessageHandler.java
+++ 
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/ClientInboundMessageHandler.java
@@ -421,28 +421,34 @@ public class ClientInboundMessageHandler
 
         // Each inbound handler in a pipeline has to release the received 
messages.
         var unpacker = new ClientMessageUnpacker(byteBuf);
-        metrics.bytesReceivedAdd(byteBuf.readableBytes() + 
ClientMessageCommon.HEADER_SIZE);
 
-        switch (state) {
-            case STATE_BEFORE_HANDSHAKE:
-                state = STATE_HANDSHAKE_REQUESTED;
-                
metrics.bytesReceivedAdd(ClientMessageCommon.MAGIC_BYTES.length);
-                handshake(ctx, unpacker);
+        try {
+            metrics.bytesReceivedAdd(byteBuf.readableBytes() + 
ClientMessageCommon.HEADER_SIZE);
 
-                break;
+            switch (state) {
+                case STATE_BEFORE_HANDSHAKE:
+                    state = STATE_HANDSHAKE_REQUESTED;
+                    
metrics.bytesReceivedAdd(ClientMessageCommon.MAGIC_BYTES.length);
+                    handshake(ctx, unpacker);
 
-            case STATE_HANDSHAKE_REQUESTED:
-                // Handshake is in progress, any messages are not allowed.
-                throw new IgniteException(PROTOCOL_ERR, "Unexpected message 
received before handshake completion");
+                    break;
 
-            case STATE_HANDSHAKE_RESPONSE_SENT:
-                assert clientContext != null : "Client context != null";
-                processOperation(ctx, unpacker);
+                case STATE_HANDSHAKE_REQUESTED:
+                    // Handshake is in progress, any messages are not allowed.
+                    throw new IgniteException(PROTOCOL_ERR, "Unexpected 
message received before handshake completion");
 
-                break;
+                case STATE_HANDSHAKE_RESPONSE_SENT:
+                    assert clientContext != null : "Client context != null";
+                    processOperation(ctx, unpacker);
 
-            default:
-                throw new IllegalStateException("Unexpected state: " + state);
+                    break;
+
+                default:
+                    throw new IllegalStateException("Unexpected state: " + 
state);
+            }
+        } catch (Throwable t) {
+            unpacker.close();
+            throw t;
         }
     }
 

Reply via email to