From 7eb1570339b3756bc1863f33af0054d53e362da2 Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Tue, 18 Aug 2026 14:31:54 +0800 Subject: [PATCH 1/2] chore(deps): upgrade grpc-java from 1.83.0 to 1.83.1 1. bump grpcVersion to 1.83.1 to pick up the upstream fix for grpc/grpc-java#12930 (PR grpc/grpc-java#12942), which enforces connection.remote().maxActiveStreams(maxStreams) at handler startup 2. drop GrpcNettyMaxConcurrentStreamsLimiter, the local protocol-negotiator shim that applied the same limit while 1.83.0 left the remote endpoint unbounded until the client acknowledged SETTINGS 3. set maxConcurrentCallsPerConnection directly on NettyServerBuilder in RpcService, as it was done before the shim 4. move shouldIgnoreClientMaxHeaderListSizeOnServer from the deleted shim test into NettyHttp2HeaderSecurityTest, since it guards netty CVE-2026-50560 rather than the shim 5. update the io.grpc checksums in gradle/verification-metadata.xml 6. keep RpcServiceHttp2SecurityTest as the regression guard: it fails on 1.83.0 without the shim and passes on 1.83.1 --- build.gradle | 2 +- .../GrpcNettyMaxConcurrentStreamsLimiter.java | 79 ------------- .../tron/common/application/RpcService.java | 3 +- ...cNettyMaxConcurrentStreamsLimiterTest.java | 108 ------------------ .../NettyHttp2HeaderSecurityTest.java | 53 +++++++++ gradle/verification-metadata.xml | 108 +++++++++--------- 6 files changed, 109 insertions(+), 244 deletions(-) delete mode 100644 framework/src/main/java/org/tron/common/application/GrpcNettyMaxConcurrentStreamsLimiter.java delete mode 100644 framework/src/test/java/org/tron/common/application/GrpcNettyMaxConcurrentStreamsLimiterTest.java create mode 100644 framework/src/test/java/org/tron/common/application/NettyHttp2HeaderSecurityTest.java diff --git a/build.gradle b/build.gradle index 65e72c0fb73..06186778971 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ plugins { } ext { - grpcVersion = "1.83.0" + grpcVersion = "1.83.1" } allprojects { diff --git a/framework/src/main/java/org/tron/common/application/GrpcNettyMaxConcurrentStreamsLimiter.java b/framework/src/main/java/org/tron/common/application/GrpcNettyMaxConcurrentStreamsLimiter.java deleted file mode 100644 index cdd71ffee3c..00000000000 --- a/framework/src/main/java/org/tron/common/application/GrpcNettyMaxConcurrentStreamsLimiter.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * java-tron is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * java-tron is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with java-tron. If not, see . - */ - -package org.tron.common.application; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import io.grpc.netty.GrpcHttp2ConnectionHandler; -import io.grpc.netty.InternalProtocolNegotiator; -import io.grpc.netty.InternalProtocolNegotiators; -import io.grpc.netty.NettyServerBuilder; -import io.netty.channel.ChannelHandler; -import io.netty.util.AsciiString; - -/** Enforces the advertised HTTP/2 concurrent stream limit for grpc-netty servers. */ -final class GrpcNettyMaxConcurrentStreamsLimiter { - - private GrpcNettyMaxConcurrentStreamsLimiter() { - } - - static NettyServerBuilder configurePlaintext( - NettyServerBuilder builder, int maxConcurrentStreams) { - checkNotNull(builder, "builder"); - checkArgument(maxConcurrentStreams > 0, "maxConcurrentStreams must be positive"); - builder.maxConcurrentCallsPerConnection(maxConcurrentStreams); - // TODO: Remove this shim after https://github.com/grpc/grpc-java/issues/12930 is fixed. - return builder.protocolNegotiator(newPlaintextNegotiator(maxConcurrentStreams)); - } - - static InternalProtocolNegotiator.ProtocolNegotiator newPlaintextNegotiator( - int maxConcurrentStreams) { - checkArgument(maxConcurrentStreams > 0, "maxConcurrentStreams must be positive"); - return new EnforcingProtocolNegotiator( - InternalProtocolNegotiators.serverPlaintext(), maxConcurrentStreams); - } - - private static final class EnforcingProtocolNegotiator - implements InternalProtocolNegotiator.ProtocolNegotiator { - - private final InternalProtocolNegotiator.ProtocolNegotiator delegate; - private final int maxConcurrentStreams; - - private EnforcingProtocolNegotiator( - InternalProtocolNegotiator.ProtocolNegotiator delegate, int maxConcurrentStreams) { - this.delegate = checkNotNull(delegate, "delegate"); - this.maxConcurrentStreams = maxConcurrentStreams; - } - - @Override - public AsciiString scheme() { - return delegate.scheme(); - } - - @Override - public ChannelHandler newHandler(GrpcHttp2ConnectionHandler grpcHandler) { - // grpc-java builds the connection directly, bypassing Netty's builder-side enforcement. - grpcHandler.connection().remote().maxActiveStreams(maxConcurrentStreams); - return delegate.newHandler(grpcHandler); - } - - @Override - public void close() { - delegate.close(); - } - } -} diff --git a/framework/src/main/java/org/tron/common/application/RpcService.java b/framework/src/main/java/org/tron/common/application/RpcService.java index 27fcc479f4e..c398b71ae41 100644 --- a/framework/src/main/java/org/tron/common/application/RpcService.java +++ b/framework/src/main/java/org/tron/common/application/RpcService.java @@ -100,9 +100,8 @@ protected NettyServerBuilder initServerBuilder() { serverBuilder = serverBuilder.executor(this.executorService); } // Set configs from config.conf or default value - serverBuilder = GrpcNettyMaxConcurrentStreamsLimiter.configurePlaintext( - serverBuilder, parameter.getMaxConcurrentCallsPerConnection()); serverBuilder + .maxConcurrentCallsPerConnection(parameter.getMaxConcurrentCallsPerConnection()) .flowControlWindow(parameter.getFlowControlWindow()) .maxConnectionIdle(parameter.getMaxConnectionIdleInMillis(), TimeUnit.MILLISECONDS) .maxConnectionAge(parameter.getMaxConnectionAgeInMillis(), TimeUnit.MILLISECONDS) diff --git a/framework/src/test/java/org/tron/common/application/GrpcNettyMaxConcurrentStreamsLimiterTest.java b/framework/src/test/java/org/tron/common/application/GrpcNettyMaxConcurrentStreamsLimiterTest.java deleted file mode 100644 index fc578ca7947..00000000000 --- a/framework/src/test/java/org/tron/common/application/GrpcNettyMaxConcurrentStreamsLimiterTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * java-tron is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * java-tron is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with java-tron. If not, see . - */ - -package org.tron.common.application; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThrows; - -import io.grpc.ChannelLogger; -import io.grpc.ChannelLogger.ChannelLogLevel; -import io.grpc.netty.GrpcHttp2ConnectionHandler; -import io.grpc.netty.InternalProtocolNegotiator; -import io.netty.channel.ChannelHandler; -import io.netty.handler.codec.http2.DefaultHttp2Connection; -import io.netty.handler.codec.http2.DefaultHttp2ConnectionDecoder; -import io.netty.handler.codec.http2.DefaultHttp2ConnectionEncoder; -import io.netty.handler.codec.http2.DefaultHttp2FrameReader; -import io.netty.handler.codec.http2.DefaultHttp2FrameWriter; -import io.netty.handler.codec.http2.Http2Connection; -import io.netty.handler.codec.http2.Http2ConnectionDecoder; -import io.netty.handler.codec.http2.Http2ConnectionEncoder; -import io.netty.handler.codec.http2.Http2Error; -import io.netty.handler.codec.http2.Http2Exception; -import io.netty.handler.codec.http2.Http2FrameWriter; -import io.netty.handler.codec.http2.Http2Settings; -import org.junit.Test; - -public class GrpcNettyMaxConcurrentStreamsLimiterTest { - - private static final ChannelLogger NOOP_LOGGER = new ChannelLogger() { - @Override - public void log(ChannelLogLevel level, String message) { - } - - @Override - public void log(ChannelLogLevel level, String messageFormat, Object... args) { - } - }; - - @Test - public void shouldEnforceMaxStreamsBeforeSettingsAck() throws Exception { - Http2Connection connection = new DefaultHttp2Connection(true); - GrpcHttp2ConnectionHandler grpcHandler = newGrpcHandler(connection); - InternalProtocolNegotiator.ProtocolNegotiator negotiator = - GrpcNettyMaxConcurrentStreamsLimiter.newPlaintextNegotiator(2); - - ChannelHandler negotiationHandler = negotiator.newHandler(grpcHandler); - - assertNotNull(negotiationHandler); - assertEquals(2, connection.remote().maxActiveStreams()); - connection.remote().createStream(1, true); - connection.remote().createStream(3, true); - Http2Exception exception = assertThrows( - Http2Exception.class, () -> connection.remote().createStream(5, true)); - assertEquals(Http2Error.REFUSED_STREAM, exception.error()); - negotiator.close(); - } - - @Test - public void shouldIgnoreClientMaxHeaderListSizeOnServer() throws Exception { - Http2Connection connection = new DefaultHttp2Connection(true); - Http2FrameWriter frameWriter = new DefaultHttp2FrameWriter(); - Http2ConnectionEncoder encoder = - new DefaultHttp2ConnectionEncoder(connection, frameWriter); - long originalMaxHeaderListSize = - encoder.configuration().headersConfiguration().maxHeaderListSize(); - - encoder.remoteSettings(new Http2Settings().maxHeaderListSize(1)); - - assertEquals(originalMaxHeaderListSize, - encoder.configuration().headersConfiguration().maxHeaderListSize()); - encoder.close(); - } - - @Test - public void shouldRejectNonPositiveStreamLimit() { - IllegalArgumentException zeroLimitException = assertThrows(IllegalArgumentException.class, - () -> GrpcNettyMaxConcurrentStreamsLimiter.newPlaintextNegotiator(0)); - assertEquals("maxConcurrentStreams must be positive", zeroLimitException.getMessage()); - IllegalArgumentException negativeLimitException = assertThrows(IllegalArgumentException.class, - () -> GrpcNettyMaxConcurrentStreamsLimiter.newPlaintextNegotiator(-1)); - assertEquals("maxConcurrentStreams must be positive", negativeLimitException.getMessage()); - } - - private static GrpcHttp2ConnectionHandler newGrpcHandler(Http2Connection connection) { - Http2FrameWriter frameWriter = new DefaultHttp2FrameWriter(); - Http2ConnectionEncoder encoder = - new DefaultHttp2ConnectionEncoder(connection, frameWriter); - Http2ConnectionDecoder decoder = new DefaultHttp2ConnectionDecoder( - connection, encoder, new DefaultHttp2FrameReader()); - return new GrpcHttp2ConnectionHandler( - null, decoder, encoder, new Http2Settings(), NOOP_LOGGER) { - }; - } -} diff --git a/framework/src/test/java/org/tron/common/application/NettyHttp2HeaderSecurityTest.java b/framework/src/test/java/org/tron/common/application/NettyHttp2HeaderSecurityTest.java new file mode 100644 index 00000000000..6a4f4330f04 --- /dev/null +++ b/framework/src/test/java/org/tron/common/application/NettyHttp2HeaderSecurityTest.java @@ -0,0 +1,53 @@ +/* + * java-tron is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * java-tron is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with java-tron. If not, see . + */ + +package org.tron.common.application; + +import static org.junit.Assert.assertEquals; + +import io.netty.handler.codec.http2.DefaultHttp2Connection; +import io.netty.handler.codec.http2.DefaultHttp2ConnectionEncoder; +import io.netty.handler.codec.http2.DefaultHttp2FrameWriter; +import io.netty.handler.codec.http2.Http2Connection; +import io.netty.handler.codec.http2.Http2ConnectionEncoder; +import io.netty.handler.codec.http2.Http2FrameWriter; +import io.netty.handler.codec.http2.Http2Settings; +import org.junit.Test; + +/** Guards the netty HTTP/2 header-size behaviour the gRPC server relies on. */ +public class NettyHttp2HeaderSecurityTest { + + /** + * CVE-2026-50560: SETTINGS_MAX_HEADER_LIST_SIZE tells the server what the client is willing to + * receive, so it must not shrink the server encoder's own limit. Otherwise a hostile client can + * advertise a tiny value and make every response-header write throw, which is a Rapid-Reset-like + * denial of service. Netty enforced the client value before 4.1.135.Final / 4.2.15.Final. + */ + @Test + public void shouldIgnoreClientMaxHeaderListSizeOnServer() throws Exception { + Http2Connection connection = new DefaultHttp2Connection(true); + Http2FrameWriter frameWriter = new DefaultHttp2FrameWriter(); + Http2ConnectionEncoder encoder = + new DefaultHttp2ConnectionEncoder(connection, frameWriter); + long originalMaxHeaderListSize = + encoder.configuration().headersConfiguration().maxHeaderListSize(); + + encoder.remoteSettings(new Http2Settings().maxHeaderListSize(1)); + + assertEquals(originalMaxHeaderListSize, + encoder.configuration().headersConfiguration().maxHeaderListSize()); + encoder.close(); + } +} diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 6a3e641d5d6..7ee11e51920 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -1171,76 +1171,76 @@ - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + @@ -1251,18 +1251,18 @@ - - - + + + - - + + - - + + - - + + From ce055d6ee546231c63d7b6b6fd9ad56b859c092a Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Tue, 18 Aug 2026 14:45:33 +0800 Subject: [PATCH 2/2] chore(deps): upgrade jackson from 2.18.6 to 2.18.10 1. bump jackson-databind in :common to 2.18.10 and let jackson-annotations, jackson-core and jackson-bom follow it transitively 2. update the jackson checksums in gradle/verification-metadata.xml 3. leave jackson-parent at 2.18.4, which jackson-bom 2.18.10 still declares as its parent 4. reword the jackson-databind#3627 comment to say why it is there: avoid x.y.z.w micro-patches, they may ship broken Gradle module metadata --- common/build.gradle | 4 ++- gradle/verification-metadata.xml | 54 ++++++++++++++++---------------- 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/common/build.gradle b/common/build.gradle index 14d3eb4e637..4b36d067b70 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -8,7 +8,9 @@ sourceCompatibility = 1.8 dependencies { - api group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.18.6' // https://github.com/FasterXML/jackson-databind/issues/3627 + // avoid x.y.z.w micro-patches, they may ship broken Gradle module metadata: + // https://github.com/FasterXML/jackson-databind/issues/3627 + api group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.18.10' api "com.cedarsoftware:java-util:3.2.0" api group: 'org.apache.httpcomponents', name: 'httpasyncclient', version: '4.1.1' api group: 'commons-codec', name: 'commons-codec', version: '1.11' diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 7ee11e51920..08c7f6d34b9 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -189,9 +189,9 @@ - - - + + + @@ -199,9 +199,9 @@ - - - + + + @@ -219,15 +219,15 @@ - - - + + + - - + + - - + + @@ -235,15 +235,15 @@ - - - + + + - - + + - - + + @@ -251,15 +251,15 @@ - - - + + + - - + + - - + +