diff options
-rw-r--r-- | main/dnsmasq/APKBUILD | 33 | ||||
-rw-r--r-- | main/dnsmasq/CVE-2017-14491-2.patch | 68 | ||||
-rw-r--r-- | main/dnsmasq/CVE-2017-14491.patch | 263 | ||||
-rw-r--r-- | main/dnsmasq/CVE-2017-14492.patch | 30 | ||||
-rw-r--r-- | main/dnsmasq/CVE-2017-14493.patch | 30 | ||||
-rw-r--r-- | main/dnsmasq/CVE-2017-14494.patch | 30 | ||||
-rw-r--r-- | main/dnsmasq/CVE-2017-14495.patch | 41 | ||||
-rw-r--r-- | main/dnsmasq/CVE-2017-14496.patch | 66 |
8 files changed, 554 insertions, 7 deletions
diff --git a/main/dnsmasq/APKBUILD b/main/dnsmasq/APKBUILD index ee9c814bbf4..d75208d0f53 100644 --- a/main/dnsmasq/APKBUILD +++ b/main/dnsmasq/APKBUILD @@ -1,7 +1,18 @@ # Maintainer: Natanael Copa <ncopa@alpinelinux.org> +# Contributor: Jakub Jirutka <jakub@jirutka.cz> +# +# secfixes: +# 2.76-r1: +# - CVE-2017-14491 +# - CVE-2017-14492 +# - CVE-2017-14493 +# - CVE-2017-14494 +# - CVE-2017-14495 +# - CVE-2017-14496 +# pkgname=dnsmasq pkgver=2.76 -pkgrel=0 +pkgrel=1 pkgdesc="Small forwarding DNS server" url="http://www.thekelleys.org.uk/dnsmasq/" arch="all" @@ -11,6 +22,13 @@ makedepends="linux-headers" install="$pkgname.pre-install $pkgname.pre-upgrade" subpackages="$pkgname-doc" source="http://www.thekelleys.org.uk/dnsmasq/$pkgname-$pkgver.tar.gz + CVE-2017-14491.patch + CVE-2017-14492.patch + CVE-2017-14493.patch + CVE-2017-14494.patch + CVE-2017-14496.patch + CVE-2017-14495.patch + CVE-2017-14491-2.patch $pkgname.initd $pkgname.confd " @@ -39,12 +57,13 @@ package() { install dnsmasq.conf.example "$pkgdir"/etc/dnsmasq.conf } -md5sums="6610f8233ca89b15a1bb47c788ffb84f dnsmasq-2.76.tar.gz -bfc91bcb341fd6d0f50eaeca1bb31cb0 dnsmasq.initd -16985abb08c8e11f85e38b37ea3863a4 dnsmasq.confd" -sha256sums="777c4762d2fee3738a0380401f2d087b47faa41db2317c60660d69ad10a76c32 dnsmasq-2.76.tar.gz -9105043609236d774c1f502c309b56cbc669ce0b5e39b424789bbf55f0842037 dnsmasq.initd -51c0672a70d5d6793d295d82db666d372fb081e8627318f67c88e48d08d254b5 dnsmasq.confd" sha512sums="c22627a8d864671096d3b3428ec4f879b513e1f1e7f79be3ab89444c56234e748fbfa6b6b4f9e521984fea95d363f4aa2ca6243f0dfc12ffb74bed0648ae21c5 dnsmasq-2.76.tar.gz +aa82a4d07f22dfc4913aaefb678890b0523f89f5283b1bab97c9e8540aafaa3be436a205f4e442c51336209e81e6236325ede5f1d5ba0de671bb1cbcd8979a14 CVE-2017-14491.patch +a3fbde8c902ccab61b279f6977dddc46c7e2ae9c5cd2c9e0b297bbbe2965cd9a5d254bc4a0fcabc53db0dc3e945f77f85ffd798c2d181c8c0ad48391754f3781 CVE-2017-14492.patch +083ce54a4e1a41f60302cdd3f353f1ba9ea84a3f474d1ce0b9f2d88c14c36bb83a314775260b83788f89866575199391d2f40b773224798bdd4ad09f847e20b1 CVE-2017-14493.patch +3aed0e80eb1d0bcc1639e83668ac49fced2681d907ab70a00ded50fb987cc2ade6f264016877666075b8a9efc542df57badbe4e1aa89d60b792a13c00029041a CVE-2017-14494.patch +d63f2ed7b34796ff42891813084c56df1ce7e7da1ea2485a029b8c7b5dfda2110fdf8c217564a77571562a9b4778e777f9dec6de8c1e9ffb52f6e85fb6cc566c CVE-2017-14496.patch +d3ffcd4451a52930a9499047559853f7a3b653a26254d3abeb972dd9ed663c406db3cc415cf5b3d5eeb44e37ff21573eaa6bc92415e8e97d13ff9890c4a0683f CVE-2017-14495.patch +ae665e0545038f1660eb8b67db71b403a3bdcc1b6915438f6e0eaec5c0d7c43dc49b72bb68c2204882d3c2fd280313ee2035a699ff2308d23e8ade65ef87a323 CVE-2017-14491-2.patch a7c44bd4c7d04d881e561288ee4979378ee0cd72a812a5dc33a040aea40374a2cbcafb1b3b2a6fa07291ee0831b7d421f7a8749289213fe1fb3205163980bfa5 dnsmasq.initd 9a401bfc408bf1638645c61b8ca734bea0a09ef79fb36648ec7ef21666257234254bbe6c73c82cc23aa1779ddcdda0e6baa2c041866f16dfb9c4e0ba9133eab8 dnsmasq.confd" diff --git a/main/dnsmasq/CVE-2017-14491-2.patch b/main/dnsmasq/CVE-2017-14491-2.patch new file mode 100644 index 00000000000..d72b07759db --- /dev/null +++ b/main/dnsmasq/CVE-2017-14491-2.patch @@ -0,0 +1,68 @@ +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] 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 + diff --git a/main/dnsmasq/CVE-2017-14491.patch b/main/dnsmasq/CVE-2017-14491.patch new file mode 100644 index 00000000000..9b62e903e0b --- /dev/null +++ b/main/dnsmasq/CVE-2017-14491.patch @@ -0,0 +1,263 @@ +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 + diff --git a/main/dnsmasq/CVE-2017-14492.patch b/main/dnsmasq/CVE-2017-14492.patch new file mode 100644 index 00000000000..152c677aa50 --- /dev/null +++ b/main/dnsmasq/CVE-2017-14492.patch @@ -0,0 +1,30 @@ +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] 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 + diff --git a/main/dnsmasq/CVE-2017-14493.patch b/main/dnsmasq/CVE-2017-14493.patch new file mode 100644 index 00000000000..20b178245c5 --- /dev/null +++ b/main/dnsmasq/CVE-2017-14493.patch @@ -0,0 +1,30 @@ +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] 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 + diff --git a/main/dnsmasq/CVE-2017-14494.patch b/main/dnsmasq/CVE-2017-14494.patch new file mode 100644 index 00000000000..eeba01b8bd2 --- /dev/null +++ b/main/dnsmasq/CVE-2017-14494.patch @@ -0,0 +1,30 @@ +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] 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 + diff --git a/main/dnsmasq/CVE-2017-14495.patch b/main/dnsmasq/CVE-2017-14495.patch new file mode 100644 index 00000000000..7aad2b3de8a --- /dev/null +++ b/main/dnsmasq/CVE-2017-14495.patch @@ -0,0 +1,41 @@ +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] 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 + diff --git a/main/dnsmasq/CVE-2017-14496.patch b/main/dnsmasq/CVE-2017-14496.patch new file mode 100644 index 00000000000..85ac34202bc --- /dev/null +++ b/main/dnsmasq/CVE-2017-14496.patch @@ -0,0 +1,66 @@ +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] 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 + |