Fix MQTT decoder size check after variable header replay#16787
Conversation
chrisvest
left a comment
There was a problem hiding this comment.
Just one small comment, otherwise looks good.
| int followingPingReqPackets = 3; | ||
| EmbeddedChannel channel = new EmbeddedChannel(new MqttDecoder(maxBytesInMessage)); | ||
| ByteBuf byteBuf = ALLOCATOR.buffer(); | ||
| byteBuf.writeByte(0x30); |
There was a problem hiding this comment.
None of the other tests directly encode MQTT messages. Please add some comments describing what's going on, so one can read this without having the MQTT standard at hand.
There was a problem hiding this comment.
Pushed 4a91a65 with byte-level annotations on both tests: every writeByte/writeShort now spells out the MQTT field it represents (PUBLISH fixed header, remaining-length Variable Byte Integer, topic-name length prefix, PINGREQ packets), and each test opens with a note on why the packets are hand-crafted rather than routed through MqttEncoder. PTAL.
|
@daguimu Please look at my review comment. |
Address review feedback on netty#16787: explain each writeByte / writeShort with the MQTT field it represents (PUBLISH fixed header, remaining-length VBI, topic-name length prefix, PINGREQ packets) so the tests can be read without the MQTT spec at hand. Also add a header comment on each test noting why the packets are hand-crafted instead of using MqttEncoder (the bug under test requires malformed packets that the encoder will not produce). No behavior change.
|
@chrisvest Sorry for the delay — addressed your review comment in 4a91a65 (also responded in-thread). Each |
|
Is there any chance this could get merged and included in a new release ASAP? Anybody using the MQTT codec can't upgrade to the most recent release which means they can't get the latest security fixes. |
|
Auto-port PR for 4.1: #16838 |
|
Auto-port PR for 5.0: #16839 |
|
@jbertram Yeah, I will do a release later today. |
|
@chrisvest, many thanks! |
…ay (#16838) Auto-port of #16787 to 4.1 Cherry-picked commit: 72df658 --- ## Problem The MQTT decoder can reject valid packets after the CVE-2026-44248 fix when several MQTT packets are present in the same cumulation buffer. If the current packet's variable header needs a replay, the decoder compares the total readable bytes in the buffer against `maxBytesInMessage`, so later packets can make the current in-limit packet look too large. ## Root Cause `READ_VARIABLE_HEADER` recorded `buffer.readableBytes()` before decoding the variable header. That value is the cumulation's total readable bytes, not the current MQTT packet's declared remaining length. When `decodeVariableHeader` throws `Signal.REPLAY`, the too-large decision must be based on `bytesRemainingBeforeVariableHeader` for the current packet. ## Fix - Use `bytesRemainingBeforeVariableHeader` when deciding whether to swallow `Signal.REPLAY` and raise `TooLongFrameException`. - Continue replaying when the current packet is within `maxBytesInMessage`, even if the cumulation contains additional bytes for following packets. ## Tests Added | Change Point | Test | |-------------|------| | Variable-header replay uses the current packet size instead of total cumulation bytes for the too-long check | `testPublishMessageIncompleteVariableHeaderDoesNotUseCumulationSizeForTooLongCheck()` verifies an incomplete in-limit PUBLISH variable header with extra cumulated PINGREQ packets does not emit an invalid message | | Oversized current packets still fail during variable-header replay | `testPublishMessageIncompleteVariableHeaderStillFailsWhenCurrentPacketTooLarge()` verifies an incomplete PUBLISH whose own remaining length exceeds `maxBytesInMessage` still emits a `TooLongFrameException` | ## Impact This restores decoding for valid in-limit MQTT packets batched in the same buffer while preserving the CVE fix: packets whose declared remaining length exceeds `maxBytesInMessage` still fail with `TooLongFrameException` even if variable-header decoding requests replay. Fixes #16776 Co-authored-by: Guimu <30684111+daguimu@users.noreply.github.com>
…ip ci] Bumps `netty.version` from 4.2.13.Final to 4.2.14.Final. Updates `io.netty:netty-transport` from 4.2.13.Final to 4.2.14.Final Release notes *Sourced from [io.netty:netty-transport's releases](https://github.com/netty/netty/releases).* > netty-4.2.14.Final > ------------------ > > What's Changed > -------------- > > * HTTP: Fix revapi failure introduced by 84530fa81e12dcd1d42310bb20c1385cb44128d8 by [`@normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16748](https://redirect.github.com/netty/netty/pull/16748) > * HTTP: Re-add constructor to HttpProxyHandler that was removed by mistake by [`@normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16747](https://redirect.github.com/netty/netty/pull/16747) > * Marshalling: Explicit document security requirements by [`@normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16752](https://redirect.github.com/netty/netty/pull/16752) > * Fix io\_uring op completion TRACE logging by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16755](https://redirect.github.com/netty/netty/pull/16755) > * Quic: Ensure writes are done before notify close promise of QuicheQui… by [`@normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16758](https://redirect.github.com/netty/netty/pull/16758) > * Avoid re-parsing openssl key material with non-cached provider by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16759](https://redirect.github.com/netty/netty/pull/16759) > * Pin HTTP/RTSP version + method normalization to Locale.US by [`@daguimu`](https://github.com/daguimu) in [netty/netty#16765](https://redirect.github.com/netty/netty/pull/16765) > * Fill MsgHdrMemoryArray#hdrs with null entry on release by [`@tsegismont`](https://github.com/tsegismont) in [netty/netty#16764](https://redirect.github.com/netty/netty/pull/16764) > * Revapi: Use default "oldVersion" by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16774](https://redirect.github.com/netty/netty/pull/16774) > * Adaptive: Fix concurrency issue in adaptive allocator by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16767](https://redirect.github.com/netty/netty/pull/16767) > * Auto-port 4.2: Make bulk byte moving in ByteBuf faster by [`@netty-project-bot`](https://github.com/netty-project-bot) in [netty/netty#16781](https://redirect.github.com/netty/netty/pull/16781) > * Pin multipart Content-Type / Content-Transfer-Encoding case folding to Locale.US by [`@daguimu`](https://github.com/daguimu) in [netty/netty#16768](https://redirect.github.com/netty/netty/pull/16768) > * Remove dead native declarations by [`@pandareen`](https://github.com/pandareen) in [netty/netty#16783](https://redirect.github.com/netty/netty/pull/16783) > * Isolate tests that modify available Security providers by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16793](https://redirect.github.com/netty/netty/pull/16793) > * Remove test annotations from a method that isn't a test by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16792](https://redirect.github.com/netty/netty/pull/16792) > * Enable OpenSslCachingKeyMaterialProvider to evict stale entries after cert rotation by [`@zhangweikop`](https://github.com/zhangweikop) in [netty/netty#16523](https://redirect.github.com/netty/netty/pull/16523) > * IoUring: extend user data from short to long by [`@dreamlike-ocean`](https://github.com/dreamlike-ocean) in [netty/netty#16682](https://redirect.github.com/netty/netty/pull/16682) > * Revert CompositeByteBuf component search fast path by [`@yawkat`](https://github.com/yawkat) in [netty/netty#16811](https://redirect.github.com/netty/netty/pull/16811) > * HTTP2: Use 100 as default max concurrent streams setting by [`@normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16804](https://redirect.github.com/netty/netty/pull/16804) > * Fix ResumptionController wrapping by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16815](https://redirect.github.com/netty/netty/pull/16815) > * Resolve all localhost addresses without querying DNS servers by [`@JulianVennen`](https://github.com/JulianVennen) in [netty/netty#16749](https://redirect.github.com/netty/netty/pull/16749) > * IpFilter: Fix ClassCastException caused by IpSubnetFilter if only ipv6 rules are configured but remote peer is using ipv4 by [`@normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16803](https://redirect.github.com/netty/netty/pull/16803) > * Fix memoryAddress() for direct ByteBuffers wrapped by Unpooled without Unsafe by [`@dreamlike-ocean`](https://github.com/dreamlike-ocean) in [netty/netty#16788](https://redirect.github.com/netty/netty/pull/16788) > * Route synchronous onLookupComplete exceptions via fireExceptionCaught by [`@kwondh5217`](https://github.com/kwondh5217) in [netty/netty#16794](https://redirect.github.com/netty/netty/pull/16794) > * IoUring: Stop generic FileRegion drain loop when transferred() reaches count() by [`@LuciferYang`](https://github.com/LuciferYang) in [netty/netty#16826](https://redirect.github.com/netty/netty/pull/16826) > * MQTT: Allow MQTT 5 CONNECT with password only by [`@shblue21`](https://github.com/shblue21) in [netty/netty#16833](https://redirect.github.com/netty/netty/pull/16833) > * Fix MQTT decoder size check after variable header replay by [`@daguimu`](https://github.com/daguimu) in [netty/netty#16787](https://redirect.github.com/netty/netty/pull/16787) > > New Contributors > ---------------- > > * [`@pandareen`](https://github.com/pandareen) made their first contribution in [netty/netty#16783](https://redirect.github.com/netty/netty/pull/16783) > * [`@zhangweikop`](https://github.com/zhangweikop) made their first contribution in [netty/netty#16523](https://redirect.github.com/netty/netty/pull/16523) > * [`@JulianVennen`](https://github.com/JulianVennen) made their first contribution in [netty/netty#16749](https://redirect.github.com/netty/netty/pull/16749) > * [`@kwondh5217`](https://github.com/kwondh5217) made their first contribution in [netty/netty#16794](https://redirect.github.com/netty/netty/pull/16794) > * [`@shblue21`](https://github.com/shblue21) made their first contribution in [netty/netty#16833](https://redirect.github.com/netty/netty/pull/16833) > > **Full Changelog**: <netty/netty@netty-4.2.13.Final...netty-4.2.14.Final> Commits * [`0a60b75`](netty/netty@0a60b75) [maven-release-plugin] prepare release netty-4.2.14.Final * [`72df658`](netty/netty@72df658) Fix MQTT decoder size check after variable header replay ([#16787](https://redirect.github.com/netty/netty/issues/16787)) * [`7125dba`](netty/netty@7125dba) MQTT: Allow MQTT 5 CONNECT with password only ([#16833](https://redirect.github.com/netty/netty/issues/16833)) * [`9e19320`](netty/netty@9e19320) IoUring: Stop generic FileRegion drain loop when transferred() reaches count(... * [`4ce9f17`](netty/netty@4ce9f17) Route synchronous onLookupComplete exceptions via fireExceptionCaught ([#16794](https://redirect.github.com/netty/netty/issues/16794)) * [`f7b1b7d`](netty/netty@f7b1b7d) Fix memoryAddress() for direct ByteBuffers wrapped by Unpooled without Unsafe... * [`0ccb265`](netty/netty@0ccb265) IpFilter: Fix ClassCastException caused by IpSubnetFilter if only ipv6 rules ... * [`a6aeb6d`](netty/netty@a6aeb6d) Resolve all localhost addresses without querying DNS servers ([#16749](https://redirect.github.com/netty/netty/issues/16749)) * [`c328ba2`](netty/netty@c328ba2) Fix ResumptionController wrapping ([#16815](https://redirect.github.com/netty/netty/issues/16815)) * [`bc5862b`](netty/netty@bc5862b) HTTP2: Use 100 as default max concurrent streams setting ([#16804](https://redirect.github.com/netty/netty/issues/16804)) * Additional commits viewable in [compare view](netty/netty@netty-4.2.13.Final...netty-4.2.14.Final) Updates `io.netty:netty-codec` from 4.2.13.Final to 4.2.14.Final Release notes *Sourced from [io.netty:netty-codec's releases](https://github.com/netty/netty/releases).* > netty-4.2.14.Final > ------------------ > > What's Changed > -------------- > > * HTTP: Fix revapi failure introduced by 84530fa81e12dcd1d42310bb20c1385cb44128d8 by [`@normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16748](https://redirect.github.com/netty/netty/pull/16748) > * HTTP: Re-add constructor to HttpProxyHandler that was removed by mistake by [`@normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16747](https://redirect.github.com/netty/netty/pull/16747) > * Marshalling: Explicit document security requirements by [`@normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16752](https://redirect.github.com/netty/netty/pull/16752) > * Fix io\_uring op completion TRACE logging by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16755](https://redirect.github.com/netty/netty/pull/16755) > * Quic: Ensure writes are done before notify close promise of QuicheQui… by [`@normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16758](https://redirect.github.com/netty/netty/pull/16758) > * Avoid re-parsing openssl key material with non-cached provider by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16759](https://redirect.github.com/netty/netty/pull/16759) > * Pin HTTP/RTSP version + method normalization to Locale.US by [`@daguimu`](https://github.com/daguimu) in [netty/netty#16765](https://redirect.github.com/netty/netty/pull/16765) > * Fill MsgHdrMemoryArray#hdrs with null entry on release by [`@tsegismont`](https://github.com/tsegismont) in [netty/netty#16764](https://redirect.github.com/netty/netty/pull/16764) > * Revapi: Use default "oldVersion" by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16774](https://redirect.github.com/netty/netty/pull/16774) > * Adaptive: Fix concurrency issue in adaptive allocator by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16767](https://redirect.github.com/netty/netty/pull/16767) > * Auto-port 4.2: Make bulk byte moving in ByteBuf faster by [`@netty-project-bot`](https://github.com/netty-project-bot) in [netty/netty#16781](https://redirect.github.com/netty/netty/pull/16781) > * Pin multipart Content-Type / Content-Transfer-Encoding case folding to Locale.US by [`@daguimu`](https://github.com/daguimu) in [netty/netty#16768](https://redirect.github.com/netty/netty/pull/16768) > * Remove dead native declarations by [`@pandareen`](https://github.com/pandareen) in [netty/netty#16783](https://redirect.github.com/netty/netty/pull/16783) > * Isolate tests that modify available Security providers by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16793](https://redirect.github.com/netty/netty/pull/16793) > * Remove test annotations from a method that isn't a test by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16792](https://redirect.github.com/netty/netty/pull/16792) > * Enable OpenSslCachingKeyMaterialProvider to evict stale entries after cert rotation by [`@zhangweikop`](https://github.com/zhangweikop) in [netty/netty#16523](https://redirect.github.com/netty/netty/pull/16523) > * IoUring: extend user data from short to long by [`@dreamlike-ocean`](https://github.com/dreamlike-ocean) in [netty/netty#16682](https://redirect.github.com/netty/netty/pull/16682) > * Revert CompositeByteBuf component search fast path by [`@yawkat`](https://github.com/yawkat) in [netty/netty#16811](https://redirect.github.com/netty/netty/pull/16811) > * HTTP2: Use 100 as default max concurrent streams setting by [`@normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16804](https://redirect.github.com/netty/netty/pull/16804) > * Fix ResumptionController wrapping by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16815](https://redirect.github.com/netty/netty/pull/16815) > * Resolve all localhost addresses without querying DNS servers by [`@JulianVennen`](https://github.com/JulianVennen) in [netty/netty#16749](https://redirect.github.com/netty/netty/pull/16749) > * IpFilter: Fix ClassCastException caused by IpSubnetFilter if only ipv6 rules are configured but remote peer is using ipv4 by [`@normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16803](https://redirect.github.com/netty/netty/pull/16803) > * Fix memoryAddress() for direct ByteBuffers wrapped by Unpooled without Unsafe by [`@dreamlike-ocean`](https://github.com/dreamlike-ocean) in [netty/netty#16788](https://redirect.github.com/netty/netty/pull/16788) > * Route synchronous onLookupComplete exceptions via fireExceptionCaught by [`@kwondh5217`](https://github.com/kwondh5217) in [netty/netty#16794](https://redirect.github.com/netty/netty/pull/16794) > * IoUring: Stop generic FileRegion drain loop when transferred() reaches count() by [`@LuciferYang`](https://github.com/LuciferYang) in [netty/netty#16826](https://redirect.github.com/netty/netty/pull/16826) > * MQTT: Allow MQTT 5 CONNECT with password only by [`@shblue21`](https://github.com/shblue21) in [netty/netty#16833](https://redirect.github.com/netty/netty/pull/16833) > * Fix MQTT decoder size check after variable header replay by [`@daguimu`](https://github.com/daguimu) in [netty/netty#16787](https://redirect.github.com/netty/netty/pull/16787) > > New Contributors > ---------------- > > * [`@pandareen`](https://github.com/pandareen) made their first contribution in [netty/netty#16783](https://redirect.github.com/netty/netty/pull/16783) > * [`@zhangweikop`](https://github.com/zhangweikop) made their first contribution in [netty/netty#16523](https://redirect.github.com/netty/netty/pull/16523) > * [`@JulianVennen`](https://github.com/JulianVennen) made their first contribution in [netty/netty#16749](https://redirect.github.com/netty/netty/pull/16749) > * [`@kwondh5217`](https://github.com/kwondh5217) made their first contribution in [netty/netty#16794](https://redirect.github.com/netty/netty/pull/16794) > * [`@shblue21`](https://github.com/shblue21) made their first contribution in [netty/netty#16833](https://redirect.github.com/netty/netty/pull/16833) > > **Full Changelog**: <netty/netty@netty-4.2.13.Final...netty-4.2.14.Final> Commits * [`0a60b75`](netty/netty@0a60b75) [maven-release-plugin] prepare release netty-4.2.14.Final * [`72df658`](netty/netty@72df658) Fix MQTT decoder size check after variable header replay ([#16787](https://redirect.github.com/netty/netty/issues/16787)) * [`7125dba`](netty/netty@7125dba) MQTT: Allow MQTT 5 CONNECT with password only ([#16833](https://redirect.github.com/netty/netty/issues/16833)) * [`9e19320`](netty/netty@9e19320) IoUring: Stop generic FileRegion drain loop when transferred() reaches count(... * [`4ce9f17`](netty/netty@4ce9f17) Route synchronous onLookupComplete exceptions via fireExceptionCaught ([#16794](https://redirect.github.com/netty/netty/issues/16794)) * [`f7b1b7d`](netty/netty@f7b1b7d) Fix memoryAddress() for direct ByteBuffers wrapped by Unpooled without Unsafe... * [`0ccb265`](netty/netty@0ccb265) IpFilter: Fix ClassCastException caused by IpSubnetFilter if only ipv6 rules ... * [`a6aeb6d`](netty/netty@a6aeb6d) Resolve all localhost addresses without querying DNS servers ([#16749](https://redirect.github.com/netty/netty/issues/16749)) * [`c328ba2`](netty/netty@c328ba2) Fix ResumptionController wrapping ([#16815](https://redirect.github.com/netty/netty/issues/16815)) * [`bc5862b`](netty/netty@bc5862b) HTTP2: Use 100 as default max concurrent streams setting ([#16804](https://redirect.github.com/netty/netty/issues/16804)) * Additional commits viewable in [compare view](netty/netty@netty-4.2.13.Final...netty-4.2.14.Final) Updates `io.netty:netty-handler` from 4.2.13.Final to 4.2.14.Final Release notes *Sourced from [io.netty:netty-handler's releases](https://github.com/netty/netty/releases).* > netty-4.2.14.Final > ------------------ > > What's Changed > -------------- > > * HTTP: Fix revapi failure introduced by 84530fa81e12dcd1d42310bb20c1385cb44128d8 by [`@normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16748](https://redirect.github.com/netty/netty/pull/16748) > * HTTP: Re-add constructor to HttpProxyHandler that was removed by mistake by [`@normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16747](https://redirect.github.com/netty/netty/pull/16747) > * Marshalling: Explicit document security requirements by [`@normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16752](https://redirect.github.com/netty/netty/pull/16752) > * Fix io\_uring op completion TRACE logging by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16755](https://redirect.github.com/netty/netty/pull/16755) > * Quic: Ensure writes are done before notify close promise of QuicheQui… by [`@normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16758](https://redirect.github.com/netty/netty/pull/16758) > * Avoid re-parsing openssl key material with non-cached provider by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16759](https://redirect.github.com/netty/netty/pull/16759) > * Pin HTTP/RTSP version + method normalization to Locale.US by [`@daguimu`](https://github.com/daguimu) in [netty/netty#16765](https://redirect.github.com/netty/netty/pull/16765) > * Fill MsgHdrMemoryArray#hdrs with null entry on release by [`@tsegismont`](https://github.com/tsegismont) in [netty/netty#16764](https://redirect.github.com/netty/netty/pull/16764) > * Revapi: Use default "oldVersion" by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16774](https://redirect.github.com/netty/netty/pull/16774) > * Adaptive: Fix concurrency issue in adaptive allocator by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16767](https://redirect.github.com/netty/netty/pull/16767) > * Auto-port 4.2: Make bulk byte moving in ByteBuf faster by [`@netty-project-bot`](https://github.com/netty-project-bot) in [netty/netty#16781](https://redirect.github.com/netty/netty/pull/16781) > * Pin multipart Content-Type / Content-Transfer-Encoding case folding to Locale.US by [`@daguimu`](https://github.com/daguimu) in [netty/netty#16768](https://redirect.github.com/netty/netty/pull/16768) > * Remove dead native declarations by [`@pandareen`](https://github.com/pandareen) in [netty/netty#16783](https://redirect.github.com/netty/netty/pull/16783) > * Isolate tests that modify available Security providers by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16793](https://redirect.github.com/netty/netty/pull/16793) > * Remove test annotations from a method that isn't a test by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16792](https://redirect.github.com/netty/netty/pull/16792) > * Enable OpenSslCachingKeyMaterialProvider to evict stale entries after cert rotation by [`@zhangweikop`](https://github.com/zhangweikop) in [netty/netty#16523](https://redirect.github.com/netty/netty/pull/16523) > * IoUring: extend user data from short to long by [`@dreamlike-ocean`](https://github.com/dreamlike-ocean) in [netty/netty#16682](https://redirect.github.com/netty/netty/pull/16682) > * Revert CompositeByteBuf component search fast path by [`@yawkat`](https://github.com/yawkat) in [netty/netty#16811](https://redirect.github.com/netty/netty/pull/16811) > * HTTP2: Use 100 as default max concurrent streams setting by [`@normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16804](https://redirect.github.com/netty/netty/pull/16804) > * Fix ResumptionController wrapping by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16815](https://redirect.github.com/netty/netty/pull/16815) > * Resolve all localhost addresses without querying DNS servers by [`@JulianVennen`](https://github.com/JulianVennen) in [netty/netty#16749](https://redirect.github.com/netty/netty/pull/16749) > * IpFilter: Fix ClassCastException caused by IpSubnetFilter if only ipv6 rules are configured but remote peer is using ipv4 by [`@normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16803](https://redirect.github.com/netty/netty/pull/16803) > * Fix memoryAddress() for direct ByteBuffers wrapped by Unpooled without Unsafe by [`@dreamlike-ocean`](https://github.com/dreamlike-ocean) in [netty/netty#16788](https://redirect.github.com/netty/netty/pull/16788) > * Route synchronous onLookupComplete exceptions via fireExceptionCaught by [`@kwondh5217`](https://github.com/kwondh5217) in [netty/netty#16794](https://redirect.github.com/netty/netty/pull/16794) > * IoUring: Stop generic FileRegion drain loop when transferred() reaches count() by [`@LuciferYang`](https://github.com/LuciferYang) in [netty/netty#16826](https://redirect.github.com/netty/netty/pull/16826) > * MQTT: Allow MQTT 5 CONNECT with password only by [`@shblue21`](https://github.com/shblue21) in [netty/netty#16833](https://redirect.github.com/netty/netty/pull/16833) > * Fix MQTT decoder size check after variable header replay by [`@daguimu`](https://github.com/daguimu) in [netty/netty#16787](https://redirect.github.com/netty/netty/pull/16787) > > New Contributors > ---------------- > > * [`@pandareen`](https://github.com/pandareen) made their first contribution in [netty/netty#16783](https://redirect.github.com/netty/netty/pull/16783) > * [`@zhangweikop`](https://github.com/zhangweikop) made their first contribution in [netty/netty#16523](https://redirect.github.com/netty/netty/pull/16523) > * [`@JulianVennen`](https://github.com/JulianVennen) made their first contribution in [netty/netty#16749](https://redirect.github.com/netty/netty/pull/16749) > * [`@kwondh5217`](https://github.com/kwondh5217) made their first contribution in [netty/netty#16794](https://redirect.github.com/netty/netty/pull/16794) > * [`@shblue21`](https://github.com/shblue21) made their first contribution in [netty/netty#16833](https://redirect.github.com/netty/netty/pull/16833) > > **Full Changelog**: <netty/netty@netty-4.2.13.Final...netty-4.2.14.Final> Commits * [`0a60b75`](netty/netty@0a60b75) [maven-release-plugin] prepare release netty-4.2.14.Final * [`72df658`](netty/netty@72df658) Fix MQTT decoder size check after variable header replay ([#16787](https://redirect.github.com/netty/netty/issues/16787)) * [`7125dba`](netty/netty@7125dba) MQTT: Allow MQTT 5 CONNECT with password only ([#16833](https://redirect.github.com/netty/netty/issues/16833)) * [`9e19320`](netty/netty@9e19320) IoUring: Stop generic FileRegion drain loop when transferred() reaches count(... * [`4ce9f17`](netty/netty@4ce9f17) Route synchronous onLookupComplete exceptions via fireExceptionCaught ([#16794](https://redirect.github.com/netty/netty/issues/16794)) * [`f7b1b7d`](netty/netty@f7b1b7d) Fix memoryAddress() for direct ByteBuffers wrapped by Unpooled without Unsafe... * [`0ccb265`](netty/netty@0ccb265) IpFilter: Fix ClassCastException caused by IpSubnetFilter if only ipv6 rules ... * [`a6aeb6d`](netty/netty@a6aeb6d) Resolve all localhost addresses without querying DNS servers ([#16749](https://redirect.github.com/netty/netty/issues/16749)) * [`c328ba2`](netty/netty@c328ba2) Fix ResumptionController wrapping ([#16815](https://redirect.github.com/netty/netty/issues/16815)) * [`bc5862b`](netty/netty@bc5862b) HTTP2: Use 100 as default max concurrent streams setting ([#16804](https://redirect.github.com/netty/netty/issues/16804)) * Additional commits viewable in [compare view](netty/netty@netty-4.2.13.Final...netty-4.2.14.Final) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- Dependabot commands and options You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
…l [skip ci] Bumps [io.netty:netty-all](https://github.com/netty/netty) from 4.2.13.Final to 4.2.14.Final. Release notes *Sourced from [io.netty:netty-all's releases](https://github.com/netty/netty/releases).* > netty-4.2.14.Final > ------------------ > > What's Changed > -------------- > > * HTTP: Fix revapi failure introduced by 84530fa81e12dcd1d42310bb20c1385cb44128d8 by [`@normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16748](https://redirect.github.com/netty/netty/pull/16748) > * HTTP: Re-add constructor to HttpProxyHandler that was removed by mistake by [`@normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16747](https://redirect.github.com/netty/netty/pull/16747) > * Marshalling: Explicit document security requirements by [`@normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16752](https://redirect.github.com/netty/netty/pull/16752) > * Fix io\_uring op completion TRACE logging by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16755](https://redirect.github.com/netty/netty/pull/16755) > * Quic: Ensure writes are done before notify close promise of QuicheQui… by [`@normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16758](https://redirect.github.com/netty/netty/pull/16758) > * Avoid re-parsing openssl key material with non-cached provider by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16759](https://redirect.github.com/netty/netty/pull/16759) > * Pin HTTP/RTSP version + method normalization to Locale.US by [`@daguimu`](https://github.com/daguimu) in [netty/netty#16765](https://redirect.github.com/netty/netty/pull/16765) > * Fill MsgHdrMemoryArray#hdrs with null entry on release by [`@tsegismont`](https://github.com/tsegismont) in [netty/netty#16764](https://redirect.github.com/netty/netty/pull/16764) > * Revapi: Use default "oldVersion" by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16774](https://redirect.github.com/netty/netty/pull/16774) > * Adaptive: Fix concurrency issue in adaptive allocator by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16767](https://redirect.github.com/netty/netty/pull/16767) > * Auto-port 4.2: Make bulk byte moving in ByteBuf faster by [`@netty-project-bot`](https://github.com/netty-project-bot) in [netty/netty#16781](https://redirect.github.com/netty/netty/pull/16781) > * Pin multipart Content-Type / Content-Transfer-Encoding case folding to Locale.US by [`@daguimu`](https://github.com/daguimu) in [netty/netty#16768](https://redirect.github.com/netty/netty/pull/16768) > * Remove dead native declarations by [`@pandareen`](https://github.com/pandareen) in [netty/netty#16783](https://redirect.github.com/netty/netty/pull/16783) > * Isolate tests that modify available Security providers by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16793](https://redirect.github.com/netty/netty/pull/16793) > * Remove test annotations from a method that isn't a test by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16792](https://redirect.github.com/netty/netty/pull/16792) > * Enable OpenSslCachingKeyMaterialProvider to evict stale entries after cert rotation by [`@zhangweikop`](https://github.com/zhangweikop) in [netty/netty#16523](https://redirect.github.com/netty/netty/pull/16523) > * IoUring: extend user data from short to long by [`@dreamlike-ocean`](https://github.com/dreamlike-ocean) in [netty/netty#16682](https://redirect.github.com/netty/netty/pull/16682) > * Revert CompositeByteBuf component search fast path by [`@yawkat`](https://github.com/yawkat) in [netty/netty#16811](https://redirect.github.com/netty/netty/pull/16811) > * HTTP2: Use 100 as default max concurrent streams setting by [`@normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16804](https://redirect.github.com/netty/netty/pull/16804) > * Fix ResumptionController wrapping by [`@chrisvest`](https://github.com/chrisvest) in [netty/netty#16815](https://redirect.github.com/netty/netty/pull/16815) > * Resolve all localhost addresses without querying DNS servers by [`@JulianVennen`](https://github.com/JulianVennen) in [netty/netty#16749](https://redirect.github.com/netty/netty/pull/16749) > * IpFilter: Fix ClassCastException caused by IpSubnetFilter if only ipv6 rules are configured but remote peer is using ipv4 by [`@normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16803](https://redirect.github.com/netty/netty/pull/16803) > * Fix memoryAddress() for direct ByteBuffers wrapped by Unpooled without Unsafe by [`@dreamlike-ocean`](https://github.com/dreamlike-ocean) in [netty/netty#16788](https://redirect.github.com/netty/netty/pull/16788) > * Route synchronous onLookupComplete exceptions via fireExceptionCaught by [`@kwondh5217`](https://github.com/kwondh5217) in [netty/netty#16794](https://redirect.github.com/netty/netty/pull/16794) > * IoUring: Stop generic FileRegion drain loop when transferred() reaches count() by [`@LuciferYang`](https://github.com/LuciferYang) in [netty/netty#16826](https://redirect.github.com/netty/netty/pull/16826) > * MQTT: Allow MQTT 5 CONNECT with password only by [`@shblue21`](https://github.com/shblue21) in [netty/netty#16833](https://redirect.github.com/netty/netty/pull/16833) > * Fix MQTT decoder size check after variable header replay by [`@daguimu`](https://github.com/daguimu) in [netty/netty#16787](https://redirect.github.com/netty/netty/pull/16787) > > New Contributors > ---------------- > > * [`@pandareen`](https://github.com/pandareen) made their first contribution in [netty/netty#16783](https://redirect.github.com/netty/netty/pull/16783) > * [`@zhangweikop`](https://github.com/zhangweikop) made their first contribution in [netty/netty#16523](https://redirect.github.com/netty/netty/pull/16523) > * [`@JulianVennen`](https://github.com/JulianVennen) made their first contribution in [netty/netty#16749](https://redirect.github.com/netty/netty/pull/16749) > * [`@kwondh5217`](https://github.com/kwondh5217) made their first contribution in [netty/netty#16794](https://redirect.github.com/netty/netty/pull/16794) > * [`@shblue21`](https://github.com/shblue21) made their first contribution in [netty/netty#16833](https://redirect.github.com/netty/netty/pull/16833) > > **Full Changelog**: <netty/netty@netty-4.2.13.Final...netty-4.2.14.Final> Commits * [`0a60b75`](netty/netty@0a60b75) [maven-release-plugin] prepare release netty-4.2.14.Final * [`72df658`](netty/netty@72df658) Fix MQTT decoder size check after variable header replay ([#16787](https://redirect.github.com/netty/netty/issues/16787)) * [`7125dba`](netty/netty@7125dba) MQTT: Allow MQTT 5 CONNECT with password only ([#16833](https://redirect.github.com/netty/netty/issues/16833)) * [`9e19320`](netty/netty@9e19320) IoUring: Stop generic FileRegion drain loop when transferred() reaches count(... * [`4ce9f17`](netty/netty@4ce9f17) Route synchronous onLookupComplete exceptions via fireExceptionCaught ([#16794](https://redirect.github.com/netty/netty/issues/16794)) * [`f7b1b7d`](netty/netty@f7b1b7d) Fix memoryAddress() for direct ByteBuffers wrapped by Unpooled without Unsafe... * [`0ccb265`](netty/netty@0ccb265) IpFilter: Fix ClassCastException caused by IpSubnetFilter if only ipv6 rules ... * [`a6aeb6d`](netty/netty@a6aeb6d) Resolve all localhost addresses without querying DNS servers ([#16749](https://redirect.github.com/netty/netty/issues/16749)) * [`c328ba2`](netty/netty@c328ba2) Fix ResumptionController wrapping ([#16815](https://redirect.github.com/netty/netty/issues/16815)) * [`bc5862b`](netty/netty@bc5862b) HTTP2: Use 100 as default max concurrent streams setting ([#16804](https://redirect.github.com/netty/netty/issues/16804)) * Additional commits viewable in [compare view](netty/netty@netty-4.2.13.Final...netty-4.2.14.Final) [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- Dependabot commands and options You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Netty 4.1.133.Final introduced a regression in MqttDecoder while fixing CVE-2026-44248: when multiple MQTT packets are present in the same cumulation buffer, the per-message size check used the total buffer size instead of the current packet's declared remaining length. Valid in-limit packets get rejected with TooLongFrameException("message length exceeds 65536: <small number>"). Fixed upstream by netty/netty#16787 and ported to 4.1 as netty/netty@30f8f284db, released in 4.1.134.Final.
### Motivation #16787 fixed the `READ_VARIABLE_HEADER` too-long check on the **4.2** branch by replacing a `ReplayingDecoderByteBuf.readableBytes()` probe with the message size declared by the fixed header. That fix was auto-ported to 4.1 in #16838, **but a later CVE-2026-44248 security merge re-introduced the broken code on 4.1**, so the 4.1 branch still carries the regression: ```java int initialAvailableBytes = buffer.readableBytes(); ... if (initialAvailableBytes < maxBytesInMessage) { throw signal; // REPLAY } else { bailOut = true; // too long } ``` Because `MqttDecoder extends ReplayingDecoder`, `buffer` is a `ReplayingDecoderByteBuf` whose `readableBytes()` returns `Integer.MAX_VALUE - readerIndex` rather than the bytes actually buffered. With the default `maxBytesInMessage` of `8092`, the `initialAvailableBytes < maxBytesInMessage` check is therefore effectively always false. So when `decodeVariableHeader` asks for a `REPLAY` because the variable header has not fully arrived yet, the decoder takes the `bailOut` branch and rejects the message with a `TooLongFrameException` instead of waiting for the rest — a valid message whose variable header is split across reads is dropped. ### Modification Re-apply the #16787 fix on 4.1: drop the `initialAvailableBytes` / `readableBytes()` probe and decide based on `bytesRemainingBeforeVariableHeader` (the remaining length declared by the fixed header). A genuinely oversized message is still rejected by the existing `bytesRemainingBeforeVariableHeader > maxBytesInMessage` check; an incomplete one now correctly `REPLAY`s. ### Result A message whose variable header arrives in chunks is decoded once complete, instead of being rejected as too long, while declared-oversize messages still fail with `TooLongFrameException`. The two regression tests from #16787 are ported here. All `codec-mqtt` tests pass locally. Note: this targets **4.1 only** and intentionally carries no cherry-pick label — 4.2 already has the fix via #16787. Found while addressing @chrisvest's review comment on #16813 about the same `readableBytes()` antipattern.
) Motivation: The CVE-2026-44248 fix in 82f47fa added a guard at the top of `decodeProperties` to trigger an early REPLAY when the cumulation buffer did not yet have the full properties block: ```java if (buffer.readableBytes() < totalPropertiesLength) { buffer.readSlice(totalPropertiesLength); } ``` Because `MqttDecoder` extends `ReplayingDecoder`, the buffer passed to `decodeProperties` is a `ReplayingDecoderByteBuf` whose `readableBytes()` returns `Integer.MAX_VALUE - readerIndex` rather than the actual number of bytes available (see `ReplayingDecoderByteBuf.readableBytes()`). The `if`-condition is therefore false in practice and the `readSlice()` call never executes, so the early-REPLAY optimization is effectively dead code. When the properties block arrives in chunks the decoder still falls back to partial parsing followed by a mid-loop REPLAY, which defeats the optimization's intent on slow streams. Modification: Replace the broken `readableBytes()` check with a `getByte()` probe at `buffer.readerIndex() + totalPropertiesLength - 1`. `ReplayingDecoderByteBuf.checkIndex` throws `Signal.REPLAY` when `index + 1 > writerIndex` — i.e. exactly when the cumulation buffer does not yet hold the full properties block. The call has no side effect on `readerIndex`, so subsequent parsing is unchanged once the data arrives. A `totalPropertiesLength > 0` guard skips the probe when there are no properties. Result: The early-REPLAY guard now actually fires when properties data is incomplete, restoring the CVE-2026-44248 fix's intent of avoiding repeated partial-properties parsing on slow streams. No semantic change on the happy path; all 107 existing `codec-mqtt` tests pass locally. Note: this is complementary to #16787, which addresses the *outer* variable-header REPLAY handling broken by the same CVE patch (same `buffer.readableBytes()` antipattern in a ReplayingDecoder context). Both fixes are independent and can land in either order; together they restore the optimization the CVE-2026-44248 fix originally aimed for.
…ually fire (#16919) Auto-port of #16813 to 4.2 Cherry-picked commit: 2d781e2 --- Motivation: The CVE-2026-44248 fix in 82f47fa added a guard at the top of `decodeProperties` to trigger an early REPLAY when the cumulation buffer did not yet have the full properties block: ```java if (buffer.readableBytes() < totalPropertiesLength) { buffer.readSlice(totalPropertiesLength); } ``` Because `MqttDecoder` extends `ReplayingDecoder`, the buffer passed to `decodeProperties` is a `ReplayingDecoderByteBuf` whose `readableBytes()` returns `Integer.MAX_VALUE - readerIndex` rather than the actual number of bytes available (see `ReplayingDecoderByteBuf.readableBytes()`). The `if`-condition is therefore false in practice and the `readSlice()` call never executes, so the early-REPLAY optimization is effectively dead code. When the properties block arrives in chunks the decoder still falls back to partial parsing followed by a mid-loop REPLAY, which defeats the optimization's intent on slow streams. Modification: Replace the broken `readableBytes()` check with a `getByte()` probe at `buffer.readerIndex() + totalPropertiesLength - 1`. `ReplayingDecoderByteBuf.checkIndex` throws `Signal.REPLAY` when `index + 1 > writerIndex` — i.e. exactly when the cumulation buffer does not yet hold the full properties block. The call has no side effect on `readerIndex`, so subsequent parsing is unchanged once the data arrives. A `totalPropertiesLength > 0` guard skips the probe when there are no properties. Result: The early-REPLAY guard now actually fires when properties data is incomplete, restoring the CVE-2026-44248 fix's intent of avoiding repeated partial-properties parsing on slow streams. No semantic change on the happy path; all 107 existing `codec-mqtt` tests pass locally. Note: this is complementary to #16787, which addresses the *outer* variable-header REPLAY handling broken by the same CVE patch (same `buffer.readableBytes()` antipattern in a ReplayingDecoder context). Both fixes are independent and can land in either order; together they restore the optimization the CVE-2026-44248 fix originally aimed for. Co-authored-by: Guimu <30684111+daguimu@users.noreply.github.com>
Problem
The MQTT decoder can reject valid packets after the CVE-2026-44248 fix when several MQTT packets are present in the same cumulation buffer. If the current packet's variable header needs a replay, the decoder compares the total readable bytes in the buffer against
maxBytesInMessage, so later packets can make the current in-limit packet look too large.Root Cause
READ_VARIABLE_HEADERrecordedbuffer.readableBytes()before decoding the variable header. That value is the cumulation's total readable bytes, not the current MQTT packet's declared remaining length. WhendecodeVariableHeaderthrowsSignal.REPLAY, the too-large decision must be based onbytesRemainingBeforeVariableHeaderfor the current packet.Fix
bytesRemainingBeforeVariableHeaderwhen deciding whether to swallowSignal.REPLAYand raiseTooLongFrameException.maxBytesInMessage, even if the cumulation contains additional bytes for following packets.Tests Added
testPublishMessageIncompleteVariableHeaderDoesNotUseCumulationSizeForTooLongCheck()verifies an incomplete in-limit PUBLISH variable header with extra cumulated PINGREQ packets does not emit an invalid messagetestPublishMessageIncompleteVariableHeaderStillFailsWhenCurrentPacketTooLarge()verifies an incomplete PUBLISH whose own remaining length exceedsmaxBytesInMessagestill emits aTooLongFrameExceptionImpact
This restores decoding for valid in-limit MQTT packets batched in the same buffer while preserving the CVE fix: packets whose declared remaining length exceeds
maxBytesInMessagestill fail withTooLongFrameExceptioneven if variable-header decoding requests replay.Fixes #16776