diff --git a/backport-Do-not-try-to-re-read-deleted-files-inside-a-hostsdi.patch b/backport-Do-not-try-to-re-read-deleted-files-inside-a-hostsdi.patch new file mode 100644 index 0000000000000000000000000000000000000000..268b0c720b81f219623f625fdc6fa219431492ec --- /dev/null +++ b/backport-Do-not-try-to-re-read-deleted-files-inside-a-hostsdi.patch @@ -0,0 +1,41 @@ +From 92c32e0bace9ba11bea2cb77912695da3221f656 Mon Sep 17 00:00:00 2001 +From: Dominik Derigs +Date: Thu, 27 Oct 2022 12:36:38 +0100 +Subject: [PATCH] Do not (try to) re-read deleted files inside a --hostsdir. + +Conflict:NA +Reference:https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=id=92c32e0bace9ba11bea2cb77912695da3221f656 + +--- + src/inotify.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/src/inotify.c b/src/inotify.c +index 5776feb..438a622 100644 +--- a/src/inotify.c ++++ b/src/inotify.c +@@ -253,12 +253,18 @@ int inotify_check(time_t now) + strcpy(path, ah->fname); + strcat(path, "/"); + strcat(path, in->name); +- +- my_syslog(LOG_INFO, _("inotify, new or changed file %s"), path); ++ ++ /* Is this is a deletion event? */ ++ if (in->mask & IN_DELETE) ++ my_syslog(LOG_INFO, _("inotify: %s (removed)"), path); ++ else ++ my_syslog(LOG_INFO, _("inotify: %s (new or modified)"), path); + + if (ah->flags & AH_HOSTS) + { +- read_hostsfile(path, ah->index, 0, NULL, 0); ++ /* (Re-)load hostsfile only if this event isn't triggered by deletion */ ++ if (!(in->mask & IN_DELETE)) ++ read_hostsfile(path, ah->index, 0, NULL, 0); + #ifdef HAVE_DHCP + if (daemon->dhcp || daemon->doing_dhcp6) + { +-- +2.27.0 + diff --git a/backport-Fix-GOST-signature-algorithms-for-DNSSEC-validation.patch b/backport-Fix-GOST-signature-algorithms-for-DNSSEC-validation.patch new file mode 100644 index 0000000000000000000000000000000000000000..38bbdb8271c50b7757fa4db437f0b7b974815f29 --- /dev/null +++ b/backport-Fix-GOST-signature-algorithms-for-DNSSEC-validation.patch @@ -0,0 +1,63 @@ +From 1f9215f5f92c5478c8aaba8054d192a5e6280e95 Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Wed, 16 Nov 2022 15:54:43 +0000 +Subject: [PATCH] Fix GOST signature algorithms for DNSSEC validation. + +Use CryptoPro version of the hash function. +Handle the little-endian wire format of key data. +Get the wire order of S and R correct. + +Note that Nettle version 3.6 or later is required for GOST support. +Conflict:NA +Reference:https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=id=1f9215f5f92c5478c8aaba8054d192a5e6280e95 +--- + src/crypto.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +diff --git a/src/crypto.c b/src/crypto.c +index 4009569..9b97aed 100644 +--- a/src/crypto.c ++++ b/src/crypto.c +@@ -309,14 +309,14 @@ static int dnsmasq_gostdsa_verify(struct blockdata *key_data, unsigned int key_l + mpz_init(y); + } + +- mpz_import(x, 32 , 1, 1, 0, 0, p); +- mpz_import(y, 32 , 1, 1, 0, 0, p + 32); ++ mpz_import(x, 32, -1, 1, 0, 0, p); ++ mpz_import(y, 32, -1, 1, 0, 0, p + 32); + + if (!ecc_point_set(gost_key, x, y)) +- return 0; ++ return 0; + +- mpz_import(sig_struct->r, 32, 1, 1, 0, 0, sig); +- mpz_import(sig_struct->s, 32, 1, 1, 0, 0, sig + 32); ++ mpz_import(sig_struct->s, 32, 1, 1, 0, 0, sig); ++ mpz_import(sig_struct->r, 32, 1, 1, 0, 0, sig + 32); + + return nettle_gostdsa_verify(gost_key, digest_len, digest, sig_struct); + } +@@ -425,7 +425,9 @@ char *ds_digest_name(int digest) + { + case 1: return "sha1"; + case 2: return "sha256"; +- case 3: return "gosthash94"; ++#if MIN_VERSION(3, 6) ++ case 3: return "gosthash94cp"; ++#endif + case 4: return "sha384"; + default: return NULL; + } +@@ -444,7 +446,7 @@ char *algo_digest_name(int algo) + case 7: return "sha1"; /* RSASHA1-NSEC3-SHA1 */ + case 8: return "sha256"; /* RSA/SHA-256 */ + case 10: return "sha512"; /* RSA/SHA-512 */ +- case 12: return "gosthash94"; /* ECC-GOST */ ++ case 12: return "gosthash94cp"; /* ECC-GOST */ + case 13: return "sha256"; /* ECDSAP256SHA256 */ + case 14: return "sha384"; /* ECDSAP384SHA384 */ + case 15: return "null_hash"; /* ED25519 */ +-- +2.27.0 + diff --git a/backport-Fix-bug-in-dynamic-host-when-interface-has-16-IPv4-a.patch b/backport-Fix-bug-in-dynamic-host-when-interface-has-16-IPv4-a.patch new file mode 100644 index 0000000000000000000000000000000000000000..e06f8a826d412b5dce22af99086f2944acccd6bf --- /dev/null +++ b/backport-Fix-bug-in-dynamic-host-when-interface-has-16-IPv4-a.patch @@ -0,0 +1,28 @@ +From b87d7aa0411f267a7e0fb1184643a14d4b54a59b Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Thu, 13 Oct 2022 15:02:54 +0100 +Subject: [PATCH] Fix bug in --dynamic-host when interface has /16 IPv4 + address. + +Conflict:NA +Reference:https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=id=b87d7aa0411f267a7e0fb1184643a14d4b54a59b +--- + src/network.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletion(-) + +diff --git a/src/network.c b/src/network.c +index 6166484..b8dcc75 100644 +--- a/src/network.c ++++ b/src/network.c +@@ -360,7 +360,7 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label, + + if (int_name->flags & INP4) + { +- if (netmask.s_addr == 0xffff) ++ if (netmask.s_addr == 0xffffffff) + continue; + + newaddr.s_addr = (addr->in.sin_addr.s_addr & netmask.s_addr) | +-- +2.27.0 + diff --git a/backport-Fix-in-dhcpv4-rapid-commit-code.patch b/backport-Fix-in-dhcpv4-rapid-commit-code.patch new file mode 100644 index 0000000000000000000000000000000000000000..328873df36b7dd68d15eae2c2ae50b5bd48b1795 --- /dev/null +++ b/backport-Fix-in-dhcpv4-rapid-commit-code.patch @@ -0,0 +1,49 @@ +From 1bcad678066745e98ca29dc4883241f4e5e32ac9 Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Thu, 27 Oct 2022 12:04:58 +0100 +Subject: [PATCH] Fix in dhcpv4 rapid-commit code. + +1) Cosmetic: don't log the tags twice. + +2) Functional. If a host has an old lease for a different address, + the rapid-commit will appear to work, but the old lease will + not be removed and the new lease will not be recorded, so + the client and server will have conflicting state, leading to + problems later. +Conflict:NA +Reference:https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=id=1bcad678066745e98ca29dc4883241f4e5e32ac9 +--- + src/rfc2131.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/src/rfc2131.c b/src/rfc2131.c +index 2056cba..17e97b5 100644 +--- a/src/rfc2131.c ++++ b/src/rfc2131.c +@@ -1153,15 +1153,22 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, + tagif_netid = run_tag_if(&context->netid); + } + +- log_tags(tagif_netid, ntohl(mess->xid)); + apply_delay(mess->xid, recvtime, tagif_netid); + + if (option_bool(OPT_RAPID_COMMIT) && option_find(mess, sz, OPTION_RAPID_COMMIT, 0)) + { + rapid_commit = 1; ++ /* If a lease exists for this host and another address, squash it. */ ++ if (lease && lease->addr.s_addr != mess->yiaddr.s_addr) ++ { ++ lease_prune(lease, now); ++ lease = NULL; ++ } + goto rapid_commit; + } + ++ log_tags(tagif_netid, ntohl(mess->xid)); ++ + daemon->metrics[METRIC_DHCPOFFER]++; + log_packet("DHCPOFFER" , &mess->yiaddr, emac, emac_len, iface_name, NULL, NULL, mess->xid); + +-- +2.27.0 + diff --git a/backport-Fix-massive-confusion-on-server-reload.patch b/backport-Fix-massive-confusion-on-server-reload.patch new file mode 100644 index 0000000000000000000000000000000000000000..2b3225d17cf357f5bf7d74acfcf7b9f99ad21c85 --- /dev/null +++ b/backport-Fix-massive-confusion-on-server-reload.patch @@ -0,0 +1,237 @@ +From 553c4c99cca173e9964d0edbd0676ed96c30f62b Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Mon, 3 Jan 2022 23:32:30 +0000 +Subject: [PATCH] Fix massive confusion on server reload. + +The 2.86 upstream server rewrite severely broke re-reading +of server configuration. It would get everyting right the first +time, but on re-reading /etc/resolv.conf or --servers-file +or setting things with DBUS, the results were just wrong. + +This should put things right again. +Conflict:NA +Reference:https://github.com/rhuijben/dnsmasq/commit/553c4c99cca173e9964d0edbd0676ed96c30f62b +--- + src/domain-match.c | 151 +++++++++++++++++++++++++-------------------- + 1 file changed, 85 insertions(+), 66 deletions(-) + +diff --git a/src/domain-match.c b/src/domain-match.c +index 2780cef..bab9876 100644 +--- a/src/domain-match.c ++++ b/src/domain-match.c +@@ -547,22 +547,39 @@ static int order_qsort(const void *a, const void *b) + return rc; + } + ++/* Must be called before add_update_server() to set daemon->servers_tail */ + void mark_servers(int flag) + { +- struct server *serv; ++ struct server *serv, **up; + ++ daemon->servers_tail = NULL; ++ + /* mark everything with argument flag */ + for (serv = daemon->servers; serv; serv = serv->next) +- if (serv->flags & flag) +- serv->flags |= SERV_MARK; +- else +- serv->flags &= ~SERV_MARK; ++ { ++ if (serv->flags & flag) ++ serv->flags |= SERV_MARK; ++ else ++ serv->flags &= ~SERV_MARK; + +- for (serv = daemon->local_domains; serv; serv = serv->next) +- if (serv->flags & flag) +- serv->flags |= SERV_MARK; +- else +- serv->flags &= ~SERV_MARK; ++ daemon->servers_tail = serv; ++ } ++ ++ /* --address etc is different: since they are expected to be ++ 1) numerous and 2) not reloaded often. We just delete ++ and recreate. */ ++ if (flag) ++ for (serv = daemon->local_domains, up = &daemon->local_domains; serv; serv = serv->next) ++ { ++ if (serv->flags & flag) ++ { ++ *up = serv->next; ++ free(serv->domain); ++ free(serv); ++ } ++ else ++ up = &serv->next; ++ } + } + + void cleanup_servers(void) +@@ -570,7 +587,7 @@ void cleanup_servers(void) + struct server *serv, *tmp, **up; + + /* unlink and free anything still marked. */ +- for (serv = daemon->servers, up = &daemon->servers; serv; serv = tmp) ++ for (serv = daemon->servers, up = &daemon->servers, daemon->servers_tail = NULL; serv; serv = tmp) + { + tmp = serv->next; + if (serv->flags & SERV_MARK) +@@ -586,19 +603,6 @@ void cleanup_servers(void) + daemon->servers_tail = serv; + } + } +- +- for (serv = daemon->local_domains, up = &daemon->local_domains; serv; serv = tmp) +- { +- tmp = serv->next; +- if (serv->flags & SERV_MARK) +- { +- *up = serv->next; +- free(serv->domain); +- free(serv); +- } +- else +- up = &serv->next; +- } + + /* If we're delaying things, we don't call check_servers(), but + reload_servers() may have deleted some servers, rendering the server_array +@@ -637,35 +641,16 @@ int add_update_server(int flags, + if (!alloc_domain) + return 0; + +- /* See if there is a suitable candidate, and unmark +- only do this for forwarding servers, not +- address or local, to avoid delays on large numbers. */ + if (flags & SERV_IS_LOCAL) +- for (serv = daemon->servers; serv; serv = serv->next) +- if ((serv->flags & SERV_MARK) && +- hostname_isequal(alloc_domain, serv->domain)) +- break; +- +- if (serv) +- { +- free(alloc_domain); +- alloc_domain = serv->domain; +- } +- else + { + size_t size; + +- if (flags & SERV_IS_LOCAL) +- { +- if (flags & SERV_6ADDR) +- size = sizeof(struct serv_addr6); +- else if (flags & SERV_4ADDR) +- size = sizeof(struct serv_addr4); +- else +- size = sizeof(struct serv_local); +- } ++ if (flags & SERV_6ADDR) ++ size = sizeof(struct serv_addr6); ++ else if (flags & SERV_4ADDR) ++ size = sizeof(struct serv_addr4); + else +- size = sizeof(struct server); ++ size = sizeof(struct serv_local); + + if (!(serv = whine_malloc(size))) + { +@@ -673,19 +658,53 @@ int add_update_server(int flags, + return 0; + } + +- if (flags & SERV_IS_LOCAL) ++ serv->next = daemon->local_domains; ++ daemon->local_domains = serv; ++ ++ if (flags & SERV_4ADDR) ++ ((struct serv_addr4*)serv)->addr = local_addr->addr4; ++ ++ if (flags & SERV_6ADDR) ++ ((struct serv_addr6*)serv)->addr = local_addr->addr6; ++ } ++ else ++ { ++ /* Upstream servers. See if there is a suitable candidate, if so unmark ++ and move to the end of the list, for order. The entry found may already ++ be at the end. */ ++ struct server **up, *tmp; ++ ++ for (serv = daemon->servers, up = &daemon->servers; serv; serv = tmp) + { +- serv->next = daemon->local_domains; +- daemon->local_domains = serv; ++ tmp = serv->next; ++ if ((serv->flags & SERV_MARK) && ++ hostname_isequal(alloc_domain, serv->domain)) ++ { ++ /* Need to move down? */ ++ if (serv->next) ++ { ++ *up = serv->next; ++ daemon->servers_tail->next = serv; ++ daemon->servers_tail = serv; ++ serv->next = NULL; ++ } ++ break; ++ } ++ } + +- if (flags & SERV_4ADDR) +- ((struct serv_addr4*)serv)->addr = local_addr->addr4; +- +- if (flags & SERV_6ADDR) +- ((struct serv_addr6*)serv)->addr = local_addr->addr6; ++ if (serv) ++ { ++ free(alloc_domain); ++ alloc_domain = serv->domain; + } + else + { ++ if (!(serv = whine_malloc(sizeof(struct server)))) ++ { ++ free(alloc_domain); ++ return 0; ++ } ++ + memset(serv, 0, sizeof(struct server)); + + /* Add to the end of the chain, for order */ +@@ -694,20 +713,20 @@ int add_update_server(int flags, + else + daemon->servers = serv; + daemon->servers_tail = serv; +- ++ } ++ + #ifdef HAVE_LOOP +- serv->uid = rand32(); ++ serv->uid = rand32(); + #endif + +- if (interface) +- safe_strncpy(serv->interface, interface, sizeof(serv->interface)); +- if (addr) +- serv->addr = *addr; +- if (source_addr) +- serv->source_addr = *source_addr; +- } ++ if (interface) ++ safe_strncpy(serv->interface, interface, sizeof(serv->interface)); ++ if (addr) ++ serv->addr = *addr; ++ if (source_addr) ++ serv->source_addr = *source_addr; + } +- ++ + serv->flags = flags; + serv->domain = alloc_domain; + serv->domain_len = strlen(alloc_domain); +-- +2.27.0 + diff --git a/backport-Fix-namebuff-overwrite-leading-to-wrong-log-after-so.patch b/backport-Fix-namebuff-overwrite-leading-to-wrong-log-after-so.patch new file mode 100644 index 0000000000000000000000000000000000000000..4aa2248fc1bb43a1c35e0f987499917ecc9aea20 --- /dev/null +++ b/backport-Fix-namebuff-overwrite-leading-to-wrong-log-after-so.patch @@ -0,0 +1,35 @@ +From e518e87533345f53fb59e1b9e99994dd73eb8942 Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Fri, 9 Sep 2022 15:56:54 +0100 +Subject: [PATCH] Fix namebuff overwrite leading to wrong log after socket bind + warning. + +Conflict:NA +Reference:https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=id=e518e87533345f53fb59e1b9e99994dd73eb8942 +--- + src/forward.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/forward.c b/src/forward.c +index aa9ace0..9d1f005 100644 +--- a/src/forward.c ++++ b/src/forward.c +@@ -2439,12 +2439,12 @@ static int random_sock(struct server *s) + return fd; + + if (s->interface[0] == 0) +- (void)prettyprint_addr(&s->source_addr, daemon->namebuff); ++ (void)prettyprint_addr(&s->source_addr, daemon->addrbuff); + else +- strcpy(daemon->namebuff, s->interface); ++ safe_strncpy(daemon->addrbuff, s->interface, ADDRSTRLEN); + + my_syslog(LOG_ERR, _("failed to bind server socket to %s: %s"), +- daemon->namebuff, strerror(errno)); ++ daemon->addrbuff, strerror(errno)); + close(fd); + } + +-- +2.27.0 + diff --git a/backport-Fix-use-after-free-in-mark_servers.patch b/backport-Fix-use-after-free-in-mark_servers.patch new file mode 100644 index 0000000000000000000000000000000000000000..3e19cad3c29920051ab42bd575883a0fd5377fb7 --- /dev/null +++ b/backport-Fix-use-after-free-in-mark_servers.patch @@ -0,0 +1,43 @@ +From 022ad63f0c8cbb17ba37ee4128eae30ebb873ce4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= +Date: Sat, 26 Nov 2022 18:49:21 +0000 +Subject: [PATCH] Fix use-after-free in mark_servers() + +Conflict:NA +Reference:https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=id=022ad63f0c8cbb17ba37ee4128eae30ebb873ce4 +--- + src/domain-match.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/src/domain-match.c b/src/domain-match.c +index bef460a..fe8e25a 100644 +--- a/src/domain-match.c ++++ b/src/domain-match.c +@@ -559,7 +559,7 @@ static int maybe_free_servers = 0; + /* Must be called before add_update_server() to set daemon->servers_tail */ + void mark_servers(int flag) + { +- struct server *serv, **up; ++ struct server *serv, *next, **up; + + daemon->servers_tail = NULL; + +@@ -580,11 +580,13 @@ void mark_servers(int flag) + 1) numerous and 2) not reloaded often. We just delete + and recreate. */ + if (flag) +- for (serv = daemon->local_domains, up = &daemon->local_domains; serv; serv = serv->next) ++ for (serv = daemon->local_domains, up = &daemon->local_domains; serv; serv = next) + { ++ next = serv->next; ++ + if (serv->flags & flag) + { +- *up = serv->next; ++ *up = next; + free(serv->domain); + free(serv); + } +-- +2.27.0 + diff --git a/backport-Handle-DS-records-for-unsupported-crypto-algorithms-.patch b/backport-Handle-DS-records-for-unsupported-crypto-algorithms-.patch new file mode 100644 index 0000000000000000000000000000000000000000..f6c933f257c7316d53d0fc64a26aa4aedb49f45d --- /dev/null +++ b/backport-Handle-DS-records-for-unsupported-crypto-algorithms-.patch @@ -0,0 +1,140 @@ +From 9ed3ee67ecd2a388d319bff116b27bcc62286ccc Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Wed, 16 Nov 2022 16:49:30 +0000 +Subject: [PATCH] Handle DS records for unsupported crypto algorithms + correctly. + +Such a DS, as long as it is validated, should allow answers +in the domain is attests to be returned as unvalidated, and not +as a validation error. +Conflict:NA +Reference:https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=id=9ed3ee67ecd2a388d319bff116b27bcc62286ccc + +--- + src/dnssec.c | 58 ++++++++++++++++++++++++++++++++-------------------- + 1 file changed, 36 insertions(+), 22 deletions(-) + +diff --git a/src/dnssec.c b/src/dnssec.c +index 346ceae..ca402ac 100644 +--- a/src/dnssec.c ++++ b/src/dnssec.c +@@ -979,10 +979,13 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch + } + + /* The DNS packet is expected to contain the answer to a DS query +- Put all DSs in the answer which are valid into the cache. ++ Put all DSs in the answer which are valid and have hash and signature algos ++ we support into the cache. + Also handles replies which prove that there's no DS at this location, + either because the zone is unsigned or this isn't a zone cut. These are + cached too. ++ If none of the DS's are for supported algos, treat the answer as if ++ it's a proof of no DS at this location. RFC4035 para 5.2. + return codes: + STAT_OK At least one valid DS found and in cache. + STAT_BOGUS no DS in reply or not signed, fails validation, bad packet. +@@ -993,8 +996,8 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch + int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class) + { + unsigned char *p = (unsigned char *)(header+1); +- int qtype, qclass, rc, i, neganswer, nons, neg_ttl = 0; +- int aclass, atype, rdlen; ++ int qtype, qclass, rc, i, neganswer, nons, neg_ttl = 0, found_supported = 0; ++ int aclass, atype, rdlen, flags; + unsigned long ttl; + union all_addr a; + +@@ -1065,14 +1068,22 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char + algo = *p++; + digest = *p++; + +- if ((key = blockdata_alloc((char*)p, rdlen - 4))) ++ if (!ds_digest_name(digest) || !ds_digest_name(digest)) ++ { ++ a.log.keytag = keytag; ++ a.log.algo = algo; ++ a.log.digest = digest; ++ log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu (not supported)"); ++ neg_ttl = ttl; ++ } ++ else if ((key = blockdata_alloc((char*)p, rdlen - 4))) + { + a.ds.digest = digest; + a.ds.keydata = key; + a.ds.algo = algo; + a.ds.keytag = keytag; + a.ds.keylen = rdlen - 4; +- ++ + if (!cache_insert(name, &a, class, now, ttl, F_FORWARD | F_DS | F_DNSSECOK)) + { + blockdata_free(key); +@@ -1083,26 +1094,29 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char + a.log.keytag = keytag; + a.log.algo = algo; + a.log.digest = digest; +- if (ds_digest_name(digest) && algo_digest_name(algo)) +- log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu"); +- else +- log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu (not supported)"); ++ log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu"); ++ found_supported = 1; + } + } + + p = psave; + } ++ + if (!ADD_RDLEN(header, p, plen, rdlen)) + return STAT_BOGUS; /* bad packet */ + } + + cache_end_insert(); + ++ /* Fall through if no supported algo DS found. */ ++ if (found_supported) ++ return STAT_OK; + } +- else ++ ++ flags = F_FORWARD | F_DS | F_NEG | F_DNSSECOK; ++ ++ if (neganswer) + { +- int flags = F_FORWARD | F_DS | F_NEG | F_DNSSECOK; +- + if (RCODE(header) == NXDOMAIN) + flags |= F_NXDOMAIN; + +@@ -1110,18 +1124,18 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char + to store presence/absence of NS. */ + if (nons) + flags &= ~F_DNSSECOK; +- +- cache_start_insert(); +- +- /* Use TTL from NSEC for negative cache entries */ +- if (!cache_insert(name, NULL, class, now, neg_ttl, flags)) +- return STAT_BOGUS; +- +- cache_end_insert(); +- +- log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, nons ? "no DS/cut" : "no DS"); + } + ++ cache_start_insert(); ++ ++ /* Use TTL from NSEC for negative cache entries */ ++ if (!cache_insert(name, NULL, class, now, neg_ttl, flags)) ++ return STAT_BOGUS; ++ ++ cache_end_insert(); ++ ++ if (neganswer) ++ log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, nons ? "no DS/cut" : "no DS"); + return STAT_OK; + } + +-- +2.27.0 + diff --git a/backport-Optimize-inserting-records-into-server-list.patch b/backport-Optimize-inserting-records-into-server-list.patch new file mode 100644 index 0000000000000000000000000000000000000000..ce648f0db96a6241a68c9ba7137b82f5c3e76b5a --- /dev/null +++ b/backport-Optimize-inserting-records-into-server-list.patch @@ -0,0 +1,69 @@ +From eb88eed1fc8ed246e9355531c2715fa2f7738afc Mon Sep 17 00:00:00 2001 +From: hev +Date: Sun, 19 Sep 2021 18:56:08 +0800 +Subject: [PATCH] Optimize inserting records into server list. + +Signed-off-by: hev + +Conflict:NA +Reference:https://github.com/rhuijben/dnsmasq/commit/eb88eed1fc8ed246e9355531c2715fa2f7738afc +--- + src/dnsmasq.h | 2 +- + src/domain-match.c | 17 ++++++++--------- + 2 files changed, 9 insertions(+), 10 deletions(-) + +diff --git a/src/dnsmasq.h b/src/dnsmasq.h +index 327ad65..639c568 100644 +--- a/src/dnsmasq.h ++++ b/src/dnsmasq.h +@@ -1105,7 +1105,7 @@ extern struct daemon { + char *lease_change_command; + struct iname *if_names, *if_addrs, *if_except, *dhcp_except, *auth_peers, *tftp_interfaces; + struct bogus_addr *bogus_addr, *ignore_addr; +- struct server *servers, *local_domains, **serverarray, *no_rebind; ++ struct server *servers, *servers_tail, *local_domains, **serverarray, *no_rebind; + int server_has_wildcard; + int serverarraysz, serverarrayhwm; + struct ipsets *ipsets; +diff --git a/src/domain-match.c b/src/domain-match.c +index 8f29621..3f1cc74 100644 +--- a/src/domain-match.c ++++ b/src/domain-match.c +@@ -576,7 +576,10 @@ void cleanup_servers(void) + free(serv); + } + else +- up = &serv->next; ++ { ++ up = &serv->next; ++ daemon->servers_tail = serv; ++ } + } + + for (serv = daemon->local_domains, up = &daemon->local_domains; serv; serv = tmp) +@@ -673,18 +676,14 @@ int add_update_server(int flags, + } + else + { +- struct server *s; +- + memset(serv, 0, sizeof(struct server)); + + /* Add to the end of the chain, for order */ +- if (!daemon->servers) +- daemon->servers = serv; ++ if (daemon->servers_tail) ++ daemon->servers_tail->next = serv; + else +- { +- for (s = daemon->servers; s->next; s = s->next); +- s->next = serv; +- } ++ daemon->servers = serv; ++ daemon->servers_tail = serv; + + #ifdef HAVE_LOOP + serv->uid = rand32(); +-- +2.27.0 + diff --git a/backport-Reconcile-names-and-address-counts-when-reading-host.patch b/backport-Reconcile-names-and-address-counts-when-reading-host.patch new file mode 100644 index 0000000000000000000000000000000000000000..b95120ba44cda152a6ff1e8c248ab11965e42dda --- /dev/null +++ b/backport-Reconcile-names-and-address-counts-when-reading-host.patch @@ -0,0 +1,72 @@ +From d3c21c596ef96027429b11216fcdbf65c9434afa Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Sun, 30 Oct 2022 15:40:20 +0000 +Subject: [PATCH] Reconcile "names" and "address" counts when reading + hostfiles. + +Conflict:NA +Reference:https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=id=d3c21c596ef96027429b11216fcdbf65c9434afa +--- + src/cache.c | 10 +++++----- + src/inotify.c | 2 +- + 2 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/cache.c b/src/cache.c +index f8c4b2c..119cf9f 100644 +--- a/src/cache.c ++++ b/src/cache.c +@@ -189,7 +189,7 @@ static void rehash(int size) + else if (new_size <= hash_size || !(new = whine_malloc(new_size * sizeof(struct crec *)))) + return; + +- for(i = 0; i < new_size; i++) ++ for (i = 0; i < new_size; i++) + new[i] = NULL; + + old = hash_table; +@@ -1169,7 +1169,7 @@ int read_hostsfile(char *filename, unsigned int index, int cache_size, struct cr + { + FILE *f = fopen(filename, "r"); + char *token = daemon->namebuff, *domain_suffix = NULL; +- int addr_count = 0, name_count = cache_size, lineno = 1; ++ int names_done = 0, name_count = cache_size, lineno = 1; + unsigned int flags = 0; + union all_addr addr; + int atnl, addrlen = 0; +@@ -1205,8 +1205,6 @@ int read_hostsfile(char *filename, unsigned int index, int cache_size, struct cr + continue; + } + +- addr_count++; +- + /* rehash every 1000 names. */ + if (rhash && ((name_count - cache_size) > 1000)) + { +@@ -1238,6 +1236,7 @@ int read_hostsfile(char *filename, unsigned int index, int cache_size, struct cr + cache->ttd = daemon->local_ttl; + add_hosts_entry(cache, &addr, addrlen, index, rhash, hashsz); + name_count++; ++ names_done++; + } + if ((cache = whine_malloc(SIZEOF_BARE_CREC + strlen(canon) + 1))) + { +@@ -1246,6 +1245,7 @@ int read_hostsfile(char *filename, unsigned int index, int cache_size, struct cr + cache->ttd = daemon->local_ttl; + add_hosts_entry(cache, &addr, addrlen, index, rhash, hashsz); + name_count++; ++ names_done++; + } + free(canon); + +@@ -1262,7 +1262,7 @@ int read_hostsfile(char *filename, unsigned int index, int cache_size, struct cr + if (rhash) + rehash(name_count); + +- my_syslog(LOG_INFO, _("read %s - %d addresses"), filename, addr_count); ++ my_syslog(LOG_INFO, _("read %s - %d names"), filename, names_done); + + return name_count; + } +-- +2.27.0 + diff --git a/dnsmasq.spec b/dnsmasq.spec index 1147acccb56fbf41fe965079f631e212225a65a0..5612d7a680b4ab48f3d6af9035c6d461a2a066cf 100644 --- a/dnsmasq.spec +++ b/dnsmasq.spec @@ -1,6 +1,6 @@ Name: dnsmasq Version: 2.86 -Release: 4 +Release: 5 Summary: Dnsmasq provides network infrastructure for small networks License: GPLv2 or GPLv3 URL: http://www.thekelleys.org.uk/dnsmasq/ @@ -36,6 +36,16 @@ Patch25: backport-Fix-parsing-of-IPv6-addresses-with-peer-from-netlink.pa Patch26: backport-Fix-bad-interaction-between-address-ip-and-ser.patch Patch27: backport-Fix-address-which-was-lost-in-2.86.patch Patch28: backport-CVE-2023-28450-Set-the-default-maximum-DNS-UDP-packet.patch +Patch29: backport-Fix-namebuff-overwrite-leading-to-wrong-log-after-so.patch +Patch30: backport-Fix-bug-in-dynamic-host-when-interface-has-16-IPv4-a.patch +Patch31: backport-Fix-in-dhcpv4-rapid-commit-code.patch +Patch32: backport-Do-not-try-to-re-read-deleted-files-inside-a-hostsdi.patch +Patch33: backport-Reconcile-names-and-address-counts-when-reading-host.patch +Patch34: backport-Fix-GOST-signature-algorithms-for-DNSSEC-validation.patch +Patch35: backport-Handle-DS-records-for-unsupported-crypto-algorithms-.patch +Patch36: backport-Optimize-inserting-records-into-server-list.patch +Patch37: backport-Fix-massive-confusion-on-server-reload.patch +Patch38: backport-Fix-use-after-free-in-mark_servers.patch BuildRequires: gcc BuildRequires: dbus-devel pkgconfig libidn2-devel nettle-devel systemd @@ -125,6 +135,12 @@ install -Dpm644 %{SOURCE2} $RPM_BUILD_ROOT%{_sysusersdir}/dnsmasq.conf %{_mandir}/man8/dnsmasq* %changelog +* Tue Mar 28 2023 renmingshuai - 2.88-5 +- Type:bugfix +- Id:NA +- SUG:NA +- DESC:backport some upstream patches + * Sat Mar 18 2023 renmingshuai - 2.86-4 - Type:CVE - Id:CVE-2023-28450