diff --git a/CHANGELOG b/CHANGELOG index b3fd0dd..a642b02 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,6 @@ version 2.77 Generate an error when configured with a CNAME loop, - rather than a crash. Thnaks to George Metz for + rather than a crash. Thanks to George Metz for spotting this problem. Calculate the length of TFTP error reply packet @@ -51,6 +51,13 @@ version 2.77 Add DNSMASQ_REQUESTED_OPTIONS environment variable to the lease-change script. Thanks to ZHAO Yu for the patch. + Fix foobar in rrfilter code, that could cause misformed + replies, especially when DNSSEC validation on, and + the upstream server returns answer with the RRs in a + particular order. The only DNS server known to tickle + this is Nominum's. Thanks to Dave Täht for spotting the + bug and assisting in the fix. + version 2.76 Include 0.0.0.0/8 in DNS rebind checks. This range diff --git a/src/rrfilter.c b/src/rrfilter.c index e42d621..a784522 100644 --- a/src/rrfilter.c +++ b/src/rrfilter.c @@ -239,7 +239,15 @@ size_t rrfilter(struct dns_header *header, size_t plen, int mode) if (!check_rrs(p, header, plen, 0, rrs, rr_found)) return plen; - /* Third pass, elide records */ + /* Third pass, actually fix up pointers in the records */ + p = (unsigned char *)(header+1); + + check_name(&p, header, plen, 1, rrs, rr_found); + p += 4; /* qclass, qtype */ + + check_rrs(p, header, plen, 1, rrs, rr_found); + + /* Fouth pass, elide records */ for (p = rrs[0], i = 1; i < rr_found; i += 2) { unsigned char *start = rrs[i]; @@ -254,14 +262,6 @@ size_t rrfilter(struct dns_header *header, size_t plen, int mode) header->nscount = htons(ntohs(header->nscount) - chop_ns); header->arcount = htons(ntohs(header->arcount) - chop_ar); - /* Fourth pass, fix up pointers in the remaining records */ - p = (unsigned char *)(header+1); - - check_name(&p, header, plen, 1, rrs, rr_found); - p += 4; /* qclass, qtype */ - - check_rrs(p, header, plen, 1, rrs, rr_found); - return plen; }