Commit 0740e43e authored by Simon Kelley's avatar Simon Kelley

Fix rrfilter bug leading to malformed replies.

Bug tickled by Nominum upstream when DNSSEC enabled, due to
unusual order of RRs in reply from upstream server.
parent 903df07b
version 2.77 version 2.77
Generate an error when configured with a CNAME loop, 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. spotting this problem.
Calculate the length of TFTP error reply packet Calculate the length of TFTP error reply packet
...@@ -51,6 +51,13 @@ version 2.77 ...@@ -51,6 +51,13 @@ version 2.77
Add DNSMASQ_REQUESTED_OPTIONS environment variable to the Add DNSMASQ_REQUESTED_OPTIONS environment variable to the
lease-change script. Thanks to ZHAO Yu for the patch. 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 version 2.76
Include 0.0.0.0/8 in DNS rebind checks. This range Include 0.0.0.0/8 in DNS rebind checks. This range
......
...@@ -239,7 +239,15 @@ size_t rrfilter(struct dns_header *header, size_t plen, int mode) ...@@ -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)) if (!check_rrs(p, header, plen, 0, rrs, rr_found))
return plen; 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) for (p = rrs[0], i = 1; i < rr_found; i += 2)
{ {
unsigned char *start = rrs[i]; unsigned char *start = rrs[i];
...@@ -254,14 +262,6 @@ size_t rrfilter(struct dns_header *header, size_t plen, int mode) ...@@ -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->nscount = htons(ntohs(header->nscount) - chop_ns);
header->arcount = htons(ntohs(header->arcount) - chop_ar); 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; return plen;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment