Skip to content

[Bug] Negative frame data length causes IllegalArgumentException in ExchangeCodec #16447

Description

@L1nq0

Pre-check

  • I am sure that all the content I provide is in English.

Search before asking

  • I had searched in the issues and found no similar issues.

Apache Dubbo Component

Java SDK (apache/dubbo)

Dubbo Version

Dubbo Java 3.3.6 (tag dubbo-3.3.6); the same code is unchanged on the 3.3 branch (checked today).
OpenJDK 21, Linux.
Protocol: dubbo.

Steps to reproduce this issue

While testing how the dubbo protocol codec handles invalid frames locally, we found that a frame whose header declares a negative data length makes decode throw IllegalArgumentException before decodeBody is reached.

A complete minimal frame is 16 bytes:

da bb c2 00 ff ff ff ff ff ff ff ff ff ff ff ff

magic dabb, flag c2 (request, twoway, hessian2), requestId all ff, and the data length field at offset 12 set to ffffffff, which reads back as -1.

Passing these bytes to DubboCodec.decode, or writing them to a provider port over TCP, throws:

java.lang.IllegalArgumentException: length: -1
    at org.apache.dubbo.remoting.buffer.ChannelBufferInputStream.<init>(ChannelBufferInputStream.java:37)
    at org.apache.dubbo.remoting.exchange.codec.ExchangeCodec.decode(ExchangeCodec.java:134)
    at org.apache.dubbo.remoting.exchange.codec.ExchangeCodec.decode(ExchangeCodec.java:92)

On the netty4 transport the exception leaves the codec and is handled as a connection-level exception (logged, connection closed).

What you expected to happen

A header declaring a negative data length is not a valid frame, and no additional input can make it one. decode should reject such a frame as invalid at the point the length is read, instead of letting a stream constructor throw an uncaught IllegalArgumentException from inside the codec. A sign check on len right after Bytes.bytes2int would cover it; returning NEED_MORE_INPUT would not fit here, since it would leave the channel waiting for input that can never make a negative length valid.

Anything else

Root cause, in ExchangeCodec (dubbo-remoting-api, tag dubbo-3.3.6):

  • line 119: the data length is read as a signed int (Bytes.bytes2int(header, 12))
  • line 123: finishRespWhenOverPayload only compares against the payload upper bound, and only for responses
  • line 129: the completeness check (readable < len + 16) passes for every negative len
  • line 134: ChannelBufferInputStream rejects negative lengths with IllegalArgumentException, which escapes decode

We have the 16-byte reproducer and a direct codec call available as a minimal demo, and are willing to submit a PR with the check and a test.

Do you have a (mini) reproduction demo?

  • Yes, I have a minimal reproduction demo to help resolve this issue more effectively!

Are you willing to submit a pull request to fix on your own?

  • Yes I am willing to submit a pull request on my own!

Code of Conduct

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions