From a030263eaa371759f07f08600d9f7d69d0ac6596 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Oct 02 2017 13:35:23 +0000 Subject: import dnsmasq-2.76-2.el7_4.2 --- diff --git a/SOURCES/dnsmasq-2.76-CVE-2017-14491-2.patch b/SOURCES/dnsmasq-2.76-CVE-2017-14491-2.patch new file mode 100644 index 0000000..3935566 --- /dev/null +++ b/SOURCES/dnsmasq-2.76-CVE-2017-14491-2.patch @@ -0,0 +1,68 @@ +From 62cb936cb7ad5f219715515ae7d32dd281a5aa1f Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Tue, 26 Sep 2017 22:00:11 +0100 +Subject: 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.7.4 + diff --git a/SOURCES/dnsmasq-2.76-CVE-2017-14491.patch b/SOURCES/dnsmasq-2.76-CVE-2017-14491.patch new file mode 100644 index 0000000..4d8dbd5 --- /dev/null +++ b/SOURCES/dnsmasq-2.76-CVE-2017-14491.patch @@ -0,0 +1,262 @@ +From 8868a04895b27d42d42e364f1a0c0196c1505b04 Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Mon, 25 Sep 2017 18:17:11 +0100 +Subject: [PATCH 1/9] 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. +--- + 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 1179492..06e5579 100644 +--- a/src/dnsmasq.h ++++ b/src/dnsmasq.h +@@ -1162,7 +1162,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 3c77c7d..f45c804 100644 +--- a/src/dnssec.c ++++ b/src/dnssec.c +@@ -2227,7 +2227,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 eb78b1a..3469f53 100644 +--- a/src/option.c ++++ b/src/option.c +@@ -1378,7 +1378,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 24d08c1..78410d6 100644 +--- a/src/rfc1035.c ++++ b/src/rfc1035.c +@@ -1049,6 +1049,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, ...) + { +@@ -1058,12 +1059,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); +@@ -1072,7 +1082,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); +@@ -1093,6 +1109,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; +@@ -1100,36 +1117,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); +@@ -1141,20 +1169,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 8b99d4b..75893a6 100644 +--- a/src/rfc2131.c ++++ b/src/rfc2131.c +@@ -2420,10 +2420,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 3f4d69c..73bdee4 100644 +--- a/src/rfc3315.c ++++ b/src/rfc3315.c +@@ -1472,10 +1472,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 1a9f228..be9f8a6 100644 +--- a/src/util.c ++++ b/src/util.c +@@ -218,15 +218,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 + diff --git a/SOURCES/dnsmasq-2.76-CVE-2017-14492.patch b/SOURCES/dnsmasq-2.76-CVE-2017-14492.patch new file mode 100644 index 0000000..b381148 --- /dev/null +++ b/SOURCES/dnsmasq-2.76-CVE-2017-14492.patch @@ -0,0 +1,31 @@ +From c14b8b511ac55f6933aebefbd6cc27c1ec74ad58 Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Mon, 25 Sep 2017 18:47:15 +0100 +Subject: [PATCH 2/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 749b666..d09fe0e 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 + diff --git a/SOURCES/dnsmasq-2.76-CVE-2017-14493.patch b/SOURCES/dnsmasq-2.76-CVE-2017-14493.patch new file mode 100644 index 0000000..5634803 --- /dev/null +++ b/SOURCES/dnsmasq-2.76-CVE-2017-14493.patch @@ -0,0 +1,30 @@ +From 5086b12a4b1269d1576b5bab01f72c6fa19c55bc Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Mon, 25 Sep 2017 18:52:50 +0100 +Subject: [PATCH 3/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 73bdee4..8d18a28 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 + diff --git a/SOURCES/dnsmasq-2.76-CVE-2017-14494.patch b/SOURCES/dnsmasq-2.76-CVE-2017-14494.patch new file mode 100644 index 0000000..3743a32 --- /dev/null +++ b/SOURCES/dnsmasq-2.76-CVE-2017-14494.patch @@ -0,0 +1,30 @@ +From 8c8fe650dc17aad0fbafc920fde719218dc4568d Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Mon, 25 Sep 2017 20:05:11 +0100 +Subject: [PATCH 4/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 8d18a28..03b3f84 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 + diff --git a/SOURCES/dnsmasq-2.76-CVE-2017-14495.patch b/SOURCES/dnsmasq-2.76-CVE-2017-14495.patch new file mode 100644 index 0000000..8ca5d0f --- /dev/null +++ b/SOURCES/dnsmasq-2.76-CVE-2017-14495.patch @@ -0,0 +1,41 @@ +From f2ad2cecb55825f7e4409222de1688b9ceebceda Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Mon, 25 Sep 2017 20:16:50 +0100 +Subject: [PATCH 6/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 eed135e..5bdc133 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 + diff --git a/SOURCES/dnsmasq-2.76-CVE-2017-14496.patch b/SOURCES/dnsmasq-2.76-CVE-2017-14496.patch new file mode 100644 index 0000000..f32b919 --- /dev/null +++ b/SOURCES/dnsmasq-2.76-CVE-2017-14496.patch @@ -0,0 +1,66 @@ +From 5ab67e936085a9e584c9b3e43f442ef5bee7f40e Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Mon, 25 Sep 2017 20:11:58 +0100 +Subject: [PATCH 5/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 d2b514b..eed135e 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; +@@ -217,8 +224,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 + diff --git a/SOURCES/dnsmasq-2.76-gita3303e196.patch b/SOURCES/dnsmasq-2.76-gita3303e196.patch new file mode 100644 index 0000000..a437848 --- /dev/null +++ b/SOURCES/dnsmasq-2.76-gita3303e196.patch @@ -0,0 +1,45 @@ +From 2c1aec1e979a209eb2f2b035314a8c973b4ac269 Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Thu, 7 Sep 2017 20:45:00 +0100 +Subject: [PATCH 7/9] 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 5bdc133..a8d0167 100644 +--- a/src/edns0.c ++++ b/src/edns0.c +@@ -221,7 +221,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 9b464d3..0f8f462 100644 +--- a/src/forward.c ++++ b/src/forward.c +@@ -1408,6 +1408,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 + diff --git a/SOURCES/dnsmasq-2.76-misc-cleanups.patch b/SOURCES/dnsmasq-2.76-misc-cleanups.patch new file mode 100644 index 0000000..e8a2132 --- /dev/null +++ b/SOURCES/dnsmasq-2.76-misc-cleanups.patch @@ -0,0 +1,63 @@ +From 3947ab0069e443e72debe26379b8517fac8f6e41 Mon Sep 17 00:00:00 2001 +From: Simon Kelley +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 a8d0167..0552d38 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 78410d6..917bac2 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) +@@ -485,6 +485,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 75893a6..71d5846 100644 +--- a/src/rfc2131.c ++++ b/src/rfc2131.c +@@ -155,7 +155,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 + diff --git a/SOURCES/dnsmasq-2.76-underflow.patch b/SOURCES/dnsmasq-2.76-underflow.patch new file mode 100644 index 0000000..ac8188e --- /dev/null +++ b/SOURCES/dnsmasq-2.76-underflow.patch @@ -0,0 +1,74 @@ +From d4f2e0b8d8f0b5daa0d468f62a0d5f1df58ac325 Mon Sep 17 00:00:00 2001 +From: Doran Moppert +Date: Tue, 26 Sep 2017 14:48:20 +0930 +Subject: [PATCH 9/9] google patch hand-applied + +--- + src/edns0.c | 10 +++++----- + src/forward.c | 4 ++++ + src/rfc1035.c | 6 ++++-- + 3 files changed, 13 insertions(+), 7 deletions(-) + +diff --git a/src/edns0.c b/src/edns0.c +index 0552d38..bec4a36 100644 +--- a/src/edns0.c ++++ b/src/edns0.c +@@ -212,11 +212,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 */ +- } ++ if (p + rdlen > limit) ++ { ++ free(buff); ++ return plen; /* Too big */ ++ } + memcpy(p, buff, rdlen); + free(buff); + p += rdlen; +diff --git a/src/forward.c b/src/forward.c +index 0f8f462..a729c06 100644 +--- a/src/forward.c ++++ b/src/forward.c +@@ -1412,6 +1412,10 @@ void receive_query(struct listener *listen, time_t now) + udp_size = PACKETSZ; /* Sanity check - can't reduce below default. RFC 6891 6.2.3 */ + } + ++ // Make sure the udp size is not smaller than the incoming message so that we ++ // do not underflow ++ if (udp_size < n) udp_size = n; ++ + #ifdef HAVE_AUTH + if (auth_dns) + { +diff --git a/src/rfc1035.c b/src/rfc1035.c +index 917bac2..ae65702 100644 +--- a/src/rfc1035.c ++++ b/src/rfc1035.c +@@ -1182,8 +1182,8 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int + va_end(ap); /* clean up variable argument pointer */ + + j = p - sav - 2; +- /* this has already been checked against limit before */ +- 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) +@@ -1243,6 +1243,8 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen, + int nxdomain = 0, auth = 1, trunc = 0, sec_data = 1; + struct mx_srv_record *rec; + size_t len; ++ // Make sure we do not underflow here too. ++ if (qlen > (limit - ((char *)header))) return 0; + + if (ntohs(header->ancount) != 0 || + ntohs(header->nscount) != 0 || +-- +2.9.5 + diff --git a/SPECS/dnsmasq.spec b/SPECS/dnsmasq.spec index 8a6450a..8b2e92b 100644 --- a/SPECS/dnsmasq.spec +++ b/SPECS/dnsmasq.spec @@ -13,7 +13,7 @@ Name: dnsmasq Version: 2.76 -Release: 2%{?extraversion}%{?dist} +Release: 2%{?extraversion}%{?dist}.2 Summary: A lightweight DHCP/caching DNS server Group: System Environment/Daemons @@ -38,6 +38,17 @@ Patch5: dnsmasq-2.76-warning-fixes.patch Patch6: dnsmasq-2.76-label-warning.patch Patch7: dnsmasq-2.76-label-man.patch Patch8: dnsmasq-2.76-coverity.patch +Patch9: dnsmasq-2.76-CVE-2017-14491.patch +Patch10: dnsmasq-2.76-CVE-2017-14492.patch +Patch11: dnsmasq-2.76-CVE-2017-14493.patch +Patch12: dnsmasq-2.76-CVE-2017-14494.patch +Patch13: dnsmasq-2.76-CVE-2017-14496.patch +Patch14: dnsmasq-2.76-CVE-2017-14495.patch +# commit a3303e196e5d304ec955c4d63afb923ade66c6e8 +Patch15: dnsmasq-2.76-gita3303e196.patch +Patch16: dnsmasq-2.76-underflow.patch +Patch17: dnsmasq-2.76-misc-cleanups.patch +Patch18: dnsmasq-2.76-CVE-2017-14491-2.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -81,6 +92,16 @@ query/remove a DHCP server's leases. %patch6 -p1 %patch7 -p1 %patch8 -p1 -b .coverity +%patch9 -p1 -b .CVE-2017-14491 +%patch10 -p1 -b .CVE-2017-14492 +%patch11 -p1 -b .CVE-2017-14493 +%patch12 -p1 -b .CVE-2017-14494 +%patch13 -p1 -b .CVE-2017-14496 +%patch14 -p1 -b .CVE-2017-14495 +%patch15 -p1 -b .gita3303e196 +%patch16 -p1 -b .underflow +%patch17 -p1 -b .misc +%patch18 -p1 -b .CVE-2017-14491-2 # 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 @@ -167,6 +188,18 @@ rm -rf $RPM_BUILD_ROOT %{_mandir}/man1/dhcp_* %changelog +* Wed Sep 27 2017 Petr Menšík - 2.76-2.2 +- Small correction of CVE-2017-14491 + +* Tue Sep 26 2017 Petr Menšík - 2.76-2.1 +- Fix CVE-2017-14491 +- Fix CVE-2017-14492 +- Fix CVE-2017-14493 +- Fix CVE-2017-14494 +- Fix CVE-2017-14496 +- Fix CVE-2017-14495 +- extra fixes + * Wed Mar 15 2017 Petr Menšík - 2.76-2 - Fix a few coverity warnings - package is dual-licensed GPL v2 or v3