Skip to content

fix: harden gRPC HTTP/2 stream limits - #18

Merged
xxo1shine merged 1 commit into
xxo1shine:fix/discard-unknown-fields-for-p2p-messagesfrom
GuipaiQigong111:codex/fix-grpc-http2-cves-discard-unknown-fields
Jul 28, 2026
Merged

fix: harden gRPC HTTP/2 stream limits#18
xxo1shine merged 1 commit into
xxo1shine:fix/discard-unknown-fields-for-p2p-messagesfrom
GuipaiQigong111:codex/fix-grpc-http2-cves-discard-unknown-fields

Conversation

@GuipaiQigong111

@GuipaiQigong111 GuipaiQigong111 commented Jul 27, 2026

Copy link
Copy Markdown

Summary

  • upgrade grpc-java from 1.81.0 to 1.83.0
  • consume Netty 4.2.15.Final from grpc-java 1.83.0 instead of overriding Netty through a separate BOM
  • retain Netty's 4.1 pooled allocator behavior during the initial 4.2 rollout
  • enforce the configured concurrent-stream limit on grpc-java's server-side HTTP/2 connection before the client acknowledges server SETTINGS
  • use a finite default of 100 concurrent calls per connection and migrate legacy explicit 0 to that secure default
  • add real Netty handler and raw-socket RpcService regression coverage

Root cause

grpc-java constructs DefaultHttp2Connection, its encoder, and its decoder directly instead of using Netty's Http2ConnectionHandlerBuilder. It advertises SETTINGS_MAX_CONCURRENT_STREAMS, but Netty normally applies that setting to connection.remote().maxActiveStreams() only after the peer acknowledges it.

Netty's fixed builder applies the limit immediately, but grpc-java bypasses that builder. java-tron therefore installs a small plaintext protocol-negotiator wrapper that applies the same validated value before delegating handler installation:

grpcHandler.connection().remote().maxActiveStreams(maxConcurrentStreams);

The compatibility shim is tracked by grpc-java#12930 and can be removed after grpc-java performs equivalent server-side enforcement.

Dependency selection

The standalone nettyVersion and netty-bom declaration have been removed. The resolved runtime classpath contains 13 Netty modules, all at 4.2.15.Final, with no Netty 4.1.x or mixed 4.2.x versions.

Netty 4.2 split its former codec artifact into smaller modules. java-tron's backup server directly uses the protobuf frame codec, which is not a grpc-netty transitive dependency, so netty-codec-protobuf is declared explicitly at the same 4.2.15.Final version. Its protobuf-java and javanano transitives remain excluded.

The macOS/ARM64 protoc-gen-grpc-java version is aligned to 1.83.0, as required by the existing build configuration. grpc-java 1.83.0 resolves protobuf-java 3.25.9 and its corresponding dependency updates.

Netty 4.2 allocator migration

Netty 4.2 changes the default allocator from pooled to adaptive. Following Netty's staged migration guidance, both java-tron VM option files explicitly set -Dio.netty.allocator.type=pooled. The adaptive allocator can be evaluated separately with representative load and soak testing.

The gRPC version is defined once in the root Gradle extension and reused by runtime dependencies and the ARM/macOS code generator. Obsolete gRPC 1.81.0 and Netty 4.1.132.Final verification entries have been removed.

Configuration impact

node.rpc.maxConcurrentCallsPerConnection now defaults to 100.

Previous releases treated an explicit value of 0 as unlimited. This PR maps 0 to the secure default of 100 and logs a startup migration warning. Operators that require more than 100 concurrent calls on one connection must configure an explicit positive value. Negative values now fail during configuration parsing with a clear parameter error.

Validation on target branch

Passed locally after applying the change to fix/discard-unknown-fields-for-p2p-messages:

  • resolved all 13 Netty runtime modules to 4.2.15.Final
  • verified the assembled distribution contains -Dio.netty.allocator.type=pooled
  • ./gradlew :common:test --tests org.tron.core.config.args.NodeConfigTest
  • gRPC limiter and raw-socket RpcServiceHttp2SecurityTest
  • target-branch KeepAliveMessageTest and MessageUnknownFieldTest
  • ./gradlew :framework:checkstyleMain :framework:checkstyleTest :framework:assemble :protocol:assemble

The branch is one squashed commit ahead of fix/discard-unknown-fields-for-p2p-messages.

<artifact name="guava-33.6.0-jre.jar">
<sha256 value="dc573e1fca4fd5454f4a5fd3d7da2df03002876a4175bafc14a95980dd7713b3" origin="Generated by Gradle"/>
</artifact>
<artifact name="guava-33.6.0-jre.module">

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add guava:33.6.0-jre.pom sha256

@GuipaiQigong111
GuipaiQigong111 force-pushed the codex/fix-grpc-http2-cves-discard-unknown-fields branch from b4f11ec to 3fc7b23 Compare July 27, 2026 13:17

@Test
public void shouldRejectNonPositiveStreamLimit() {
assertThrows(IllegalArgumentException.class,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IllegalArgumentException exception = assertThrows(
IllegalArgumentException.class,
() -> GrpcNettyMaxConcurrentStreamsLimiter.newPlaintextNegotiator(limit));
assertEquals("maxConcurrentStreams must be positive", exception.getMessage());

Comment thread build.gradle Outdated
// https://github.com/grpc/grpc-java/pull/12319, Add support for macOS aarch64 with universal binary
// https://github.com/grpc/grpc-java/pull/11371 , 1.64.x is not supported CentOS 7.
ProtocGenVersion: isArm64 || isMac ? '1.81.0' : '1.60.0'
ProtocGenVersion: isArm64 || isMac ? '1.83.0' : '1.60.0'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gRPC version 1.83.0 is still duplicated in build.gradle and protocol/build.gradle. Define grpcVersion once in the root ext block and use it for both the runtime dependencies and ARM/macOS code generator.

Comment thread protocol/build.gradle Outdated
def protobufVersion = '3.25.8'
// keep same version as protoc-gen-grpc-java for arm64 or macOS, see rootProject.archInfo.requires.ProtocGenVersion
def grpcVersion = '1.81.0'
def grpcVersion = '1.83.0'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Netty 4.2 allocator migration has not been addressed. The upgrade implicitly changes Netty’s default allocator from pooled to adaptive, but the PR neither pins io.netty.allocator.type=pooled nor provides representative load or soak-test results for the adaptive allocator. Netty recommends retaining the pooled allocator during the initial 4.2 rollout and evaluating adaptive allocation separately. See the Netty 4.2 Migration Guide.

Comment thread gradle/verification-metadata.xml Outdated

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Obsolete verification entries remain, including gRPC 1.81.0 and Netty 4.1.132.Final. This does not affect the resolved runtime classpath, but it does not satisfy the earlier requirement to clean up expired verification metadata.

<artifact name="guava-parent-33.4.0-jre.pom">
<sha256 value="3a499ed34a0d9ee0f1bcc39230021a1cd4e2f7dd0426ab6844f585465d41dcd7" origin="Generated by Gradle"/>
</artifact>
</component>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gradle/verification-metadata.xml is missing guava-parent:33.6.0-jre.pom (and guava-33.6.0-jre.pom).
grpc-core/grpc-api 1.83.0 pull guava:33.6.0-android

@GuipaiQigong111
GuipaiQigong111 force-pushed the codex/fix-grpc-http2-cves-discard-unknown-fields branch from 3fc7b23 to ab1872f Compare July 28, 2026 03:09
@GuipaiQigong111
GuipaiQigong111 marked this pull request as ready for review July 28, 2026 03:15
@GuipaiQigong111
GuipaiQigong111 force-pushed the codex/fix-grpc-http2-cves-discard-unknown-fields branch from ab1872f to e672eb5 Compare July 28, 2026 03:40
@GuipaiQigong111
GuipaiQigong111 force-pushed the codex/fix-grpc-http2-cves-discard-unknown-fields branch from e672eb5 to 1275864 Compare July 28, 2026 03:49

@waynercheung waynercheung left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@xxo1shine
xxo1shine merged commit a78bf35 into xxo1shine:fix/discard-unknown-fields-for-p2p-messages Jul 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants