reject zero-length padded DATA frame in H2Context::OnData#3325
reject zero-length padded DATA frame in H2Context::OnData#3325sahvx655-wq wants to merge 1 commit into
Conversation
| H2ParseResult H2Context::OnData( | ||
| butil::IOBufBytesIterator& it, const H2FrameHead& frame_head) { | ||
| const bool has_padding = (frame_head.flags & H2_FLAGS_PADDED); | ||
| if (frame_head.payload_size < (size_t)has_padding) { |
There was a problem hiding this comment.
The logic is not clear to converter a bool to a size_t here
There was a problem hiding this comment.
Agreed, the bool to size_t cast was too cute and obscured what it was actually testing. I've removed it in favour of the explicit zero check inside the PADDED branch below.
| uint32_t frag_size = frame_head.payload_size; | ||
| uint8_t pad_length = 0; | ||
| if (frame_head.flags & H2_FLAGS_PADDED) { | ||
| if (has_padding) { |
There was a problem hiding this comment.
I think a better way is to add the check code here:
if (frag_size <= 0) {
LOG(ERROR) << ...
return ...;
}
There was a problem hiding this comment.
Done, moved the check inside the PADDED branch as you suggested. One small tweak: I used frag_size == 0 rather than <= 0, since frag_size is uint32_t and -W flags the <= 0 form as always-false. Same effect, just keeps the build warning-free.
It reads cleaner there anyway, the zero-length case only matters when PADDED is set and we're about to decrement for the pad-length byte. The check sits before --frag_size, so a payload_size of 0 with PADDED now returns FRAME_SIZE_ERROR rather than wrapping frag_size to 0xFFFFFFFF and slipping past the frag_size < pad_length check. An empty unpadded DATA frame still passes through untouched.
a25df47 to
b877235
Compare
A DATA frame with the PADDED flag but Length 0 underflows frag_size here.
--frag_sizewraps the uint32_t to 0xFFFFFFFF, thefrag_size < pad_lengthcheck then passes, and the bogus size reaches append_and_forward, which swallows the rest of the connection buffer as one DATA payload and feeds ~4GiB into the flow-control counter. OnHeaders already rejects this case; OnData was missing the same guard. Fix returns FRAME_SIZE_ERROR per RFC 7540 6.1 when a padded frame has no room for the pad-length byte.