From 9e01d572cf012ddffb1c5e2b504a0db35be98c5e Mon Sep 17 00:00:00 2001 From: JinwooHwang Date: Mon, 26 Oct 2026 16:47:15 -0400 Subject: [PATCH] GEODE-10684: Make ClientProxyMembershipID read path consistent with its write path --- .../sanctionedDataSerializables.txt | 2 +- .../tier/sockets/ClientProxyMembershipID.java | 12 +++++++++++- .../sockets/ClientProxyMembershipIDTest.java | 19 +++++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/geode-core/src/integrationTest/resources/org/apache/geode/codeAnalysis/sanctionedDataSerializables.txt b/geode-core/src/integrationTest/resources/org/apache/geode/codeAnalysis/sanctionedDataSerializables.txt index 90c0cd442d30..32aec72df57c 100644 --- a/geode-core/src/integrationTest/resources/org/apache/geode/codeAnalysis/sanctionedDataSerializables.txt +++ b/geode-core/src/integrationTest/resources/org/apache/geode/codeAnalysis/sanctionedDataSerializables.txt @@ -1726,7 +1726,7 @@ fromData,1 toData,1 org/apache/geode/internal/cache/tier/sockets/ClientProxyMembershipID,2 -fromData,19 +fromData,63 toData,19 org/apache/geode/internal/cache/tier/sockets/ClientReAuthenticateMessage,2 diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ClientProxyMembershipID.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ClientProxyMembershipID.java index bae225f78722..1e83fbe7016d 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ClientProxyMembershipID.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ClientProxyMembershipID.java @@ -45,6 +45,7 @@ import org.apache.geode.internal.serialization.DeserializationContext; import org.apache.geode.internal.serialization.KnownVersion; import org.apache.geode.internal.serialization.SerializationContext; +import org.apache.geode.internal.serialization.StaticSerialization; import org.apache.geode.internal.serialization.Versioning; import org.apache.geode.logging.internal.log4j.api.LogService; import org.apache.geode.util.internal.GeodeGlossary; @@ -304,7 +305,16 @@ public void toData(final DataOutput out, final SerializationContext context) thr @Override public void fromData(final DataInput in, final DeserializationContext context) throws IOException, ClassNotFoundException { - identity = DataSerializer.readByteArray(in); + final int identityLength = StaticSerialization.readArrayLength(in); + if (identityLength > Short.MAX_VALUE) { + throw new IOException("HandShake identity length is too big"); + } + if (identityLength == -1) { + identity = null; + } else { + identity = new byte[identityLength]; + in.readFully(identity); + } uniqueId = in.readInt(); } diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/ClientProxyMembershipIDTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/ClientProxyMembershipIDTest.java index 15662d0c4a03..53652b9f251f 100644 --- a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/ClientProxyMembershipIDTest.java +++ b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/ClientProxyMembershipIDTest.java @@ -34,6 +34,7 @@ import org.apache.geode.internal.NullDataOutputStream; import org.apache.geode.internal.serialization.ByteArrayDataInput; import org.apache.geode.internal.serialization.DSCODE; +import org.apache.geode.internal.serialization.StaticSerialization; public class ClientProxyMembershipIDTest { @@ -102,6 +103,24 @@ public void readCanonicalizedReadsFixedIdForm() throws Exception { assertThat(ClientProxyMembershipID.readCanonicalized(in)).isNotNull(); } + @Test + public void fromDataRejectsIdentityLengthThatExceedsMaximum() throws IOException { + // A well-formed identity is always small: writeExternal caps it at Short.MAX_VALUE. + // fromData applies the same upper bound when reading, so the fixed-id and Externalizable + // paths agree on the maximum identity length a client may send. + final ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + final DataOutputStream out = new DataOutputStream(bytes); + out.writeByte(StaticSerialization.INT_ARRAY_LEN); + out.writeInt(Short.MAX_VALUE + 1); + out.close(); + final ByteArrayDataInput in = new ByteArrayDataInput(bytes.toByteArray()); + final ClientProxyMembershipID clientProxyMembershipID = new ClientProxyMembershipID(); + + assertThatThrownBy(() -> clientProxyMembershipID.fromData(in, null)) + .isInstanceOf(IOException.class) + .hasMessageContaining("identity length is too big"); + } + public static class ProbeObject implements Serializable { static boolean deserialized;