mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 23:27:04 +02:00
BUG/MINOR: h3: properly handle incomplete remote uni stream type
A H3 unidirectional stream is always opened with its stream type first encoded as a QUIC variable integer. If the STREAM frame contains some data but not enough to decode this varint, haproxy would crash due to an ABORT_NOW() statement. To fix this, ensure we support an incomplete stream type. In this case, h3_init_uni_stream() returns 0 and the buffer content is not cleared. Stream decoding will resume when new data are received for this stream which should be enough to decode the stream type varint. This bug has never occured on production because standard H3 stream types are small enough to be encoded on a single byte. This should be backported up to 2.6.
This commit is contained in:
parent
1751db140a
commit
5aa21c1748
12
src/h3.c
12
src/h3.c
@ -181,7 +181,9 @@ static ssize_t h3_init_uni_stream(struct h3c *h3c, struct qcs *qcs,
|
||||
|
||||
ret = b_quic_dec_int(&type, b, &len);
|
||||
if (!ret) {
|
||||
ABORT_NOW();
|
||||
/* not enough data to decode uni stream type, retry later */
|
||||
TRACE_DATA("cannot decode uni stream type due to incomplete data", H3_EV_H3S_NEW, qcs->qcc->conn, qcs);
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
@ -235,6 +237,7 @@ static ssize_t h3_init_uni_stream(struct h3c *h3c, struct qcs *qcs,
|
||||
|
||||
h3s->flags |= H3_SF_UNI_INIT;
|
||||
|
||||
out:
|
||||
TRACE_LEAVE(H3_EV_H3S_NEW, qcs->qcc->conn, qcs);
|
||||
return len;
|
||||
|
||||
@ -994,10 +997,15 @@ static ssize_t h3_decode_qcs(struct qcs *qcs, struct buffer *b, int fin)
|
||||
TRACE_ENTER(H3_EV_RX_FRAME, qcs->qcc->conn, qcs);
|
||||
|
||||
if (quic_stream_is_uni(qcs->id) && !(h3s->flags & H3_SF_UNI_INIT)) {
|
||||
if ((ret = h3_init_uni_stream(h3c, qcs, b)) < 0) {
|
||||
ret = h3_init_uni_stream(h3c, qcs, b);
|
||||
if (ret < 0) {
|
||||
TRACE_ERROR("cannot initialize uni stream", H3_EV_RX_FRAME, qcs->qcc->conn, qcs);
|
||||
goto err;
|
||||
}
|
||||
else if (!ret) {
|
||||
/* not enough data to initialize uni stream, retry later */
|
||||
goto done;
|
||||
}
|
||||
|
||||
total += ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user