aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--main/dnsmasq/APKBUILD33
-rw-r--r--main/dnsmasq/CVE-2017-14491-2.patch68
-rw-r--r--main/dnsmasq/CVE-2017-14491.patch263
-rw-r--r--main/dnsmasq/CVE-2017-14492.patch30
-rw-r--r--main/dnsmasq/CVE-2017-14493.patch30
-rw-r--r--main/dnsmasq/CVE-2017-14494.patch30
-rw-r--r--main/dnsmasq/CVE-2017-14495.patch41
-rw-r--r--main/dnsmasq/CVE-2017-14496.patch66
8 files changed, 554 insertions, 7 deletions
diff --git a/main/dnsmasq/APKBUILD b/main/dnsmasq/APKBUILD
index ee9c814bbf..d75208d0f5 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 0000000000..d72b07759d
--- /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 0000000000..9b62e903e0
--- /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 0000000000..152c677aa5
--- /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 0000000000..20b178245c
--- /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 0000000000..eeba01b8bd
--- /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 0000000000..7aad2b3de8
--- /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 0000000000..85ac34202b
--- /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
+