]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: dns: improper parsing of aditional records
authorBaptiste Assmann <bedis9@gmail.com>
Wed, 19 Feb 2020 00:08:51 +0000 (01:08 +0100)
committerWilliam Lallemand <wlallemand@haproxy.org>
Thu, 26 Mar 2020 11:43:36 +0000 (12:43 +0100)
13a9232ebc63fdf357ffcf4fa7a1a5e77a1eac2b introduced parsing of
Additionnal DNS response section to pick up IP address when available.
That said, this introduced a side effect for other query types (A and
AAAA) leading to consider those responses invalid when parsing the
Additional section.
This patch avoids this situation by ensuring the Additional section is
parsed only for SRV queries.

src/dns.c

index 3e52e1731b0ac35e256235468446c0364134dc36..953f9414c41d83a2a17a0f8ead592658d45df64d 100644 (file)
--- a/src/dns.c
+++ b/src/dns.c
@@ -1028,7 +1028,9 @@ static int dns_validate_dns_response(unsigned char *resp, unsigned char *bufend,
        /* Save the number of records we really own */
        dns_p->header.ancount = nb_saved_records;
 
-       /* now parsing additional records */
+       /* now parsing additional records for SRV queries only */
+       if (dns_query->type != DNS_RTYPE_SRV)
+               goto skip_parsing_additional_records;
        nb_saved_records = 0;
        for (i = 0; i < dns_p->header.arcount; i++) {
                if (reader >= bufend)
@@ -1043,25 +1045,7 @@ static int dns_validate_dns_response(unsigned char *resp, unsigned char *bufend,
 
                if (len == 0) {
                        pool_free(dns_answer_item_pool, dns_answer_record);
-                       return DNS_RESP_INVALID;
-               }
-
-               /* Check if the current record dname is valid.  previous_dname
-                * points either to queried dname or last CNAME target */
-               if (dns_query->type != DNS_RTYPE_SRV && memcmp(previous_dname, tmpname, len) != 0) {
-                       pool_free(dns_answer_item_pool, dns_answer_record);
-                       if (i == 0) {
-                               /* First record, means a mismatch issue between
-                                * queried dname and dname found in the first
-                                * record */
-                               return DNS_RESP_INVALID;
-                       }
-                       else {
-                               /* If not the first record, this means we have a
-                                * CNAME resolution error */
-                               return DNS_RESP_CNAME_ERROR;
-                       }
-
+                       continue;
                }
 
                memcpy(dns_answer_record->name, tmpname, len);
@@ -1206,6 +1190,8 @@ static int dns_validate_dns_response(unsigned char *resp, unsigned char *bufend,
                }
        } /* for i 0 to arcount */
 
+ skip_parsing_additional_records:
+
        /* Save the number of records we really own */
        dns_p->header.arcount = nb_saved_records;