dnsmasq: backport official fix for CVE-2017-13704

Remove LEDE partial fix for CVE-2017-13704.

Backport official fix from upstream.

Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
Signed-off-by: Hans Dedecker <dedeckeh@gmail.com> (PKG_RELEASE increase)
This commit is contained in:
Kevin Darbyshire-Bryant 2017-09-07 03:58:23 +01:00 committed by Hans Dedecker
parent f12a5b8f6d
commit 9a753c49ea
3 changed files with 95 additions and 38 deletions

View file

@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=dnsmasq
PKG_VERSION:=2.77
PKG_RELEASE:=10
PKG_RELEASE:=11
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq/

View file

@ -0,0 +1,94 @@
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.
---
CHANGELOG | 7 +++++++
src/auth.c | 5 -----
src/forward.c | 8 ++++++++
src/rfc1035.c | 5 -----
4 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 3a640f3..7e65912 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -17,6 +17,13 @@ version 2.78
--strict-order active. Thanks to Hans Dedecker
for the patch
+ Fix regression in 2.77, ironically added as a security
+ improvement, which resulted in a crash when a DNS
+ query exceeded 512 bytes (or the EDNS0 packet size,
+ if different.) Thanks to Christian Kujau, Arne Woerner
+ Juan Manuel Fernandez and Kevin Darbyshire-Bryant for
+ chasing this one down. CVE-2017-13704 applies.
+
version 2.77
Generate an error when configured with a CNAME loop,
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 ||
--
1.7.10.4

View file

@ -1,37 +0,0 @@
From 38af9b1ac3242a4128e88069c495024caa565f0e Mon Sep 17 00:00:00 2001
From: Kevin Darbyshire-Bryant <kevin@darbyshire-bryant.me.uk>
Date: Tue, 29 Aug 2017 12:35:40 +0100
Subject: [PATCH] forward.c: fix CVE-2017-13704
Fix SIGSEGV in rfc1035.c answer_request() line 1228 where memset()
is called with header & limit pointing at the same address and thus
tries to clear memory from before the buffer begins.
answer_request() is called with an invalid edns packet size provided by
the client. Ensure the udp_size provided by the client is bounded by
512 and configured maximum as per RFC 6891 6.2.3 "Values lower than 512
MUST be treated as equal to 512"
The client that exposed the problem provided a payload udp size of 0.
Signed-off-by: Kevin Darbyshire-Bryant <kevin@darbyshire-bryant.me.uk>
---
src/forward.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/forward.c b/src/forward.c
index f22556a..62c5a5a 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;
+ if (udp_size < 512)
+ udp_size = 512; /* RFC 6891 6.2.3 */
}
#ifdef HAVE_AUTH
--
2.7.4