From a9ad68aa74bbb62b7ae1d8594b9da4489d65bd9e Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Thu, 30 Nov 2023 14:01:51 +0100 Subject: [PATCH] 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. --- src/quic_tp.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/quic_tp.c b/src/quic_tp.c index 5ae4f826b..eea8a31dd 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);