From: Amaury Denoyelle Date: Thu, 30 Nov 2023 13:01:51 +0000 (+0100) Subject: BUG/MINOR: quic_tp: fix preferred_address decoding X-Git-Tag: v2.9-dev12~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a9ad68aa74bbb62b7ae1d8594b9da4489d65bd9e;p=thirdparty%2Fhaproxy.git BUG/MINOR: quic_tp: fix preferred_address decoding quic_transport_param_dec_pref_addr() is responsible to decode preferred_address from received transport parameter. There was two issues with this function : * address and port location as defined in RFC were inverted for both IPv4 and IPv6 during decoding * an invalid check was done to ensure decoded CID length corresponds to remaining buffer size. It did not take into account the final field for stateless reset token. These issues were never encountered as only server can emit preferred_address transport parameter, so the impact of this bug is invisible. This should be backported up to 2.6. --- diff --git a/src/quic_tp.c b/src/quic_tp.c index 5ae4f826b3..eea8a31ddc 100644 --- a/src/quic_tp.c +++ b/src/quic_tp.c @@ -130,27 +130,30 @@ static int quic_transport_param_dec_pref_addr(struct tp_preferred_address *addr, if (end - *buf < addr_len) return 0; - addr->ipv4_port = read_n16(*buf); - *buf += sizeof addr->ipv4_port; - memcpy(addr->ipv4_addr, *buf, sizeof addr->ipv4_addr); *buf += sizeof addr->ipv4_addr; - addr->ipv6_port = read_n16(*buf); - *buf += sizeof addr->ipv6_port; + addr->ipv4_port = read_n16(*buf); + *buf += sizeof addr->ipv4_port; memcpy(addr->ipv6_addr, *buf, sizeof addr->ipv6_addr); *buf += sizeof addr->ipv6_addr; + addr->ipv6_port = read_n16(*buf); + *buf += sizeof addr->ipv6_port; + addr->cid.len = *(*buf)++; if (addr->cid.len) { - if (end - *buf > addr->cid.len || addr->cid.len > sizeof addr->cid.data) + if (end - sizeof(addr->stateless_reset_token) - *buf > addr->cid.len || + addr->cid.len > sizeof(addr->cid.data)) { return 0; + } + memcpy(addr->cid.data, *buf, addr->cid.len); *buf += addr->cid.len; } - if (end - *buf != sizeof addr->stateless_reset_token) + if (end - *buf != sizeof(addr->stateless_reset_token)) return 0; memcpy(addr->stateless_reset_token, *buf, end - *buf);