BUG/MEDIUM: h3: Be sure to handle fin bit on the last DATA frame

When DATA frames are decoded for a QUIC stream, we take care to not exceed
the announced content-length, if any. To do so, we check we don't received
more data than excepted but also no less than announced. For the last check,
we rely on the fin bit.

However, it is possible to have several DATA frames to decode at a time
while the end of the stream was received. In this case, we must take care to
handle the fin bit only on the last frame. But because of a bug, the fin bit
was handled to early, erroneously triggering an internal error.

This patch must be backported as far as 2.6.
This commit is contained in:
Christopher Faulet 2023-07-28 09:33:29 +02:00
parent f7596209ee
commit 2f8c44cfb7

View File

@ -1095,7 +1095,7 @@ static ssize_t h3_decode_qcs(struct qcs *qcs, struct buffer *b, int fin)
/* Check that content-length is not exceeded on a new DATA frame. */
if (ftype == H3_FT_DATA) {
h3s->data_len += flen;
if (h3s->flags & H3_SF_HAVE_CLEN && h3_check_body_size(qcs, fin))
if (h3s->flags & H3_SF_HAVE_CLEN && h3_check_body_size(qcs, (fin && flen == b_data(b))))
break;
}
@ -1130,12 +1130,12 @@ static ssize_t h3_decode_qcs(struct qcs *qcs, struct buffer *b, int fin)
break;
}
/* Check content-length equality with DATA frames length on the last frame. */
if (fin && h3s->flags & H3_SF_HAVE_CLEN && h3_check_body_size(qcs, fin))
break;
last_stream_frame = (fin && flen == b_data(b));
/* Check content-length equality with DATA frames length on the last frame. */
if (last_stream_frame && h3s->flags & H3_SF_HAVE_CLEN && h3_check_body_size(qcs, last_stream_frame))
break;
h3_inc_frame_type_cnt(h3c->prx_counters, ftype);
switch (ftype) {
case H3_FT_DATA: