mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-09 16:47:18 +02:00
BUG/MEDIUM: h3: fix use-after-free on mux Rx buffer wrapping
Handle wrapping buffer in h3_data_to_htx(). If data is wrapping, first copy the contiguous data, then copy the data in front of the buffer. Note that h3_headers_to_htx() is not able to handle wrapping data. For the moment, a BUG_ON was added as a reminder. This cas never happened, most probably because HEADERS is the first frame of the stream.
This commit is contained in:
parent
0fa14a69e8
commit
30f23f53d2
18
src/h3.c
18
src/h3.c
@ -112,6 +112,8 @@ static int h3_headers_to_htx(struct qcs *qcs, struct buffer *buf, uint64_t len,
|
|||||||
struct ist authority = IST_NULL;
|
struct ist authority = IST_NULL;
|
||||||
int hdr_idx;
|
int hdr_idx;
|
||||||
|
|
||||||
|
/* TODO support buffer wrapping */
|
||||||
|
BUG_ON(b_contig_data(buf, 0) != b_data(buf));
|
||||||
if (qpack_decode_fs((const unsigned char *)b_head(buf), len, tmp, list) < 0)
|
if (qpack_decode_fs((const unsigned char *)b_head(buf), len, tmp, list) < 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
@ -198,23 +200,31 @@ static int h3_data_to_htx(struct qcs *qcs, struct buffer *buf, uint64_t len,
|
|||||||
{
|
{
|
||||||
struct buffer *appbuf;
|
struct buffer *appbuf;
|
||||||
struct htx *htx = NULL;
|
struct htx *htx = NULL;
|
||||||
size_t htx_sent;
|
size_t contig = 0, htx_sent = 0;
|
||||||
int htx_space;
|
int htx_space;
|
||||||
|
char *head;
|
||||||
|
|
||||||
appbuf = qc_get_buf(qcs, &qcs->rx.app_buf);
|
appbuf = qc_get_buf(qcs, &qcs->rx.app_buf);
|
||||||
BUG_ON(!appbuf);
|
BUG_ON(!appbuf);
|
||||||
htx = htx_from_buf(appbuf);
|
htx = htx_from_buf(appbuf);
|
||||||
|
|
||||||
|
retry:
|
||||||
htx_space = htx_free_data_space(htx);
|
htx_space = htx_free_data_space(htx);
|
||||||
if (!htx_space || htx_space < len) {
|
if (!htx_space || htx_space < len) {
|
||||||
ABORT_NOW(); /* TODO handle this case properly */
|
ABORT_NOW(); /* TODO handle this case properly */
|
||||||
}
|
}
|
||||||
|
|
||||||
htx_sent = htx_add_data(htx, ist2(b_head(buf), len));
|
contig = b_contig_data(buf, contig);
|
||||||
if (htx_sent < len) {
|
if (len > contig) {
|
||||||
ABORT_NOW(); /* TODO handle this case properly */
|
htx_sent = htx_add_data(htx, ist2(b_head(buf), contig));
|
||||||
|
head = b_orig(buf);
|
||||||
|
len -= contig;
|
||||||
|
goto retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
htx_sent += htx_add_data(htx, ist2(head, len));
|
||||||
|
BUG_ON(htx_sent < len);
|
||||||
|
|
||||||
if (fin)
|
if (fin)
|
||||||
htx->flags |= HTX_FL_EOM;
|
htx->flags |= HTX_FL_EOM;
|
||||||
htx_to_buf(htx, appbuf);
|
htx_to_buf(htx, appbuf);
|
||||||
|
Loading…
Reference in New Issue
Block a user