/[smeserver]/rpms/djbdns/sme10/200-dnscache-cname-handling.patch
ViewVC logotype

Annotation of /rpms/djbdns/sme10/200-dnscache-cname-handling.patch

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (hide annotations) (download)
Wed Jul 12 03:39:09 2017 UTC (6 years, 10 months ago) by unnilennium
Branch: MAIN
CVS Tags: djbdns-1_05-10_el7_sme, djbdns-1_05-9_el7_sme, djbdns-1_05-11_el7_sme, HEAD
* Tue Jul 11 2017 Jean-Philipe Pialasse <tests@pialasse.com> 1.05-9.sme
--import patches from openwrt and rename already applied patches
--fix security issues [SME: 10374]
- 020-dnsroots-update.patch: update list of root DNS servers
- 070-dnscache-dpos-tcp-servfail.patch: SERVFAIL rename previous patch dns_transmit-bug.patch
- 080-dnscache-cache-negatives.patch: rfc2308 ?
- 210-dnscache-strict-forwardonly.patch: rename previous patch dnscache-strict-forwardonly.patch
- 240-tinydns-alias-chain-truncation.patch: rename previous patch tinydns-alias-chain-truncation.patch
- 270-dnscache-sigpipe-fix.patch: SIGPIPE
- 300-bugfix-dnscache-dempsky-poison.patch: CVE-2009-0858
- 310-bugfix-dnscache-merge-outgoing-requests.patch: CVE-2008-4392
- 320-bugfix-dnscache-cache-soa-records.patch: CVE-2008-4392
- 450-dnscache-ghost-domain-CVE-2012-1191.patch: CVE-2012-1191 http://marc.info/?l=djbdns&m=134190748729079&w=2
--bug fixes [SME: 10374]
- 060-dnscache-big-udp-packets.patch: accept and handle longer than 512 bytes UDP packets
- 230-tinydns-data-semantic-error.patch: handle semantic error to avoid publishing false dns records
--fix issue with short ttl cname like akamaid [SME: 8362]
- 200-dnscache-cname-handling.patch: rename previous patch dnscache-cname-handling.patch
- 330-fix-dnscache-cname-handling.patch: fix dnscache cname for short ttl
- 500-cutom-dnscache-maxloop.patch: set max loop to 200
--needed for previous patches to apply cleanly
- 030-srv-records-and-axfrget.patch: add SRV record type and axfr-get decompose SRC and PTR records (for 230-*.patch)
- 050-tinydns-mmap-leak.patch: report cdb leak
- 080-dnscache-cache-negatives.patch: rfc2308 ?
- 090-tinydns-one-second.patch: improve tinydns with 8 or more  concurent connections (for 240-*.patch)
- 120-compiler-temporary-filename.patch: change tmp filename to avoid conflicts (for 230-*.patch)

1 unnilennium 1.1 --- a/query.c
2     +++ b/query.c
3     @@ -91,6 +91,21 @@ static void cleanup(struct query *z)
4     }
5     }
6    
7     +static int move_name_to_alias(struct query *z,uint32 ttl)
8     +{
9     + int j ;
10     +
11     + if (z->alias[QUERY_MAXALIAS - 1]) return 0 ;
12     + for (j = QUERY_MAXALIAS - 1;j > 0;--j)
13     + z->alias[j] = z->alias[j - 1];
14     + for (j = QUERY_MAXALIAS - 1;j > 0;--j)
15     + z->aliasttl[j] = z->aliasttl[j - 1];
16     + z->alias[0] = z->name[0];
17     + z->aliasttl[0] = ttl;
18     + z->name[0] = 0;
19     + return 1 ;
20     +}
21     +
22     static int rqa(struct query *z)
23     {
24     int i;
25     @@ -123,7 +138,6 @@ static int globalip(char *d,char ip[4])
26     static char *t1 = 0;
27     static char *t2 = 0;
28     static char *t3 = 0;
29     -static char *cname = 0;
30     static char *referral = 0;
31     static unsigned int *records = 0;
32    
33     @@ -179,15 +193,14 @@ static int doit(struct query *z,int stat
34     uint16 datalen;
35     char *control;
36     char *d;
37     + char *owner_name = 0 ;
38     const char *dtype;
39     unsigned int dlen;
40     int flagout;
41     - int flagcname;
42     int flagreferral;
43     int flagsoa;
44     uint32 ttl;
45     uint32 soattl;
46     - uint32 cnamettl;
47     int i;
48     int j;
49     int k;
50     @@ -253,7 +266,10 @@ static int doit(struct query *z,int stat
51    
52     byte_copy(key,2,DNS_T_CNAME);
53     cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
54     - if (cached) {
55     + /* A previous explicit query might have caused an empty RRSet to have been
56     + ** cached. Take care to ignore such a thing.
57     + */
58     + if (cached && cachedlen) {
59     if (typematch(DNS_T_CNAME,dtype)) {
60     log_cachedanswer(d,DNS_T_CNAME);
61     if (!rqa(z)) goto DIE;
62     @@ -262,8 +278,11 @@ static int doit(struct query *z,int stat
63     return 1;
64     }
65     log_cachedcname(d,cached);
66     - if (!dns_domain_copy(&cname,cached)) goto DIE;
67     - goto CNAME;
68     + if (!z->level) {
69     + if (!move_name_to_alias(z,ttl)) goto DIE ;
70     + }
71     + if (!dns_domain_copy(&z->name[z->level],cached)) goto DIE;
72     + goto NEWNAME;
73     }
74    
75     if (typematch(DNS_T_NS,dtype)) {
76     @@ -352,7 +371,7 @@ static int doit(struct query *z,int stat
77     }
78     }
79    
80     - if (!typematch(DNS_T_ANY,dtype) && !typematch(DNS_T_AXFR,dtype) && !typematch(DNS_T_CNAME,dtype) && !typematch(DNS_T_NS,dtype) && !typematch(DNS_T_PTR,dtype) && !typematch(DNS_T_A,dtype) && !typematch(DNS_T_MX,dtype)) {
81     + if (!typematch(DNS_T_ANY,dtype) && !typematch(DNS_T_AXFR,dtype) && !typematch(DNS_T_NS,dtype) && !typematch(DNS_T_PTR,dtype) && !typematch(DNS_T_A,dtype) && !typematch(DNS_T_MX,dtype)) {
82     byte_copy(key,2,dtype);
83     cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
84     if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) {
85     @@ -473,29 +492,31 @@ static int doit(struct query *z,int stat
86    
87     cachettl = 0;
88     flagout = 0;
89     - flagcname = 0;
90     flagreferral = 0;
91     flagsoa = 0;
92     soattl = 0;
93     - cnamettl = 0;
94     + if (!dns_domain_copy(&owner_name,d)) goto DIE;
95     + /* This code assumes that the CNAME chain is presented in the correct
96     + ** order. The example algorithm in RFC 1034 will actually result in this
97     + ** being the case, but the words do not require it to be so.
98     + */
99     for (j = 0;j < numanswers;++j) {
100     pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE;
101     pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
102    
103     - if (dns_domain_equal(t1,d))
104     + if (dns_domain_equal(t1,owner_name))
105     if (byte_equal(header + 2,2,DNS_C_IN)) { /* should always be true */
106     if (typematch(header,dtype))
107     flagout = 1;
108     else if (typematch(header,DNS_T_CNAME)) {
109     - if (!dns_packet_getname(buf,len,pos,&cname)) goto DIE;
110     - flagcname = 1;
111     - cnamettl = ttlget(header + 4);
112     + if (!dns_packet_getname(buf,len,pos,&owner_name)) goto DIE;
113     }
114     }
115    
116     uint16_unpack_big(header + 8,&datalen);
117     pos += datalen;
118     }
119     + dns_domain_free(&owner_name) ;
120     posauthority = pos;
121    
122     for (j = 0;j < numauthority;++j) {
123     @@ -522,15 +543,6 @@ static int doit(struct query *z,int stat
124     }
125     posglue = pos;
126    
127     -
128     - if (!flagcname && !rcode && !flagout && flagreferral && !flagsoa)
129     - if (dns_domain_equal(referral,control) || !dns_domain_suffix(referral,control)) {
130     - log_lame(whichserver,control,referral);
131     - byte_zero(whichserver,4);
132     - goto HAVENS;
133     - }
134     -
135     -
136     if (records) { alloc_free(records); records = 0; }
137    
138     k = numanswers + numauthority + numglue;
139     @@ -677,24 +689,36 @@ static int doit(struct query *z,int stat
140    
141     alloc_free(records); records = 0;
142    
143     + if (byte_diff(DNS_T_CNAME,2,dtype)) {
144     + /* This code assumes that the CNAME chain is presented in the correct
145     + ** order. The example algorithm in RFC 1034 will actually result in this
146     + ** being the case, but the words do not require it to be so.
147     + */
148     + pos = posanswers;
149     + for (j = 0;j < numanswers;++j) {
150     + pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE;
151     + pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
152     +
153     + if (dns_domain_equal(t1,d))
154     + if (byte_equal(header + 2,2,DNS_C_IN)) { /* should always be true */
155     + if (typematch(header,DNS_T_CNAME)) {
156     + ttl = ttlget(header + 4);
157     + if (z->level == 0) {
158     + if (!move_name_to_alias(z,ttl)) goto DIE ;
159     + }
160     + if (!dns_packet_getname(buf,len,pos,&z->name[z->level])) goto DIE;
161     + d = z->name[z->level];
162     + if (!dns_domain_suffix(d,control) || !roots_same(d,control))
163     + goto NEWNAME ; /* Cannot trust the chain further - restart using current name */
164     + }
165     + }
166    
167     - if (flagcname) {
168     - ttl = cnamettl;
169     - CNAME:
170     - if (!z->level) {
171     - if (z->alias[QUERY_MAXALIAS - 1]) goto DIE;
172     - for (j = QUERY_MAXALIAS - 1;j > 0;--j)
173     - z->alias[j] = z->alias[j - 1];
174     - for (j = QUERY_MAXALIAS - 1;j > 0;--j)
175     - z->aliasttl[j] = z->aliasttl[j - 1];
176     - z->alias[0] = z->name[0];
177     - z->aliasttl[0] = ttl;
178     - z->name[0] = 0;
179     + uint16_unpack_big(header + 8,&datalen);
180     + pos += datalen;
181     }
182     - if (!dns_domain_copy(&z->name[z->level],cname)) goto DIE;
183     - goto NEWNAME;
184     }
185    
186     + /* A "no such name" error applies to the end of any CNAME chain, not to the start. */
187     if (rcode == 3) {
188     log_nxdomain(whichserver,d,cachettl);
189     cachegeneric(DNS_T_ANY,d,"",0,cachettl);
190     @@ -707,10 +731,26 @@ static int doit(struct query *z,int stat
191     return 1;
192     }
193    
194     + /* We check for a lame server _after_ we have cached any records that it
195     + ** might have returned to us. This copes better with the incorrect
196     + ** behaviour of one content DNS server software that doesn't return
197     + ** complete CNAME chains but instead returns only the first link in a
198     + ** chain followed by a lame delegation to the same server.
199     + ** Also: We check for a lame server _after_ following the CNAME chain. The
200     + ** delegation in a referral answer applies to the _end_ of the chain, not
201     + ** to the beginning.
202     + */
203     + if (!rcode && !flagout && flagreferral && !flagsoa)
204     + if (dns_domain_equal(referral,control) || !dns_domain_suffix(referral,control)) {
205     + log_lame(whichserver,control,referral);
206     + byte_zero(whichserver,4);
207     + goto HAVENS;
208     + }
209     +
210     if (!flagout && flagsoa)
211     + /* Don't save empty RRSets for those types that we use as special markers. */
212     if (byte_diff(DNS_T_ANY,2,dtype))
213     - if (byte_diff(DNS_T_AXFR,2,dtype))
214     - if (byte_diff(DNS_T_CNAME,2,dtype)) {
215     + if (byte_diff(DNS_T_AXFR,2,dtype)) {
216     save_start();
217     save_finish(dtype,d,soattl);
218     log_nodata(whichserver,d,dtype,soattl);
219     @@ -822,6 +862,7 @@ static int doit(struct query *z,int stat
220     DIE:
221     cleanup(z);
222     if (records) { alloc_free(records); records = 0; }
223     + dns_domain_free(&owner_name) ;
224     return -1;
225     }
226    

admin@koozali.org
ViewVC Help
Powered by ViewVC 1.2.1 RSS 2.0 feed