diff options
Diffstat (limited to 'package/network/services/dnsmasq/patches/0018-Fix-sometimes-missing-DNSSEC-RRs-when-DNSSEC-validat.patch')
-rw-r--r-- | package/network/services/dnsmasq/patches/0018-Fix-sometimes-missing-DNSSEC-RRs-when-DNSSEC-validat.patch | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/package/network/services/dnsmasq/patches/0018-Fix-sometimes-missing-DNSSEC-RRs-when-DNSSEC-validat.patch b/package/network/services/dnsmasq/patches/0018-Fix-sometimes-missing-DNSSEC-RRs-when-DNSSEC-validat.patch new file mode 100644 index 0000000000..1d75418d07 --- /dev/null +++ b/package/network/services/dnsmasq/patches/0018-Fix-sometimes-missing-DNSSEC-RRs-when-DNSSEC-validat.patch @@ -0,0 +1,87 @@ +From a997ca0da044719a0ce8a232d14da8b30022592b Mon Sep 17 00:00:00 2001 +From: Simon Kelley <simon@thekelleys.org.uk> +Date: Fri, 29 Jun 2018 14:39:41 +0100 +Subject: [PATCH 18/18] Fix sometimes missing DNSSEC RRs when DNSSEC validation + not enabled. + +Dnsmasq does pass on the do-bit, and return DNSSEC RRs, irrespective +of of having DNSSEC validation compiled in or enabled. + +The thing to understand here is that the cache does not store all the +DNSSEC RRs, and dnsmasq doesn't have the (very complex) logic required +to determine the set of DNSSEC RRs required in an answer. Therefore if +the client wants the DNSSEC RRs, the query can not be answered from +the cache. When DNSSEC validation is enabled, any query with the +do-bit set is never answered from the cache, unless the domain is +known not to be signed: the query is always forwarded. This ensures +that the DNSEC RRs are included. + +The same thing should be true when DNSSEC validation is not enabled, +but there's a bug in the logic. + +line 1666 of src/rfc1035.c looks like this + + if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) || !do_bit || !(crecp->flags & F_DNSSECOK)) + +{ ...answer from cache ... } + +So local stuff (hosts, DHCP, ) get answered. If the do_bit is not set +then the query is answered, and if the domain is known not to be +signed, the query is answered. + +Unfortunately, if DNSSEC validation is not turned on then the +F_DNSSECOK bit is not valid, and it's always zero, so the question +always gets answered from the cache, even when the do-bit is set. + +This code should look like that at line 1468, dealing with PTR queries + + if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) || + !do_bit || + (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK))) + +where the F_DNSSECOK bit is only used when validation is enabled. + +Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> +--- + CHANGELOG | 7 ++++++- + src/rfc1035.c | 6 ++++-- + 2 files changed, 10 insertions(+), 3 deletions(-) + +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -33,7 +33,12 @@ version 2.80 + even if auth-sec-servers is not. Thanks to Raphaël Halimi for + the suggestion. + +- ++ Fix bug which sometimes caused dnsmasq to wrongly return answers ++ without DNSSEC RRs to queries with the do-bit set, but only when ++ DNSSEC validation was not enabled. ++ Thanks to Petr Menšík for spotting this. ++ ++ + version 2.79 + Fix parsing of CNAME arguments, which are confused by extra spaces. + Thanks to Diego Aguirre for spotting the bug. +--- a/src/rfc1035.c ++++ b/src/rfc1035.c +@@ -1663,7 +1663,9 @@ size_t answer_request(struct dns_header + } + + /* If the client asked for DNSSEC don't use cached data. */ +- if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) || !do_bit || !(crecp->flags & F_DNSSECOK)) ++ if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) || ++ !do_bit || ++ (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK))) + do + { + /* don't answer wildcard queries with data not from /etc/hosts +@@ -1747,7 +1749,7 @@ size_t answer_request(struct dns_header + { + if ((crecp = cache_find_by_name(NULL, name, now, F_CNAME | (dryrun ? F_NO_RR : 0))) && + (qtype == T_CNAME || (crecp->flags & F_CONFIG)) && +- ((crecp->flags & F_CONFIG) || !do_bit || !(crecp->flags & F_DNSSECOK))) ++ ((crecp->flags & F_CONFIG) || !do_bit || (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK)))) + { + if (!(crecp->flags & F_DNSSECOK)) + sec_data = 0; |