From 1f9c5b6ea60a33d2d5bd6a4262d9f272381346d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= Date: Thu, 15 Mar 2018 18:31:18 +0100 Subject: [PATCH] - Rebase to 2.79 - Stop using nettle_hashes directly, use access function (#1548060) - Do not break on cname with spaces (#1498667) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Petr Menšík --- .gitignore | 1 + dnsmasq-2.77-underflow.patch | 29 ++-- dnsmasq-2.78-CVE-2017-15107.patch | 212 ------------------------------ dnsmasq.spec | 11 +- sources | 2 +- 5 files changed, 18 insertions(+), 237 deletions(-) delete mode 100644 dnsmasq-2.78-CVE-2017-15107.patch diff --git a/.gitignore b/.gitignore index 7899088..1e0c820 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ dnsmasq-2.52.tar.lzma /dnsmasq-2.77rc2.tar.xz /dnsmasq-2.77.tar.xz /dnsmasq-2.78.tar.xz +/dnsmasq-2.79.tar.xz diff --git a/dnsmasq-2.77-underflow.patch b/dnsmasq-2.77-underflow.patch index 918c296..2e900bf 100644 --- a/dnsmasq-2.77-underflow.patch +++ b/dnsmasq-2.77-underflow.patch @@ -1,4 +1,4 @@ -From 9d2757b9714523b53ed487b57e740f1b5beb4e0b Mon Sep 17 00:00:00 2001 +From c82a594d95431e8615126621397ea595eb037a6b Mon Sep 17 00:00:00 2001 From: Doran Moppert Date: Tue, 26 Sep 2017 14:48:20 +0930 Subject: [PATCH] google patch hand-applied @@ -6,11 +6,11 @@ Subject: [PATCH] google patch hand-applied --- src/edns0.c | 10 +++++----- src/forward.c | 4 ++++ - src/rfc1035.c | 6 ++++-- - 3 files changed, 13 insertions(+), 7 deletions(-) + src/rfc1035.c | 2 ++ + 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/edns0.c b/src/edns0.c -index 9c6dbcb..268fbe7 100644 +index af33877..ba6ff0c 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 @@ -31,10 +31,10 @@ index 9c6dbcb..268fbe7 100644 free(buff); p += rdlen; diff --git a/src/forward.c b/src/forward.c -index d1962be..6b9c16e 100644 +index cdd11d3..3078f64 100644 --- a/src/forward.c +++ b/src/forward.c -@@ -1417,6 +1417,10 @@ void receive_query(struct listener *listen, time_t now) +@@ -1438,6 +1438,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 */ } @@ -46,21 +46,10 @@ index d1962be..6b9c16e 100644 if (auth_dns) { diff --git a/src/rfc1035.c b/src/rfc1035.c -index 0bf3bcc..3513455 100644 +index b078b59..777911b 100644 --- a/src/rfc1035.c +++ b/src/rfc1035.c -@@ -1198,8 +1198,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) -@@ -1259,6 +1259,8 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen, +@@ -1281,6 +1281,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; @@ -70,5 +59,5 @@ index 0bf3bcc..3513455 100644 if (ntohs(header->ancount) != 0 || ntohs(header->nscount) != 0 || -- -2.9.5 +2.14.3 diff --git a/dnsmasq-2.78-CVE-2017-15107.patch b/dnsmasq-2.78-CVE-2017-15107.patch deleted file mode 100644 index d8f0a31..0000000 --- a/dnsmasq-2.78-CVE-2017-15107.patch +++ /dev/null @@ -1,212 +0,0 @@ -From 7dcf32a822eeaf134526660f8c2826e18f0a8c83 Mon Sep 17 00:00:00 2001 -From: Simon Kelley -Date: Fri, 19 Jan 2018 12:26:08 +0000 -Subject: [PATCH] DNSSEC fix for wildcard NSEC records. CVE-2017-15107 applies. - -It's OK for NSEC records to be expanded from wildcards, -but in that case, the proof of non-existence is only valid -starting at the wildcard name, *. NOT the name expanded -from the wildcard. Without this check it's possible for an -attacker to craft an NSEC which wrongly proves non-existence -in a domain which includes a wildcard for NSEC. - -(cherry picked from commit 4fe6744a220eddd3f1749b40cac3dfc510787de6) - -Fix DNSSEC validation errors introduced in 4fe6744a220eddd3f1749b40cac3dfc510787de6 - -(cherry picked from commit cd7df612b14ec1bf831a966ccaf076be0dae7404) ---- - src/dnssec.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++------- - 1 file changed, 103 insertions(+), 14 deletions(-) - -diff --git a/src/dnssec.c b/src/dnssec.c -index a74d01a..704f03f 100644 ---- a/src/dnssec.c -+++ b/src/dnssec.c -@@ -424,15 +424,17 @@ static void from_wire(char *name) - static int count_labels(char *name) - { - int i; -- -+ char *p; -+ - if (*name == 0) - return 0; - -- for (i = 0; *name; name++) -- if (*name == '.') -+ for (p = name, i = 0; *p; p++) -+ if (*p == '.') - i++; - -- return i+1; -+ /* Don't count empty first label. */ -+ return *name == '.' ? i : i+1; - } - - /* Implement RFC1982 wrapped compare for 32-bit numbers */ -@@ -1405,8 +1407,8 @@ static int hostname_cmp(const char *a, const char *b) - } - } - --static int prove_non_existence_nsec(struct dns_header *header, size_t plen, unsigned char **nsecs, int nsec_count, -- char *workspace1, char *workspace2, char *name, int type, int *nons) -+static int prove_non_existence_nsec(struct dns_header *header, size_t plen, unsigned char **nsecs, unsigned char **labels, int nsec_count, -+ char *workspace1_in, char *workspace2, char *name, int type, int *nons) - { - int i, rc, rdlen; - unsigned char *p, *psave; -@@ -1419,6 +1421,9 @@ static int prove_non_existence_nsec(struct dns_header *header, size_t plen, unsi - /* Find NSEC record that proves name doesn't exist */ - for (i = 0; i < nsec_count; i++) - { -+ char *workspace1 = workspace1_in; -+ int sig_labels, name_labels; -+ - p = nsecs[i]; - if (!extract_name(header, plen, &p, workspace1, 1, 10)) - return 0; -@@ -1427,7 +1432,27 @@ static int prove_non_existence_nsec(struct dns_header *header, size_t plen, unsi - psave = p; - if (!extract_name(header, plen, &p, workspace2, 1, 10)) - return 0; -- -+ -+ /* If NSEC comes from wildcard expansion, use original wildcard -+ as name for computation. */ -+ sig_labels = *labels[i]; -+ name_labels = count_labels(workspace1); -+ -+ if (sig_labels < name_labels) -+ { -+ int k; -+ for (k = name_labels - sig_labels; k != 0; k--) -+ { -+ while (*workspace1 != '.' && *workspace1 != 0) -+ workspace1++; -+ if (k != 1 && *workspace1 == '.') -+ workspace1++; -+ } -+ -+ workspace1--; -+ *workspace1 = '*'; -+ } -+ - rc = hostname_cmp(workspace1, name); - - if (rc == 0) -@@ -1825,24 +1850,26 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns - - static int prove_non_existence(struct dns_header *header, size_t plen, char *keyname, char *name, int qtype, int qclass, char *wildname, int *nons) - { -- static unsigned char **nsecset = NULL; -- static int nsecset_sz = 0; -+ static unsigned char **nsecset = NULL, **rrsig_labels = NULL; -+ static int nsecset_sz = 0, rrsig_labels_sz = 0; - - int type_found = 0; -- unsigned char *p = skip_questions(header, plen); -+ unsigned char *auth_start, *p = skip_questions(header, plen); - int type, class, rdlen, i, nsecs_found; - - /* Move to NS section */ - if (!p || !(p = skip_section(p, ntohs(header->ancount), header, plen))) - return 0; -+ -+ auth_start = p; - - for (nsecs_found = 0, i = ntohs(header->nscount); i != 0; i--) - { - unsigned char *pstart = p; - -- if (!(p = skip_name(p, header, plen, 10))) -+ if (!extract_name(header, plen, &p, daemon->workspacename, 1, 10)) - return 0; -- -+ - GETSHORT(type, p); - GETSHORT(class, p); - p += 4; /* TTL */ -@@ -1859,7 +1886,69 @@ static int prove_non_existence(struct dns_header *header, size_t plen, char *key - if (!expand_workspace(&nsecset, &nsecset_sz, nsecs_found)) - return 0; - -- nsecset[nsecs_found++] = pstart; -+ if (type == T_NSEC) -+ { -+ /* If we're looking for NSECs, find the corresponding SIGs, to -+ extract the labels value, which we need in case the NSECs -+ are the result of wildcard expansion. -+ Note that the NSEC may not have been validated yet -+ so if there are multiple SIGs, make sure the label value -+ is the same in all, to avoid be duped by a rogue one. -+ If there are no SIGs, that's an error */ -+ unsigned char *p1 = auth_start; -+ int res, j, rdlen1, type1, class1; -+ -+ if (!expand_workspace(&rrsig_labels, &rrsig_labels_sz, nsecs_found)) -+ return 0; -+ -+ rrsig_labels[nsecs_found] = NULL; -+ -+ for (j = ntohs(header->nscount); j != 0; j--) -+ { -+ if (!(res = extract_name(header, plen, &p1, daemon->workspacename, 0, 10))) -+ return 0; -+ -+ GETSHORT(type1, p1); -+ GETSHORT(class1, p1); -+ p1 += 4; /* TTL */ -+ GETSHORT(rdlen1, p1); -+ -+ if (!CHECK_LEN(header, p1, plen, rdlen1)) -+ return 0; -+ -+ if (res == 1 && class1 == qclass && type1 == T_RRSIG) -+ { -+ int type_covered; -+ unsigned char *psav = p1; -+ -+ if (rdlen1 < 18) -+ return 0; /* bad packet */ -+ -+ GETSHORT(type_covered, p1); -+ -+ if (type_covered == T_NSEC) -+ { -+ p1++; /* algo */ -+ -+ /* labels field must be the same in every SIG we find. */ -+ if (!rrsig_labels[nsecs_found]) -+ rrsig_labels[nsecs_found] = p1; -+ else if (*rrsig_labels[nsecs_found] != *p1) /* algo */ -+ return 0; -+ } -+ p1 = psav; -+ } -+ -+ if (!ADD_RDLEN(header, p1, plen, rdlen1)) -+ return 0; -+ } -+ -+ /* Must have found at least one sig. */ -+ if (!rrsig_labels[nsecs_found]) -+ return 0; -+ } -+ -+ nsecset[nsecs_found++] = pstart; - } - - if (!ADD_RDLEN(header, p, plen, rdlen)) -@@ -1867,7 +1956,7 @@ static int prove_non_existence(struct dns_header *header, size_t plen, char *key - } - - if (type_found == T_NSEC) -- return prove_non_existence_nsec(header, plen, nsecset, nsecs_found, daemon->workspacename, keyname, name, qtype, nons); -+ return prove_non_existence_nsec(header, plen, nsecset, rrsig_labels, nsecs_found, daemon->workspacename, keyname, name, qtype, nons); - else if (type_found == T_NSEC3) - return prove_non_existence_nsec3(header, plen, nsecset, nsecs_found, daemon->workspacename, keyname, name, qtype, wildname, nons); - else --- -2.14.3 - diff --git a/dnsmasq.spec b/dnsmasq.spec index b135676..f52313d 100644 --- a/dnsmasq.spec +++ b/dnsmasq.spec @@ -12,8 +12,8 @@ %define _hardened_build 1 Name: dnsmasq -Version: 2.78 -Release: 7%{?extraversion:.%{extraversion}}%{?dist} +Version: 2.79 +Release: 1%{?extraversion:.%{extraversion}}%{?dist} Summary: A lightweight DHCP/caching DNS server License: GPLv2 or GPLv3 @@ -24,7 +24,6 @@ Source2: dnsmasq-systemd-sysusers.conf # https://bugzilla.redhat.com/show_bug.cgi?id=1495409 Patch1: dnsmasq-2.77-underflow.patch -Patch2: dnsmasq-2.78-CVE-2017-15107.patch Patch3: dnsmasq-2.78-fips.patch @@ -58,7 +57,6 @@ server's leases. %prep %setup -q -n %{name}-%{version}%{?extraversion} %patch1 -p1 -b .underflow -%patch2 -p1 -b .CVE-2017-15107 %patch3 -p1 -b .fips # use /var/lib/dnsmasq instead of /var/lib/misc @@ -159,6 +157,11 @@ install -Dpm 644 %{SOURCE2} %{buildroot}%{_sysusersdir}/dnsmasq.conf %{_mandir}/man1/dhcp_* %changelog +* Thu Mar 15 2018 Petr Menšík - 2.79-1 +- Rebase to 2.79 +- Stop using nettle_hashes directly, use access function (#1548060) +- Do not break on cname with spaces (#1498667) + * Fri Mar 02 2018 Petr Menšík - 2.78-7 - Emit warning with dnssec enabled on FIPS system (#1549507) diff --git a/sources b/sources index ed48c35..c0990c5 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (dnsmasq-2.78.tar.xz) = 9b79b84e5a768d52f90f6335ccef2c404ecd7a13e78e49f4cd0755fffc6cf34d0dc96ad4c72cad1dab3c5743a8d0d789b3e9b6e625b03c5675bb898ca61a698b +SHA512 (dnsmasq-2.79.tar.xz) = 2c06212696ab55e1584f6133872f5b196013509e4b1822d0457787b456e14341afdde887749e370a2e512124cb4138f012f4601b08690707be4acc7cf2f2876f