Blame SOURCES/dnsmasq-2.80-dnssec.patch

6484a4
From a997ca0da044719a0ce8a232d14da8b30022592b Mon Sep 17 00:00:00 2001
6484a4
From: Simon Kelley <simon@thekelleys.org.uk>
6484a4
Date: Fri, 29 Jun 2018 14:39:41 +0100
6484a4
Subject: [PATCH] Fix sometimes missing DNSSEC RRs when DNSSEC validation not
6484a4
 enabled.
6484a4
6484a4
Dnsmasq does pass on the do-bit, and return DNSSEC RRs, irrespective
6484a4
of of having DNSSEC validation compiled in or enabled.
6484a4
6484a4
The thing to understand here is that the cache does not store all the
6484a4
DNSSEC RRs, and dnsmasq doesn't have the (very complex) logic required
6484a4
to determine the set of DNSSEC RRs required in an answer. Therefore if
6484a4
the client wants the DNSSEC RRs, the query can not be answered from
6484a4
the cache. When DNSSEC validation is enabled, any query with the
6484a4
do-bit set is never answered from the cache, unless the domain is
6484a4
known not to be signed: the query is always forwarded. This ensures
6484a4
that the DNSEC RRs are included.
6484a4
6484a4
The same thing should be true when DNSSEC validation is not enabled,
6484a4
but there's a bug in the logic.
6484a4
6484a4
line 1666 of src/rfc1035.c looks like this
6484a4
6484a4
 if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) || !do_bit || !(crecp->flags & F_DNSSECOK))
6484a4
6484a4
{ ...answer from cache ... }
6484a4
6484a4
So local stuff (hosts, DHCP, ) get answered. If the do_bit is not set
6484a4
then the query is answered, and if the domain is known not to be
6484a4
signed, the query is answered.
6484a4
6484a4
Unfortunately, if DNSSEC validation is not turned on then the
6484a4
F_DNSSECOK bit is not valid, and it's always zero, so the question
6484a4
always gets answered from the cache, even when the do-bit is set.
6484a4
6484a4
This code should look like that at line 1468, dealing with PTR queries
6484a4
6484a4
  if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
6484a4
      !do_bit ||
6484a4
      (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK)))
6484a4
6484a4
where the F_DNSSECOK bit is only used when validation is enabled.
6484a4
---
6484a4
 src/rfc1035.c | 6 ++++--
6484a4
 1 file changed, 4 insertions(+), 2 deletions(-)
6484a4
6484a4
diff --git a/src/rfc1035.c b/src/rfc1035.c
6484a4
index ebb1f36..580f5ef 100644
6484a4
--- a/src/rfc1035.c
6484a4
+++ b/src/rfc1035.c
6484a4
@@ -1663,7 +1663,9 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
6484a4
 		    }
6484a4
 
6484a4
 		  /* If the client asked for DNSSEC  don't use cached data. */
6484a4
-		  if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) || !do_bit || !(crecp->flags & F_DNSSECOK))
6484a4
+		  if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
6484a4
+		      !do_bit ||
6484a4
+		      (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK)))
6484a4
 		    do
6484a4
 		      { 
6484a4
 			/* don't answer wildcard queries with data not from /etc/hosts
6484a4
@@ -1747,7 +1749,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
6484a4
 	    {
6484a4
 	      if ((crecp = cache_find_by_name(NULL, name, now, F_CNAME | (dryrun ? F_NO_RR : 0))) &&
6484a4
 		  (qtype == T_CNAME || (crecp->flags & F_CONFIG)) &&
6484a4
-		  ((crecp->flags & F_CONFIG) || !do_bit || !(crecp->flags & F_DNSSECOK)))
6484a4
+		  ((crecp->flags & F_CONFIG) || !do_bit || (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK))))
6484a4
 		{
6484a4
 		  if (!(crecp->flags & F_DNSSECOK))
6484a4
 		    sec_data = 0;
6484a4
-- 
6484a4
2.14.4
6484a4