|
1 This patch was derived from a source code patch provided by ISC to |
|
2 resolve ISC ticket RT #43632. [9.6-ESV-R11-S10] |
|
3 |
|
4 --- old/./CHANGES Wed Jan 11 14:12:28 2017 |
|
5 +++ new/./CHANGES Wed Jan 11 14:12:28 2017 |
|
6 @@ -1,5 +1,9 @@ |
|
7 --- 9.6-ESV-R11-S10 released --- |
|
8 |
|
9 +4517. [security] Named could mishandle authority sections that were |
|
10 + missing RRSIGs triggering an assertion failure. |
|
11 + (CVE-2016-9444) [RT #43632] |
|
12 + |
|
13 4510. [security] Named mishandled some responses where covering RRSIG |
|
14 records are returned without the requested data |
|
15 resulting in a assertion failure. (CVE-2016-9147) |
|
16 --- old/lib/dns/api Wed Jan 11 14:12:28 2017 |
|
17 +++ new/lib/dns/api Wed Jan 11 14:12:28 2017 |
|
18 @@ -5,5 +5,5 @@ |
|
19 # 9.9: 90-109 |
|
20 # 9.9-sub: 130-139 |
|
21 LIBINTERFACE = 114 |
|
22 -LIBREVISION = 4 |
|
23 +LIBREVISION = 5 |
|
24 LIBAGE = 1 |
|
25 --- old/lib/dns/message.c Wed Jan 11 14:12:28 2017 |
|
26 +++ new/lib/dns/message.c Wed Jan 11 14:12:28 2017 |
|
27 @@ -1169,6 +1169,63 @@ |
|
28 return (ISC_FALSE); |
|
29 } |
|
30 |
|
31 +/* |
|
32 + * Check to confirm that all DNSSEC records (DS, NSEC, NSEC3) have |
|
33 + * covering RRSIGs. |
|
34 + */ |
|
35 +static isc_boolean_t |
|
36 +auth_signed(dns_namelist_t *section) { |
|
37 + dns_name_t *name; |
|
38 + |
|
39 + for (name = ISC_LIST_HEAD(*section); |
|
40 + name != NULL; |
|
41 + name = ISC_LIST_NEXT(name, link)) |
|
42 + { |
|
43 + int auth_dnssec = 0, auth_rrsig = 0; |
|
44 + dns_rdataset_t *rds; |
|
45 + |
|
46 + for (rds = ISC_LIST_HEAD(name->list); |
|
47 + rds != NULL; |
|
48 + rds = ISC_LIST_NEXT(rds, link)) |
|
49 + { |
|
50 + switch (rds->type) { |
|
51 + case dns_rdatatype_ds: |
|
52 + auth_dnssec |= 0x1; |
|
53 + break; |
|
54 + case dns_rdatatype_nsec: |
|
55 + auth_dnssec |= 0x2; |
|
56 + break; |
|
57 + case dns_rdatatype_nsec3: |
|
58 + auth_dnssec |= 0x4; |
|
59 + break; |
|
60 + case dns_rdatatype_rrsig: |
|
61 + break; |
|
62 + default: |
|
63 + continue; |
|
64 + } |
|
65 + |
|
66 + switch (rds->covers) { |
|
67 + case dns_rdatatype_ds: |
|
68 + auth_rrsig |= 0x1; |
|
69 + break; |
|
70 + case dns_rdatatype_nsec: |
|
71 + auth_rrsig |= 0x2; |
|
72 + break; |
|
73 + case dns_rdatatype_nsec3: |
|
74 + auth_rrsig |= 0x4; |
|
75 + break; |
|
76 + default: |
|
77 + break; |
|
78 + } |
|
79 + } |
|
80 + |
|
81 + if (auth_dnssec != auth_rrsig) |
|
82 + return (ISC_FALSE); |
|
83 + } |
|
84 + |
|
85 + return (ISC_TRUE); |
|
86 +} |
|
87 + |
|
88 static isc_result_t |
|
89 getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, |
|
90 dns_section_t sectionid, unsigned int options) |
|
91 @@ -1194,12 +1251,12 @@ |
|
92 best_effort = ISC_TF(options & DNS_MESSAGEPARSE_BESTEFFORT); |
|
93 seen_problem = ISC_FALSE; |
|
94 |
|
95 + section = &msg->sections[sectionid]; |
|
96 + |
|
97 for (count = 0; count < msg->counts[sectionid]; count++) { |
|
98 int recstart = source->current; |
|
99 isc_boolean_t skip_name_search, skip_type_search; |
|
100 |
|
101 - section = &msg->sections[sectionid]; |
|
102 - |
|
103 skip_name_search = ISC_FALSE; |
|
104 skip_type_search = ISC_FALSE; |
|
105 free_rdataset = ISC_FALSE; |
|
106 @@ -1372,7 +1429,7 @@ |
|
107 goto cleanup; |
|
108 rdata->rdclass = rdclass; |
|
109 issigzero = ISC_FALSE; |
|
110 - if (rdtype == dns_rdatatype_rrsig && |
|
111 + if (rdtype == dns_rdatatype_rrsig && |
|
112 rdata->flags == 0) { |
|
113 covers = dns_rdata_covers(rdata); |
|
114 if (covers == 0) |
|
115 @@ -1577,6 +1634,19 @@ |
|
116 INSIST(free_rdataset == ISC_FALSE); |
|
117 } |
|
118 |
|
119 + /* |
|
120 + * If any of DS, NSEC or NSEC3 appeared in the |
|
121 + * authority section of a query response without |
|
122 + * a covering RRSIG, FORMERR |
|
123 + */ |
|
124 + if (sectionid == DNS_SECTION_AUTHORITY && |
|
125 + msg->opcode == dns_opcode_query && |
|
126 + ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) && |
|
127 + ((msg->flags & DNS_MESSAGEFLAG_TC) == 0) && |
|
128 + !preserve_order && |
|
129 + !auth_signed(section)) |
|
130 + DO_FORMERR; |
|
131 + |
|
132 if (seen_problem) |
|
133 return (DNS_R_RECOVERABLE); |
|
134 return (ISC_R_SUCCESS); |
|
135 --- old/lib/dns/resolver.c Wed Jan 11 14:12:30 2017 |
|
136 +++ new/lib/dns/resolver.c Wed Jan 11 14:12:29 2017 |
|
137 @@ -4766,13 +4766,9 @@ |
|
138 rdataset->type, |
|
139 &noqname); |
|
140 if (tresult == ISC_R_SUCCESS && |
|
141 - noqname != NULL) { |
|
142 - tresult = |
|
143 - dns_rdataset_addnoqname( |
|
144 + noqname != NULL) |
|
145 + (void) dns_rdataset_addnoqname( |
|
146 rdataset, noqname); |
|
147 - RUNTIME_CHECK(tresult == |
|
148 - ISC_R_SUCCESS); |
|
149 - } |
|
150 } |
|
151 addedrdataset = ardataset; |
|
152 result = dns_db_addrdataset(fctx->cache, node, |
|
153 @@ -4902,11 +4898,9 @@ |
|
154 tresult = findnoqname(fctx, name, |
|
155 rdataset->type, &noqname); |
|
156 if (tresult == ISC_R_SUCCESS && |
|
157 - noqname != NULL) { |
|
158 - tresult = dns_rdataset_addnoqname( |
|
159 - rdataset, noqname); |
|
160 - RUNTIME_CHECK(tresult == ISC_R_SUCCESS); |
|
161 - } |
|
162 + noqname != NULL) |
|
163 + (void) dns_rdataset_addnoqname( |
|
164 + rdataset, noqname); |
|
165 } |
|
166 |
|
167 /* |
|
168 --- old/./version Wed Jan 11 14:12:30 2017 |
|
169 +++ new/./version Wed Jan 11 14:12:29 2017 |
|
170 @@ -10,4 +10,4 @@ |
|
171 PATCHVER= |
|
172 RELEASETYPE=-ESV |
|
173 RELEASEVER=-R11 |
|
174 -EXTENSIONS=-S9 |
|
175 +EXTENSIONS=-S10 |