From d0ea9073fd08a9a37c493cd9b5390574d86def0a Mon Sep 17 00:00:00 2001 From: Dumitru Ceara Date: Fri, 5 Jan 2024 16:27:18 +0100 Subject: [PATCH] pinctrl: dns: Ignore additional additional records. EDNS is backwards compatible so it's safe to just ignore additional ARs. Reported-at: https://github.com/ovn-org/ovn/issues/228 Reported-at: https://issues.redhat.com/browse/FDP-222 Signed-off-by: Dumitru Ceara --- controller/pinctrl.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/controller/pinctrl.c b/controller/pinctrl.c index 12055a6756..f5efd9da14 100644 --- a/controller/pinctrl.c +++ b/controller/pinctrl.c @@ -2872,6 +2872,7 @@ dns_build_ptr_answer( } #define DNS_RCODE_SERVER_REFUSE 0x5 +#define DNS_QUERY_TYPE_CLASS_LEN (2 * sizeof(ovs_be16)) /* Called with in the pinctrl_handler thread context. */ static void @@ -2935,18 +2936,13 @@ pinctrl_handle_dns_lookup( goto exit; } - /* Check if there is an additional record present, which is unsupported */ - if (in_dns_header->arcount) { - VLOG_DBG_RL(&rl, "Received DNS query with additional records, which" - " is unsupported"); - goto exit; - } - struct udp_header *in_udp = dp_packet_l4(pkt_in); size_t udp_len = ntohs(in_udp->udp_len); size_t l4_len = dp_packet_l4_size(pkt_in); + uint8_t *l4_start = (uint8_t *) in_udp; uint8_t *end = (uint8_t *)in_udp + MIN(udp_len, l4_len); uint8_t *in_dns_data = (uint8_t *)(in_dns_header + 1); + uint8_t *in_dns_data_start = in_dns_data; uint8_t *in_queryname = in_dns_data; uint16_t idx = 0; struct ds query_name; @@ -2970,7 +2966,7 @@ pinctrl_handle_dns_lookup( in_dns_data += idx; /* Query should have TYPE and CLASS fields */ - if (in_dns_data + (2 * sizeof(ovs_be16)) > end) { + if (in_dns_data + DNS_QUERY_TYPE_CLASS_LEN > end) { ds_destroy(&query_name); goto exit; } @@ -2984,6 +2980,10 @@ pinctrl_handle_dns_lookup( goto exit; } + uint8_t *rest = in_dns_data + DNS_QUERY_TYPE_CLASS_LEN; + uint32_t query_size = rest - in_dns_data_start; + uint32_t query_l4_size = rest - l4_start; + uint64_t dp_key = ntohll(pin->flow_metadata.flow.metadata); const char *answer_data = NULL; bool ovn_owned = false; @@ -3066,7 +3066,7 @@ pinctrl_handle_dns_lookup( goto exit; } - uint16_t new_l4_size = ntohs(in_udp->udp_len) + dns_answer.size; + uint16_t new_l4_size = query_l4_size + dns_answer.size; size_t new_packet_size = pkt_in->l4_ofs + new_l4_size; struct dp_packet pkt_out; dp_packet_init(&pkt_out, new_packet_size); @@ -3103,7 +3103,7 @@ pinctrl_handle_dns_lookup( out_dns_header->arcount = 0; /* Copy the Query section. */ - dp_packet_put(&pkt_out, dp_packet_data(pkt_in), dp_packet_size(pkt_in)); + dp_packet_put(&pkt_out, dp_packet_data(pkt_in), query_size); /* Copy the answer sections. */ dp_packet_put(&pkt_out, dns_answer.data, dns_answer.size);