Rebase to 2.78

Signed-off-by: Petr Menšík <pemensik@redhat.com>
This commit is contained in:
Petr Menšík 2017-10-03 17:30:29 +02:00
parent 35c602043d
commit 1447e0aebc
14 changed files with 10 additions and 781 deletions

1
.gitignore vendored
View File

@ -25,3 +25,4 @@ dnsmasq-2.52.tar.lzma
/dnsmasq-2.76.tar.xz
/dnsmasq-2.77rc2.tar.xz
/dnsmasq-2.77.tar.xz
/dnsmasq-2.78.tar.xz

View File

@ -1,75 +0,0 @@
From 63437ffbb58837b214b4b92cb1c54bc5f3279928 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Wed, 6 Sep 2017 22:34:21 +0100
Subject: [PATCH] Fix CVE-2017-13704, which resulted in a crash on a large DNS
query.
A DNS query recieved by UDP which exceeds 512 bytes (or the EDNS0 packet size,
if different.) is enough to cause SIGSEGV.
---
src/auth.c | 5 -----
src/forward.c | 8 ++++++++
src/rfc1035.c | 5 -----
3 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/src/auth.c b/src/auth.c
index 2c24e16..7f95f98 100644
--- a/src/auth.c
+++ b/src/auth.c
@@ -119,11 +119,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
struct cname *a, *candidate;
unsigned int wclen;
- /* Clear buffer beyond request to avoid risk of
- information disclosure. */
- memset(((char *)header) + qlen, 0,
- (limit - ((char *)header)) - qlen);
-
if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY )
return 0;
diff --git a/src/forward.c b/src/forward.c
index f22556a..e3fa94b 100644
--- a/src/forward.c
+++ b/src/forward.c
@@ -1188,6 +1188,10 @@ void receive_query(struct listener *listen, time_t now)
(msg.msg_flags & MSG_TRUNC) ||
(header->hb3 & HB3_QR))
return;
+
+ /* Clear buffer beyond request to avoid risk of
+ information disclosure. */
+ memset(daemon->packet + n, 0, daemon->edns_pktsz - n);
source_addr.sa.sa_family = listen->family;
@@ -1688,6 +1692,10 @@ unsigned char *tcp_request(int confd, time_t now,
if (size < (int)sizeof(struct dns_header))
continue;
+
+ /* Clear buffer beyond request to avoid risk of
+ information disclosure. */
+ memset(payload + size, 0, 65536 - size);
query_count++;
diff --git a/src/rfc1035.c b/src/rfc1035.c
index 26f5301..af2fe46 100644
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -1223,11 +1223,6 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
struct mx_srv_record *rec;
size_t len;
- /* Clear buffer beyond request to avoid risk of
- information disclosure. */
- memset(((char *)header) + qlen, 0,
- (limit - ((char *)header)) - qlen);
-
if (ntohs(header->ancount) != 0 ||
ntohs(header->nscount) != 0 ||
ntohs(header->qdcount) == 0 ||
--
2.9.5

View File

@ -1,68 +0,0 @@
From 62cb936cb7ad5f219715515ae7d32dd281a5aa1f Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Tue, 26 Sep 2017 22:00:11 +0100
Subject: [PATCH 10/10] Security fix, CVE-2017-14491, DNS heap buffer overflow.
Further fix to 0549c73b7ea6b22a3c49beb4d432f185a81efcbc
Handles case when RR name is not a pointer to the question,
only occurs for some auth-mode replies, therefore not
detected by fuzzing (?)
---
src/rfc1035.c | 27 +++++++++++++++------------
1 file changed, 15 insertions(+), 12 deletions(-)
diff --git a/src/rfc1035.c b/src/rfc1035.c
index 27af023..56ab88b 100644
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -1086,32 +1086,35 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int
va_start(ap, format); /* make ap point to 1st unamed argument */
- /* nameoffset (1 or 2) + type (2) + class (2) + ttl (4) + 0 (2) */
- CHECK_LIMIT(12);
-
if (nameoffset > 0)
{
+ CHECK_LIMIT(2);
PUTSHORT(nameoffset | 0xc000, p);
}
else
{
char *name = va_arg(ap, char *);
- if (name)
- p = do_rfc1035_name(p, name, limit);
- if (!p)
- {
- va_end(ap);
- goto truncated;
- }
-
+ if (name && !(p = do_rfc1035_name(p, name, limit)))
+ {
+ va_end(ap);
+ goto truncated;
+ }
+
if (nameoffset < 0)
{
+ CHECK_LIMIT(2);
PUTSHORT(-nameoffset | 0xc000, p);
}
else
- *p++ = 0;
+ {
+ CHECK_LIMIT(1);
+ *p++ = 0;
+ }
}
+ /* type (2) + class (2) + ttl (4) + rdlen (2) */
+ CHECK_LIMIT(10);
+
PUTSHORT(type, p);
PUTSHORT(class, p);
PUTLONG(ttl, p); /* TTL */
--
2.9.5

View File

@ -1,263 +0,0 @@
From 445282d13b90712ef90d2c2141d0e19bb1d896d2 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Mon, 25 Sep 2017 18:17:11 +0100
Subject: [PATCH] Security fix, CVE-2017-14491 DNS heap buffer overflow.
Fix heap overflow in DNS code. This is a potentially serious
security hole. It allows an attacker who can make DNS
requests to dnsmasq, and who controls the contents of
a domain, which is thereby queried, to overflow
(by 2 bytes) a heap buffer and either crash, or
even take control of, dnsmasq.
(original commit 0549c73b7ea6b22a3c49beb4d432f185a81efcbc)
---
src/dnsmasq.h | 2 +-
src/dnssec.c | 2 +-
src/option.c | 2 +-
src/rfc1035.c | 50 +++++++++++++++++++++++++++++++++++++++++---------
src/rfc2131.c | 4 ++--
src/rfc3315.c | 4 ++--
src/util.c | 7 ++++++-
7 files changed, 54 insertions(+), 17 deletions(-)
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 06fae35..7a18898 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -1179,7 +1179,7 @@ u32 rand32(void);
u64 rand64(void);
int legal_hostname(char *c);
char *canonicalise(char *s, int *nomem);
-unsigned char *do_rfc1035_name(unsigned char *p, char *sval);
+unsigned char *do_rfc1035_name(unsigned char *p, char *sval, char *limit);
void *safe_malloc(size_t size);
void safe_pipe(int *fd, int read_noblock);
void *whine_malloc(size_t size);
diff --git a/src/dnssec.c b/src/dnssec.c
index 3330eef..b6cb55f 100644
--- a/src/dnssec.c
+++ b/src/dnssec.c
@@ -2230,7 +2230,7 @@ size_t dnssec_generate_query(struct dns_header *header, unsigned char *end, char
p = (unsigned char *)(header+1);
- p = do_rfc1035_name(p, name);
+ p = do_rfc1035_name(p, name, NULL);
*p++ = 0;
PUTSHORT(type, p);
PUTSHORT(class, p);
diff --git a/src/option.c b/src/option.c
index 064ef62..22bd19a 100644
--- a/src/option.c
+++ b/src/option.c
@@ -1415,7 +1415,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
}
p = newp;
- end = do_rfc1035_name(p + len, dom);
+ end = do_rfc1035_name(p + len, dom, NULL);
*end++ = 0;
len = end - p;
free(dom);
diff --git a/src/rfc1035.c b/src/rfc1035.c
index 1671883..3397a26 100644
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -1062,6 +1062,7 @@ int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bog
return 0;
}
+
int add_resource_record(struct dns_header *header, char *limit, int *truncp, int nameoffset, unsigned char **pp,
unsigned long ttl, int *offset, unsigned short type, unsigned short class, char *format, ...)
{
@@ -1071,12 +1072,21 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int
unsigned short usval;
long lval;
char *sval;
+#define CHECK_LIMIT(size) \
+ if (limit && p + (size) > (unsigned char*)limit) \
+ { \
+ va_end(ap); \
+ goto truncated; \
+ }
if (truncp && *truncp)
return 0;
-
+
va_start(ap, format); /* make ap point to 1st unamed argument */
-
+
+ /* nameoffset (1 or 2) + type (2) + class (2) + ttl (4) + 0 (2) */
+ CHECK_LIMIT(12);
+
if (nameoffset > 0)
{
PUTSHORT(nameoffset | 0xc000, p);
@@ -1085,7 +1095,13 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int
{
char *name = va_arg(ap, char *);
if (name)
- p = do_rfc1035_name(p, name);
+ p = do_rfc1035_name(p, name, limit);
+ if (!p)
+ {
+ va_end(ap);
+ goto truncated;
+ }
+
if (nameoffset < 0)
{
PUTSHORT(-nameoffset | 0xc000, p);
@@ -1106,6 +1122,7 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int
{
#ifdef HAVE_IPV6
case '6':
+ CHECK_LIMIT(IN6ADDRSZ);
sval = va_arg(ap, char *);
memcpy(p, sval, IN6ADDRSZ);
p += IN6ADDRSZ;
@@ -1113,36 +1130,47 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int
#endif
case '4':
+ CHECK_LIMIT(INADDRSZ);
sval = va_arg(ap, char *);
memcpy(p, sval, INADDRSZ);
p += INADDRSZ;
break;
case 'b':
+ CHECK_LIMIT(1);
usval = va_arg(ap, int);
*p++ = usval;
break;
case 's':
+ CHECK_LIMIT(2);
usval = va_arg(ap, int);
PUTSHORT(usval, p);
break;
case 'l':
+ CHECK_LIMIT(4);
lval = va_arg(ap, long);
PUTLONG(lval, p);
break;
case 'd':
- /* get domain-name answer arg and store it in RDATA field */
- if (offset)
- *offset = p - (unsigned char *)header;
- p = do_rfc1035_name(p, va_arg(ap, char *));
- *p++ = 0;
+ /* get domain-name answer arg and store it in RDATA field */
+ if (offset)
+ *offset = p - (unsigned char *)header;
+ p = do_rfc1035_name(p, va_arg(ap, char *), limit);
+ if (!p)
+ {
+ va_end(ap);
+ goto truncated;
+ }
+ CHECK_LIMIT(1);
+ *p++ = 0;
break;
case 't':
usval = va_arg(ap, int);
+ CHECK_LIMIT(usval);
sval = va_arg(ap, char *);
if (usval != 0)
memcpy(p, sval, usval);
@@ -1154,20 +1182,24 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int
usval = sval ? strlen(sval) : 0;
if (usval > 255)
usval = 255;
+ CHECK_LIMIT(usval + 1);
*p++ = (unsigned char)usval;
memcpy(p, sval, usval);
p += usval;
break;
}
+#undef CHECK_LIMIT
va_end(ap); /* clean up variable argument pointer */
j = p - sav - 2;
- PUTSHORT(j, sav); /* Now, store real RDLength */
+ /* this has already been checked against limit before */
+ PUTSHORT(j, sav); /* Now, store real RDLength */
/* check for overflow of buffer */
if (limit && ((unsigned char *)limit - p) < 0)
{
+truncated:
if (truncp)
*truncp = 1;
return 0;
diff --git a/src/rfc2131.c b/src/rfc2131.c
index a679470..052498c 100644
--- a/src/rfc2131.c
+++ b/src/rfc2131.c
@@ -2454,10 +2454,10 @@ static void do_options(struct dhcp_context *context,
if (fqdn_flags & 0x04)
{
- p = do_rfc1035_name(p, hostname);
+ p = do_rfc1035_name(p, hostname, NULL);
if (domain)
{
- p = do_rfc1035_name(p, domain);
+ p = do_rfc1035_name(p, domain, NULL);
*p++ = 0;
}
}
diff --git a/src/rfc3315.c b/src/rfc3315.c
index 054ecd0..715b6db 100644
--- a/src/rfc3315.c
+++ b/src/rfc3315.c
@@ -1479,10 +1479,10 @@ static struct dhcp_netid *add_options(struct state *state, int do_refresh)
if ((p = expand(len + 2)))
{
*(p++) = state->fqdn_flags;
- p = do_rfc1035_name(p, state->hostname);
+ p = do_rfc1035_name(p, state->hostname, NULL);
if (state->send_domain)
{
- p = do_rfc1035_name(p, state->send_domain);
+ p = do_rfc1035_name(p, state->send_domain, NULL);
*p = 0;
}
}
diff --git a/src/util.c b/src/util.c
index 145e53a..471faa9 100644
--- a/src/util.c
+++ b/src/util.c
@@ -227,15 +227,20 @@ char *canonicalise(char *in, int *nomem)
return ret;
}
-unsigned char *do_rfc1035_name(unsigned char *p, char *sval)
+unsigned char *do_rfc1035_name(unsigned char *p, char *sval, char *limit)
{
int j;
while (sval && *sval)
{
+ if (limit && p + 1 > (unsigned char*)limit)
+ return p;
+
unsigned char *cp = p++;
for (j = 0; *sval && (*sval != '.'); sval++, j++)
{
+ if (limit && p + 1 > (unsigned char*)limit)
+ return p;
#ifdef HAVE_DNSSEC
if (option_bool(OPT_DNSSEC_VALID) && *sval == NAME_ESCAPE)
*p++ = (*(++sval))-1;
--
2.9.5

View File

@ -1,30 +0,0 @@
From 24036ea507862c7b7898b68289c8130f85599c10 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Mon, 25 Sep 2017 18:47:15 +0100
Subject: [PATCH 3/9] Security fix, CVE-2017-14492, DHCPv6 RA heap overflow.
Fix heap overflow in IPv6 router advertisement code.
This is a potentially serious security hole, as a
crafted RA request can overflow a buffer and crash or
control dnsmasq. Attacker must be on the local network.
---
src/radv.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/radv.c b/src/radv.c
index 1032189..9b7e52c 100644
--- a/src/radv.c
+++ b/src/radv.c
@@ -198,6 +198,9 @@ void icmp6_packet(time_t now)
/* look for link-layer address option for logging */
if (sz >= 16 && packet[8] == ICMP6_OPT_SOURCE_MAC && (packet[9] * 8) + 8 <= sz)
{
+ if ((packet[9] * 8 - 2) * 3 - 1 >= MAXDNAME) {
+ return;
+ }
print_mac(daemon->namebuff, &packet[10], (packet[9] * 8) - 2);
mac = daemon->namebuff;
}
--
2.9.5

View File

@ -1,30 +0,0 @@
From 3d4ff1ba8419546490b464418223132529514033 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Mon, 25 Sep 2017 18:52:50 +0100
Subject: [PATCH 4/9] Security fix, CVE-2017-14493, DHCPv6 - Stack buffer
overflow.
Fix stack overflow in DHCPv6 code. An attacker who can send
a DHCPv6 request to dnsmasq can overflow the stack frame and
crash or control dnsmasq.
---
src/rfc3315.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/rfc3315.c b/src/rfc3315.c
index 1687931..920907c 100644
--- a/src/rfc3315.c
+++ b/src/rfc3315.c
@@ -206,6 +206,9 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
/* RFC-6939 */
if ((opt = opt6_find(opts, end, OPTION6_CLIENT_MAC, 3)))
{
+ if (opt6_len(opt) - 2 > DHCP_CHADDR_MAX) {
+ return 0;
+ }
state->mac_type = opt6_uint(opt, 0, 2);
state->mac_len = opt6_len(opt) - 2;
memcpy(&state->mac[0], opt6_ptr(opt, 2), state->mac_len);
--
2.9.5

View File

@ -1,30 +0,0 @@
From 33e3f1029c9ec6c63e430ff51063a6301d4b2262 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Mon, 25 Sep 2017 20:05:11 +0100
Subject: [PATCH 5/9] Security fix, CVE-2017-14494, Infoleak handling DHCPv6
forwarded requests.
Fix information leak in DHCPv6. A crafted DHCPv6 packet can
cause dnsmasq to forward memory from outside the packet
buffer to a DHCPv6 server when acting as a relay.
---
src/rfc3315.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/rfc3315.c b/src/rfc3315.c
index 920907c..4ca43e0 100644
--- a/src/rfc3315.c
+++ b/src/rfc3315.c
@@ -216,6 +216,9 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
for (opt = opts; opt; opt = opt6_next(opt, end))
{
+ if (opt6_ptr(opt, 0) + opt6_len(opt) >= end) {
+ return 0;
+ }
int o = new_opt6(opt6_type(opt));
if (opt6_type(opt) == OPTION6_RELAY_MSG)
{
--
2.9.5

View File

@ -1,41 +0,0 @@
From 51eadb692a5123b9838e5a68ecace3ac579a3a45 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Mon, 25 Sep 2017 20:16:50 +0100
Subject: [PATCH 7/9] Security fix, CVE-2017-14495, OOM in DNS response
creation.
Fix out-of-memory Dos vulnerability. An attacker which can
send malicious DNS queries to dnsmasq can trigger memory
allocations in the add_pseudoheader function
The allocated memory is never freed which leads to a DoS
through memory exhaustion. dnsmasq is vulnerable only
if one of the following option is specified:
--add-mac, --add-cpe-id or --add-subnet.
---
src/edns0.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/edns0.c b/src/edns0.c
index 95b74ee..89b2692 100644
--- a/src/edns0.c
+++ b/src/edns0.c
@@ -192,9 +192,15 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
!(p = skip_section(p,
ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount),
header, plen)))
+ {
+ free(buff);
return plen;
+ }
if (p + 11 > limit)
- return plen; /* Too big */
+ {
+ free(buff);
+ return plen; /* Too big */
+ }
*p++ = 0; /* empty name */
PUTSHORT(T_OPT, p);
PUTSHORT(udp_sz, p); /* max packet length, 512 if not given in EDNS0 header */
--
2.9.5

View File

@ -1,66 +0,0 @@
From 897c113fda0886a28a986cc6ba17bb93bd6cb1c7 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Mon, 25 Sep 2017 20:11:58 +0100
Subject: [PATCH 6/9] Security fix, CVE-2017-14496, Integer underflow in DNS
response creation.
Fix DoS in DNS. Invalid boundary checks in the
add_pseudoheader function allows a memcpy call with negative
size An attacker which can send malicious DNS queries
to dnsmasq can trigger a DoS remotely.
dnsmasq is vulnerable only if one of the following option is
specified: --add-mac, --add-cpe-id or --add-subnet.
---
src/edns0.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/src/edns0.c b/src/edns0.c
index f5b798c..95b74ee 100644
--- a/src/edns0.c
+++ b/src/edns0.c
@@ -144,7 +144,7 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
GETSHORT(len, p);
/* malformed option, delete the whole OPT RR and start again. */
- if (i + len > rdlen)
+ if (i + 4 + len > rdlen)
{
rdlen = 0;
is_last = 0;
@@ -193,6 +193,8 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount),
header, plen)))
return plen;
+ if (p + 11 > limit)
+ return plen; /* Too big */
*p++ = 0; /* empty name */
PUTSHORT(T_OPT, p);
PUTSHORT(udp_sz, p); /* max packet length, 512 if not given in EDNS0 header */
@@ -204,6 +206,11 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
/* Copy back any options */
if (buff)
{
+ if (p + rdlen > limit)
+ {
+ free(buff);
+ return plen; /* Too big */
+ }
memcpy(p, buff, rdlen);
free(buff);
p += rdlen;
@@ -220,8 +227,12 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
/* Add new option */
if (optno != 0 && replace != 2)
{
+ if (p + 4 > limit)
+ return plen; /* Too big */
PUTSHORT(optno, p);
PUTSHORT(optlen, p);
+ if (p + optlen > limit)
+ return plen; /* Too big */
memcpy(p, opt, optlen);
p += optlen;
PUTSHORT(p - datap, lenp);
--
2.9.5

View File

@ -1,44 +0,0 @@
From a3303e196e5d304ec955c4d63afb923ade66c6e8 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Thu, 7 Sep 2017 20:45:00 +0100
Subject: [PATCH] Don't return arcount=1 if EDNS0 RR won't fit in the packet.
Omitting the EDNS0 RR but setting arcount gives a malformed packet.
Also, don't accept UDP packet size less than 512 in recieved EDNS0.
---
src/edns0.c | 5 ++++-
src/forward.c | 2 ++
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/edns0.c b/src/edns0.c
index 3fde17f..f5b798c 100644
--- a/src/edns0.c
+++ b/src/edns0.c
@@ -208,7 +208,10 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
free(buff);
p += rdlen;
}
- header->arcount = htons(ntohs(header->arcount) + 1);
+
+ /* Only bump arcount if RR is going to fit */
+ if (((ssize_t)optlen) <= (limit - (p + 4)))
+ header->arcount = htons(ntohs(header->arcount) + 1);
}
if (((ssize_t)optlen) > (limit - (p + 4)))
diff --git a/src/forward.c b/src/forward.c
index e3fa94b..942b02d 100644
--- a/src/forward.c
+++ b/src/forward.c
@@ -1412,6 +1412,8 @@ void receive_query(struct listener *listen, time_t now)
defaults to 512 */
if (udp_size > daemon->edns_pktsz)
udp_size = daemon->edns_pktsz;
+ else if (udp_size < PACKETSZ)
+ udp_size = PACKETSZ; /* Sanity check - can't reduce below default. RFC 6891 6.2.3 */
}
#ifdef HAVE_AUTH
--
2.9.5

View File

@ -1,63 +0,0 @@
From 6a0b00f0d66490e074323d04782e75c4ba8a3f8d Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Mon, 25 Sep 2017 20:19:55 +0100
Subject: [PATCH 8/9] Misc code cleanups arising from Google analysis. No
security impleications or CVEs.
---
src/edns0.c | 2 +-
src/rfc1035.c | 4 +++-
src/rfc2131.c | 2 +-
3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/edns0.c b/src/edns0.c
index 89b2692..7ed5a47 100644
--- a/src/edns0.c
+++ b/src/edns0.c
@@ -159,7 +159,7 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
/* delete option if we're to replace it. */
p -= 4;
rdlen -= len + 4;
- memcpy(p, p+len+4, rdlen - i);
+ memmove(p, p+len+4, rdlen - i);
PUTSHORT(rdlen, lenp);
lenp -= 2;
}
diff --git a/src/rfc1035.c b/src/rfc1035.c
index 826f8a4..27af023 100644
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -37,7 +37,7 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
/* end marker */
{
/* check that there are the correct no of bytes after the name */
- if (!CHECK_LEN(header, p, plen, extrabytes))
+ if (!CHECK_LEN(header, p1 ? p1 : p, plen, extrabytes))
return 0;
if (isExtract)
@@ -498,6 +498,8 @@ static unsigned char *do_doctor(unsigned char *p, int count, struct dns_header *
{
unsigned int i, len = *p1;
unsigned char *p2 = p1;
+ if ((p1 + len - p) >= rdlen)
+ return 0; /* bad packet */
/* make counted string zero-term and sanitise */
for (i = 0; i < len; i++)
{
diff --git a/src/rfc2131.c b/src/rfc2131.c
index f7c1f80..f3a7e53 100644
--- a/src/rfc2131.c
+++ b/src/rfc2131.c
@@ -157,7 +157,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
for (offset = 0; offset < (len - 5); offset += elen + 5)
{
elen = option_uint(opt, offset + 4 , 1);
- if (option_uint(opt, offset, 4) == BRDBAND_FORUM_IANA)
+ if (option_uint(opt, offset, 4) == BRDBAND_FORUM_IANA && offset + elen + 5 <= len)
{
unsigned char *x = option_ptr(opt, offset + 5);
unsigned char *y = option_ptr(opt, offset + elen + 5);
--
2.9.5

View File

@ -1,44 +0,0 @@
From b476faf1c4f96c093ea1a8a0c824dea9f55b665f Mon Sep 17 00:00:00 2001
From: Christian Hesse <list@eworm.de>
Date: Mon, 25 Sep 2017 17:36:24 +0100
Subject: [PATCH] Do not include stdio.h before dnsmasq.h
We define some constants in dnsmasq.h, which have an influence on
stdio.h. So do not include stdio.h before dnsmasq.h.
---
src/dnsmasq.h | 6 ++++++
src/helper.c | 1 -
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 7a18898..421488b 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -16,6 +16,12 @@
#define COPYRIGHT "Copyright (c) 2000-2016 Simon Kelley"
+/* We do defines that influence behavior of stdio.h, so complain
+ if included too early. */
+#ifdef _STDIO_H
+# error "Header file stdio.h included too early!"
+#endif
+
#ifndef NO_LARGEFILE
/* Ensure we can use files >2GB (log files may grow this big) */
# define _LARGEFILE_SOURCE 1
diff --git a/src/helper.c b/src/helper.c
index 4fffa27..68ce9a7 100644
--- a/src/helper.c
+++ b/src/helper.c
@@ -14,7 +14,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdio.h>
#include "dnsmasq.h"
#ifdef HAVE_SCRIPT
--
2.9.5

View File

@ -12,8 +12,8 @@
%define _hardened_build 1
Name: dnsmasq
Version: 2.77
Release: 9%{?extraversion:.%{extraversion}}%{?dist}
Version: 2.78
Release: 1%{?extraversion:.%{extraversion}}%{?dist}
Summary: A lightweight DHCP/caching DNS server
Group: System Environment/Daemons
@ -22,18 +22,8 @@ URL: http://www.thekelleys.org.uk/dnsmasq/
Source0: http://www.thekelleys.org.uk/dnsmasq/%{?extrapath}%{name}-%{version}%{?extraversion}.tar.xz
Source1: %{name}.service
Patch1: dnsmasq-2.77-CVE-2017-13704.patch
Patch2: dnsmasq-2.77-CVE-2017-14491.patch
Patch3: dnsmasq-2.77-CVE-2017-14492.patch
Patch4: dnsmasq-2.77-CVE-2017-14493.patch
Patch5: dnsmasq-2.77-CVE-2017-14494.patch
Patch6: dnsmasq-2.77-CVE-2017-14496.patch
Patch7: dnsmasq-2.77-CVE-2017-14495.patch
Patch8: dnsmasq-2.77-misc-cleanups.patch
Patch9: dnsmasq-2.77-CVE-2017-14491-2.patch
Patch10: dnsmasq-2.77-stdio.h.patch
Patch11: dnsmasq-2.77-arcount.patch
Patch12: dnsmasq-2.77-underflow.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1495409
Patch1: dnsmasq-2.77-underflow.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@ -68,18 +58,7 @@ query/remove a DHCP server's leases.
%prep
%setup -q -n %{name}-%{version}%{?extraversion}
%patch1 -p1 -b .CVE-2017-13704
%patch2 -p1 -b .CVE-2017-14491
%patch3 -p1 -b .CVE-2017-14492
%patch4 -p1 -b .CVE-2017-14493
%patch5 -p1 -b .CVE-2017-14494
%patch6 -p1 -b .CVE-2017-14496
%patch7 -p1 -b .CVE-2017-14495
%patch8 -p1 -b .misc-cleanups
%patch9 -p1 -b .CVE-2017-14491-2
%patch10 -p1 -b .stdio.h
%patch11 -p1 -b .arcount
%patch12 -p1 -b .underflow
%patch1 -p1 -b .underflow
# use /var/lib/dnsmasq instead of /var/lib/misc
for file in dnsmasq.conf.example man/dnsmasq.8 man/es/dnsmasq.8 src/config.h; do
@ -166,6 +145,9 @@ rm -rf $RPM_BUILD_ROOT
%{_mandir}/man1/dhcp_*
%changelog
* Tue Oct 03 2017 Petr Menšík <pemensik@redhat.com> - 2.78-1
- Rebase to 2.78
* Tue Oct 03 2017 Petr Menšík <pemensik@redhat.com> - 2.77-9
- More patches related to CVE-2017-14491

View File

@ -1 +1 @@
SHA512 (dnsmasq-2.77.tar.xz) = 6ca98a71a8fdfd606e29c58b34dadfa63148c39f931570cca67a287e044d52c6ec2f8acbf5620ada3312e9db3a2fd63877188d829c070beaa730607e3309e768
SHA512 (dnsmasq-2.78.tar.xz) = 9b79b84e5a768d52f90f6335ccef2c404ecd7a13e78e49f4cd0755fffc6cf34d0dc96ad4c72cad1dab3c5743a8d0d789b3e9b6e625b03c5675bb898ca61a698b