Merge ~alfonsosanchezbeato/snappy-hwe-snaps/+git/wifi-ap:dnsmasq/2.75 into ~snappy-hwe-team/snappy-hwe-snaps/+git/wifi-ap:dnsmasq/2.75

Proposed by Alfonso Sanchez-Beato on 2019-05-29
Status: Merged
Approved by: Konrad Zapałowicz on 2019-05-29
Approved revision: 25accfdecc8e2ad5001d341e40cce2040859018a
Merged at revision: 59e878ad0bc3a2787d8d4b5f4fed3699212b49b1
Proposed branch: ~alfonsosanchezbeato/snappy-hwe-snaps/+git/wifi-ap:dnsmasq/2.75
Merge into: ~snappy-hwe-team/snappy-hwe-snaps/+git/wifi-ap:dnsmasq/2.75
Diff against target: 452 lines (+108/-26)
12 files modified
src/cache.c (+1/-1)
src/dnsmasq.h (+2/-1)
src/dnssec.c (+1/-1)
src/forward.c (+2/-1)
src/network.c (+30/-2)
src/option.c (+1/-1)
src/radv.c (+3/-0)
src/rfc1035.c (+49/-12)
src/rfc2131.c (+3/-3)
src/rfc3315.c (+8/-2)
src/util.c (+6/-1)
trust-anchors.conf (+2/-1)
Reviewer Review Type Date Requested Status
Alfonso Sanchez-Beato continuous-integration Approve on 2019-05-29
System Enablement Bot continuous-integration Needs Fixing on 2019-05-29
Konrad Zapałowicz (community) 2019-05-29 Approve on 2019-05-29
Review via email: mp+368037@code.launchpad.net

Commit message

Update to ubuntu package 2.75-1ubuntu0.16.04.5

Several bug fixes and USNs solved, including 3009-1, 3430-1, and 3716-1.
Changes applied from
http://archive.ubuntu.com/ubuntu/pool/main/d/dnsmasq/dnsmasq_2.75-1ubuntu0.16.04.5.diff.gz

Description of the change

Update to ubuntu package 2.75-1ubuntu0.16.04.5

Several bug fixes and USNs solved, including 3009-1, 3430-1, and 3716-1.
Changes applied from
http://archive.ubuntu.com/ubuntu/pool/main/d/dnsmasq/dnsmasq_2.75-1ubuntu0.16.04.5.diff.gz

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/cache.c b/src/cache.c
2index 178d654..1b76b67 100644
3--- a/src/cache.c
4+++ b/src/cache.c
5@@ -481,7 +481,7 @@ struct crec *cache_insert(char *name, struct all_addr *addr,
6 existing record is for an A or AAAA and
7 the record we're trying to insert is the same,
8 just drop the insert, but don't error the whole process. */
9- if ((flags & (F_IPV4 | F_IPV6)) && (flags & F_FORWARD))
10+ if ((flags & (F_IPV4 | F_IPV6)) && (flags & F_FORWARD) && addr)
11 {
12 if ((flags & F_IPV4) && (new->flags & F_IPV4) &&
13 new->addr.addr.addr.addr4.s_addr == addr->addr.addr4.s_addr)
14diff --git a/src/dnsmasq.h b/src/dnsmasq.h
15index cf1a782..e021612 100644
16--- a/src/dnsmasq.h
17+++ b/src/dnsmasq.h
18@@ -492,6 +492,7 @@ struct serverfd {
19 int fd;
20 union mysockaddr source_addr;
21 char interface[IF_NAMESIZE+1];
22+ unsigned int ifindex, used;
23 struct serverfd *next;
24 };
25
26@@ -1169,7 +1170,7 @@ u32 rand32(void);
27 u64 rand64(void);
28 int legal_hostname(char *c);
29 char *canonicalise(char *s, int *nomem);
30-unsigned char *do_rfc1035_name(unsigned char *p, char *sval);
31+unsigned char *do_rfc1035_name(unsigned char *p, char *sval, char *limit);
32 void *safe_malloc(size_t size);
33 void safe_pipe(int *fd, int read_noblock);
34 void *whine_malloc(size_t size);
35diff --git a/src/dnssec.c b/src/dnssec.c
36index 4deda24..830f304 100644
37--- a/src/dnssec.c
38+++ b/src/dnssec.c
39@@ -2264,7 +2264,7 @@ size_t dnssec_generate_query(struct dns_header *header, char *end, char *name, i
40
41 p = (unsigned char *)(header+1);
42
43- p = do_rfc1035_name(p, name);
44+ p = do_rfc1035_name(p, name, NULL);
45 *p++ = 0;
46 PUTSHORT(type, p);
47 PUTSHORT(class, p);
48diff --git a/src/forward.c b/src/forward.c
49index 2731b90..959356c 100644
50--- a/src/forward.c
51+++ b/src/forward.c
52@@ -810,7 +810,8 @@ void reply_query(int fd, int family, time_t now)
53 we get a good reply from another server. Kill it when we've
54 had replies from all to avoid filling the forwarding table when
55 everything is broken */
56- if (forward->forwardall == 0 || --forward->forwardall == 1 || RCODE(header) != SERVFAIL)
57+ if (forward->forwardall == 0 || --forward->forwardall == 1 ||
58+ (RCODE(header) != REFUSED && RCODE(header) != SERVFAIL))
59 {
60 int check_rebind = 0, no_cache_dnssec = 0, cache_secure = 0, bogusanswer = 0;
61
62diff --git a/src/network.c b/src/network.c
63index a1d90c8..b8ebd55 100644
64--- a/src/network.c
65+++ b/src/network.c
66@@ -1191,6 +1191,7 @@ int local_bind(int fd, union mysockaddr *addr, char *intname, int is_tcp)
67 static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
68 {
69 struct serverfd *sfd;
70+ unsigned int ifindex = 0;
71 int errsave;
72
73 /* when using random ports, servers which would otherwise use
74@@ -1211,11 +1212,15 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
75 return NULL;
76 #endif
77 }
78+
79+ if (intname && strlen(intname) != 0)
80+ ifindex = if_nametoindex(intname); /* index == 0 when not binding to an interface */
81
82 /* may have a suitable one already */
83 for (sfd = daemon->sfds; sfd; sfd = sfd->next )
84 if (sockaddr_isequal(&sfd->source_addr, addr) &&
85- strcmp(intname, sfd->interface) == 0)
86+ strcmp(intname, sfd->interface) == 0 &&
87+ ifindex == sfd->ifindex)
88 return sfd;
89
90 /* need to make a new one. */
91@@ -1237,11 +1242,13 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
92 errno = errsave;
93 return NULL;
94 }
95-
96+
97 strcpy(sfd->interface, intname);
98 sfd->source_addr = *addr;
99 sfd->next = daemon->sfds;
100+ sfd->ifindex = ifindex;
101 daemon->sfds = sfd;
102+
103 return sfd;
104 }
105
106@@ -1417,12 +1424,16 @@ void check_servers(void)
107 {
108 struct irec *iface;
109 struct server *serv;
110+ struct serverfd *sfd, *tmp, **up;
111 int port = 0;
112
113 /* interface may be new since startup */
114 if (!option_bool(OPT_NOWILD))
115 enumerate_interfaces(0);
116
117+ for (sfd = daemon->sfds; sfd; sfd = sfd->next)
118+ sfd->used = 0;
119+
120 for (serv = daemon->servers; serv; serv = serv->next)
121 {
122 if (!(serv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)))
123@@ -1458,6 +1469,9 @@ void check_servers(void)
124 serv->flags |= SERV_MARK;
125 continue;
126 }
127+
128+ if (serv->sfd)
129+ serv->sfd->used = 1;
130 }
131
132 if (!(serv->flags & SERV_NO_REBIND) && !(serv->flags & SERV_LITERAL_ADDRESS))
133@@ -1490,6 +1504,20 @@ void check_servers(void)
134 }
135 }
136
137+ /* Remove unused sfds */
138+ for (sfd = daemon->sfds, up = &daemon->sfds; sfd; sfd = tmp)
139+ {
140+ tmp = sfd->next;
141+ if (!sfd->used)
142+ {
143+ *up = sfd->next;
144+ close(sfd->fd);
145+ free(sfd);
146+ }
147+ else
148+ up = &sfd->next;
149+ }
150+
151 cleanup_servers();
152 }
153
154diff --git a/src/option.c b/src/option.c
155index ecc2619..ed204fb 100644
156--- a/src/option.c
157+++ b/src/option.c
158@@ -1348,7 +1348,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
159 }
160
161 p = newp;
162- end = do_rfc1035_name(p + len, dom);
163+ end = do_rfc1035_name(p + len, dom, NULL);
164 *end++ = 0;
165 len = end - p;
166 free(dom);
167diff --git a/src/radv.c b/src/radv.c
168index 39f1e92..9db0095 100644
169--- a/src/radv.c
170+++ b/src/radv.c
171@@ -197,6 +197,9 @@ void icmp6_packet(time_t now)
172 /* look for link-layer address option for logging */
173 if (sz >= 16 && packet[8] == ICMP6_OPT_SOURCE_MAC && (packet[9] * 8) + 8 <= sz)
174 {
175+ if ((packet[9] * 8 - 2) * 3 - 1 >= MAXDNAME) {
176+ return;
177+ }
178 print_mac(daemon->namebuff, &packet[10], (packet[9] * 8) - 2);
179 mac = daemon->namebuff;
180 }
181diff --git a/src/rfc1035.c b/src/rfc1035.c
182index 56647b0..9456f2a 100644
183--- a/src/rfc1035.c
184+++ b/src/rfc1035.c
185@@ -37,7 +37,7 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
186 /* end marker */
187 {
188 /* check that there are the correct no of bytes after the name */
189- if (!CHECK_LEN(header, p, plen, extrabytes))
190+ if (!CHECK_LEN(header, p1 ? p1 : p, plen, extrabytes))
191 return 0;
192
193 if (isExtract)
194@@ -794,6 +794,8 @@ static unsigned char *do_doctor(unsigned char *p, int count, struct dns_header *
195 {
196 unsigned int i, len = *p1;
197 unsigned char *p2 = p1;
198+ if ((p1 + len - p) >= rdlen)
199+ return 0; /* bad packet */
200 /* make counted string zero-term and sanitise */
201 for (i = 0; i < len; i++)
202 {
203@@ -1362,6 +1364,7 @@ int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bog
204 return 0;
205 }
206
207+
208 int add_resource_record(struct dns_header *header, char *limit, int *truncp, int nameoffset, unsigned char **pp,
209 unsigned long ttl, int *offset, unsigned short type, unsigned short class, char *format, ...)
210 {
211@@ -1371,29 +1374,47 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int
212 unsigned short usval;
213 long lval;
214 char *sval;
215+#define CHECK_LIMIT(size) \
216+ if (limit && p + (size) > (unsigned char*)limit) \
217+ { \
218+ va_end(ap); \
219+ goto truncated; \
220+ }
221
222 if (truncp && *truncp)
223 return 0;
224-
225+
226 va_start(ap, format); /* make ap point to 1st unamed argument */
227-
228+
229 if (nameoffset > 0)
230 {
231+ CHECK_LIMIT(2);
232 PUTSHORT(nameoffset | 0xc000, p);
233 }
234 else
235 {
236 char *name = va_arg(ap, char *);
237- if (name)
238- p = do_rfc1035_name(p, name);
239+ if (name && !(p = do_rfc1035_name(p, name, limit)))
240+ {
241+ va_end(ap);
242+ goto truncated;
243+ }
244+
245 if (nameoffset < 0)
246 {
247+ CHECK_LIMIT(2);
248 PUTSHORT(-nameoffset | 0xc000, p);
249 }
250 else
251- *p++ = 0;
252+ {
253+ CHECK_LIMIT(1);
254+ *p++ = 0;
255+ }
256 }
257
258+ /* type (2) + class (2) + ttl (4) + rdlen (2) */
259+ CHECK_LIMIT(10);
260+
261 PUTSHORT(type, p);
262 PUTSHORT(class, p);
263 PUTLONG(ttl, p); /* TTL */
264@@ -1406,6 +1427,7 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int
265 {
266 #ifdef HAVE_IPV6
267 case '6':
268+ CHECK_LIMIT(IN6ADDRSZ);
269 sval = va_arg(ap, char *);
270 memcpy(p, sval, IN6ADDRSZ);
271 p += IN6ADDRSZ;
272@@ -1413,36 +1435,47 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int
273 #endif
274
275 case '4':
276+ CHECK_LIMIT(INADDRSZ);
277 sval = va_arg(ap, char *);
278 memcpy(p, sval, INADDRSZ);
279 p += INADDRSZ;
280 break;
281
282 case 'b':
283+ CHECK_LIMIT(1);
284 usval = va_arg(ap, int);
285 *p++ = usval;
286 break;
287
288 case 's':
289+ CHECK_LIMIT(2);
290 usval = va_arg(ap, int);
291 PUTSHORT(usval, p);
292 break;
293
294 case 'l':
295+ CHECK_LIMIT(4);
296 lval = va_arg(ap, long);
297 PUTLONG(lval, p);
298 break;
299
300 case 'd':
301- /* get domain-name answer arg and store it in RDATA field */
302- if (offset)
303- *offset = p - (unsigned char *)header;
304- p = do_rfc1035_name(p, va_arg(ap, char *));
305- *p++ = 0;
306+ /* get domain-name answer arg and store it in RDATA field */
307+ if (offset)
308+ *offset = p - (unsigned char *)header;
309+ p = do_rfc1035_name(p, va_arg(ap, char *), limit);
310+ if (!p)
311+ {
312+ va_end(ap);
313+ goto truncated;
314+ }
315+ CHECK_LIMIT(1);
316+ *p++ = 0;
317 break;
318
319 case 't':
320 usval = va_arg(ap, int);
321+ CHECK_LIMIT(usval);
322 sval = va_arg(ap, char *);
323 if (usval != 0)
324 memcpy(p, sval, usval);
325@@ -1454,20 +1487,24 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int
326 usval = sval ? strlen(sval) : 0;
327 if (usval > 255)
328 usval = 255;
329+ CHECK_LIMIT(usval + 1);
330 *p++ = (unsigned char)usval;
331 memcpy(p, sval, usval);
332 p += usval;
333 break;
334 }
335
336+#undef CHECK_LIMIT
337 va_end(ap); /* clean up variable argument pointer */
338
339 j = p - sav - 2;
340- PUTSHORT(j, sav); /* Now, store real RDLength */
341+ /* this has already been checked against limit before */
342+ PUTSHORT(j, sav); /* Now, store real RDLength */
343
344 /* check for overflow of buffer */
345 if (limit && ((unsigned char *)limit - p) < 0)
346 {
347+truncated:
348 if (truncp)
349 *truncp = 1;
350 return 0;
351diff --git a/src/rfc2131.c b/src/rfc2131.c
352index 9f69ed5..a8ccf86 100644
353--- a/src/rfc2131.c
354+++ b/src/rfc2131.c
355@@ -155,7 +155,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
356 for (offset = 0; offset < (len - 5); offset += elen + 5)
357 {
358 elen = option_uint(opt, offset + 4 , 1);
359- if (option_uint(opt, offset, 4) == BRDBAND_FORUM_IANA)
360+ if (option_uint(opt, offset, 4) == BRDBAND_FORUM_IANA && offset + elen + 5 <= len)
361 {
362 unsigned char *x = option_ptr(opt, offset + 5);
363 unsigned char *y = option_ptr(opt, offset + elen + 5);
364@@ -2352,10 +2352,10 @@ static void do_options(struct dhcp_context *context,
365
366 if (fqdn_flags & 0x04)
367 {
368- p = do_rfc1035_name(p, hostname);
369+ p = do_rfc1035_name(p, hostname, NULL);
370 if (domain)
371 {
372- p = do_rfc1035_name(p, domain);
373+ p = do_rfc1035_name(p, domain, NULL);
374 *p++ = 0;
375 }
376 }
377diff --git a/src/rfc3315.c b/src/rfc3315.c
378index 2665d0d..99226a1 100644
379--- a/src/rfc3315.c
380+++ b/src/rfc3315.c
381@@ -206,6 +206,9 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
382 /* RFC-6939 */
383 if ((opt = opt6_find(opts, end, OPTION6_CLIENT_MAC, 3)))
384 {
385+ if (opt6_len(opt) - 2 > DHCP_CHADDR_MAX) {
386+ return 0;
387+ }
388 state->mac_type = opt6_uint(opt, 0, 2);
389 state->mac_len = opt6_len(opt) - 2;
390 memcpy(&state->mac[0], opt6_ptr(opt, 2), state->mac_len);
391@@ -213,6 +216,9 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
392
393 for (opt = opts; opt; opt = opt6_next(opt, end))
394 {
395+ if (opt6_ptr(opt, 0) + opt6_len(opt) >= end) {
396+ return 0;
397+ }
398 int o = new_opt6(opt6_type(opt));
399 if (opt6_type(opt) == OPTION6_RELAY_MSG)
400 {
401@@ -1472,10 +1478,10 @@ static struct dhcp_netid *add_options(struct state *state, int do_refresh)
402 if ((p = expand(len + 2)))
403 {
404 *(p++) = state->fqdn_flags;
405- p = do_rfc1035_name(p, state->hostname);
406+ p = do_rfc1035_name(p, state->hostname, NULL);
407 if (state->send_domain)
408 {
409- p = do_rfc1035_name(p, state->send_domain);
410+ p = do_rfc1035_name(p, state->send_domain, NULL);
411 *p = 0;
412 }
413 }
414diff --git a/src/util.c b/src/util.c
415index 469eaed..b70ad65 100644
416--- a/src/util.c
417+++ b/src/util.c
418@@ -218,15 +218,20 @@ char *canonicalise(char *in, int *nomem)
419 return ret;
420 }
421
422-unsigned char *do_rfc1035_name(unsigned char *p, char *sval)
423+unsigned char *do_rfc1035_name(unsigned char *p, char *sval, char *limit)
424 {
425 int j;
426
427 while (sval && *sval)
428 {
429+ if (limit && p + 1 > (unsigned char*)limit)
430+ return p;
431+
432 unsigned char *cp = p++;
433 for (j = 0; *sval && (*sval != '.'); sval++, j++)
434 {
435+ if (limit && p + 1 > (unsigned char*)limit)
436+ return p;
437 #ifdef HAVE_DNSSEC
438 if (option_bool(OPT_DNSSEC_VALID) && *sval == NAME_ESCAPE)
439 *p++ = (*(++sval))-1;
440diff --git a/trust-anchors.conf b/trust-anchors.conf
441index afda518..6f807cf 100644
442--- a/trust-anchors.conf
443+++ b/trust-anchors.conf
444@@ -1,9 +1,10 @@
445-# The root DNSSEC trust anchor, valid as at 30/01/2014
446+# The root DNSSEC trust anchor, valid as at 10/02/2017
447
448 # Note that this is a DS record (ie a hash of the root Zone Signing Key)
449 # If was downloaded from https://data.iana.org/root-anchors/root-anchors.xml
450
451 trust-anchor=.,19036,8,2,49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5
452+trust-anchor=.,20326,8,2,E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D
453
454
455

Subscribers

People subscribed via source and target branches