1d75418d07699644790af9428d4ca83642ab26e0
[openwrt/staging/rmilecki.git] /
1 From a997ca0da044719a0ce8a232d14da8b30022592b Mon Sep 17 00:00:00 2001
2 From: Simon Kelley <simon@thekelleys.org.uk>
3 Date: Fri, 29 Jun 2018 14:39:41 +0100
4 Subject: [PATCH 18/18] Fix sometimes missing DNSSEC RRs when DNSSEC validation
5 not enabled.
6
7 Dnsmasq does pass on the do-bit, and return DNSSEC RRs, irrespective
8 of of having DNSSEC validation compiled in or enabled.
9
10 The thing to understand here is that the cache does not store all the
11 DNSSEC RRs, and dnsmasq doesn't have the (very complex) logic required
12 to determine the set of DNSSEC RRs required in an answer. Therefore if
13 the client wants the DNSSEC RRs, the query can not be answered from
14 the cache. When DNSSEC validation is enabled, any query with the
15 do-bit set is never answered from the cache, unless the domain is
16 known not to be signed: the query is always forwarded. This ensures
17 that the DNSEC RRs are included.
18
19 The same thing should be true when DNSSEC validation is not enabled,
20 but there's a bug in the logic.
21
22 line 1666 of src/rfc1035.c looks like this
23
24 if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) || !do_bit || !(crecp->flags & F_DNSSECOK))
25
26 { ...answer from cache ... }
27
28 So local stuff (hosts, DHCP, ) get answered. If the do_bit is not set
29 then the query is answered, and if the domain is known not to be
30 signed, the query is answered.
31
32 Unfortunately, if DNSSEC validation is not turned on then the
33 F_DNSSECOK bit is not valid, and it's always zero, so the question
34 always gets answered from the cache, even when the do-bit is set.
35
36 This code should look like that at line 1468, dealing with PTR queries
37
38 if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
39 !do_bit ||
40 (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK)))
41
42 where the F_DNSSECOK bit is only used when validation is enabled.
43
44 Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
45 ---
46 CHANGELOG | 7 ++++++-
47 src/rfc1035.c | 6 ++++--
48 2 files changed, 10 insertions(+), 3 deletions(-)
49
50 --- a/CHANGELOG
51 +++ b/CHANGELOG
52 @@ -33,7 +33,12 @@ version 2.80
53 even if auth-sec-servers is not. Thanks to Raphaël Halimi for
54 the suggestion.
55
56 -
57 + Fix bug which sometimes caused dnsmasq to wrongly return answers
58 + without DNSSEC RRs to queries with the do-bit set, but only when
59 + DNSSEC validation was not enabled.
60 + Thanks to Petr Menšík for spotting this.
61 +
62 +
63 version 2.79
64 Fix parsing of CNAME arguments, which are confused by extra spaces.
65 Thanks to Diego Aguirre for spotting the bug.
66 --- a/src/rfc1035.c
67 +++ b/src/rfc1035.c
68 @@ -1663,7 +1663,9 @@ size_t answer_request(struct dns_header
69 }
70
71 /* If the client asked for DNSSEC don't use cached data. */
72 - if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) || !do_bit || !(crecp->flags & F_DNSSECOK))
73 + if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
74 + !do_bit ||
75 + (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK)))
76 do
77 {
78 /* don't answer wildcard queries with data not from /etc/hosts
79 @@ -1747,7 +1749,7 @@ size_t answer_request(struct dns_header
80 {
81 if ((crecp = cache_find_by_name(NULL, name, now, F_CNAME | (dryrun ? F_NO_RR : 0))) &&
82 (qtype == T_CNAME || (crecp->flags & F_CONFIG)) &&
83 - ((crecp->flags & F_CONFIG) || !do_bit || !(crecp->flags & F_DNSSECOK)))
84 + ((crecp->flags & F_CONFIG) || !do_bit || (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK))))
85 {
86 if (!(crecp->flags & F_DNSSECOK))
87 sec_data = 0;