-
Notifications
You must be signed in to change notification settings - Fork 224
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixing binary port decoder to bail out quickly when receiving a big mes… #5049
Fixing binary port decoder to bail out quickly when receiving a big mes… #5049
Conversation
3d5d3a6
to
6ad22ed
Compare
6ad22ed
to
17d2759
Compare
binary_port/src/binary_message.rs
Outdated
if let [b1, b2, b3, b4, remainder @ ..] = &src[..] { | ||
let length = LengthEncoding::from_le_bytes([*b1, *b2, *b3, *b4]) as usize; | ||
let remainder_length = remainder.len(); | ||
(length, remainder_length, remainder_length >= length) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the case of remainder_length > length
, I think enforcing request-response means the buffer should hold at most one message. The total buffer length should match the value foretold by the first 4 bytes, and so remainder_length
should exactly equal length
once we have the full frame. Any leftover bytes are a sign of misuse, and then, we should clear the buffer and err out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good eye 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
any leftover bytes are a sign of misuse, and then, we should clear the buffer and err out.
Can you provide a scenario where any remaining left over bytes could be misused and how the decoder could be exploited?
See my other comment here: #5049 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but see my comment above.
binary_port/src/binary_message.rs
Outdated
|
||
if length > self.max_message_size_bytes as usize { | ||
return Err(Error::RequestTooLarge { | ||
allowed: self.max_message_size_bytes, | ||
got: length as u32, | ||
}); | ||
} | ||
|
||
if remainder_length > self.max_message_size_bytes as usize { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need to do this as I mentioned on slack. In my view, the remainder could be either empty, or could contain partial frame, or multiple frames, or frame + another partial frame etc. I think in some extreme cases of very slow senders this may reject legitimate connections. This check above is sufficient (length > self.max_message_size_bytes
).
Keep in mind there are backpressure mechanisms at the TCP level that should prevent clients from sending gigabytes of garbage as long as you don't drain the socket
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i agree...i would want proof that this is necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
optimistic approval, but consider michal's comment
bors r+ |
Build succeeded: |
…sage. This PR should have no downstream effects.