From 80097cc824ec7db26f12fe583c0d6ed72a7ea8e2 Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Tue, 24 May 2022 11:13:46 +0200 Subject: [PATCH] MINOR: h3: reject too big frames The whole frame payload must have been received to demux a H3 frames, except for H3 DATA which can be fragmented into multiple HTX blocks. If the frame is bigger than the buffer and is not a DATA frame, a connection error is reported with error H3_EXCESSIVE_LOAD. This should be completed in the future with the H3 settings to limit the size of uncompressed header section. This code is more generic : it can handle every H3 frames. This is done in order to be able to use h3_decode_qcs() to demux both uni and bidir streams. --- src/h3.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/h3.c b/src/h3.c index 8d2732e44..c2dfd0002 100644 --- a/src/h3.c +++ b/src/h3.c @@ -296,11 +296,24 @@ static int h3_decode_qcs(struct qcs *qcs, int fin, void *ctx) flen = h3s->demux_frame_len; ftype = h3s->demux_frame_type; - /* Do not demux HEADERS if frame incomplete. */ - if (ftype == H3_FT_HEADERS && flen > b_data(&b)) { - BUG_ON(ncb_is_full(rxbuf)); /* TODO should define SETTINGS for max header size */ + + /* Do not demux incomplete frames except H3 DATA which can be + * fragmented in multiple HTX blocks. + */ + if (flen > b_data(&b) && ftype != H3_FT_DATA) { + /* Reject frames bigger than bufsize. + * + * TODO HEADERS should in complement be limited with H3 + * SETTINGS_MAX_FIELD_SECTION_SIZE parameter to prevent + * excessive decompressed size. + */ + if (flen > ncb_size(rxbuf)) { + qcc_emit_cc_app(qcs->qcc, H3_EXCESSIVE_LOAD); + return 1; + } break; } + last_stream_frame = (fin && flen == ncb_total_data(rxbuf)); switch (ftype) { @@ -316,14 +329,15 @@ static int h3_decode_qcs(struct qcs *qcs, int fin, void *ctx) break; case H3_FT_PUSH_PROMISE: /* Not supported */ - ret = MIN(ncb_data(rxbuf, 0), flen); + ret = flen; break; default: /* draft-ietf-quic-http34 9. Extensions to HTTP/3 * unknown frame types MUST be ignored */ h3_debug_printf(stderr, "ignore unknown frame type 0x%lx\n", ftype); - ret = MIN(ncb_data(rxbuf, 0), flen); + ret = flen; + break; } if (ret) {