aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Andree <mandree@FreeBSD.org>2023-03-18 09:17:49 +0000
committerMatthias Andree <mandree@FreeBSD.org>2023-03-18 09:17:49 +0000
commit7a10b554651ee1e9d051856b99c76c9311313947 (patch)
treeb0e122f15272ecbb21c07d4705fa701caa49f37f
parentda41aee2b26961aaf1ed1a455b1ab2721a938385 (diff)
downloadports-7a10b554651ee1e9d051856b99c76c9311313947.tar.gz
ports-7a10b554651ee1e9d051856b99c76c9311313947.zip
dns/dnsmasq: cherry-pick several upstream fixes
all from dnsmasq's Git repository hosted by Simon Kelley: + Fix DHCPv6 "use multicast" response + Avoid undefined behaviour with the ctype(3) functions. + Document suppressing default options in --dhcp-option. + Fix --rev-server option. + Set the default maximum DNS UDP packet size to 1232. + Generalise cached NXDOMAIN replies. + Fix possible SEGV when no servers defined. and bump PORTREVISION. This is so we can let it mature for two weeks before 2023Q2 and because the upstream release schedule is unforeseeable. Obtained from: Simon Kelley <simon@thekelleys.org.uk> Obtained from: Dominik Derigs <dl6er@dl6er.de> Obtained from: Taylor R Campbell <campbell+dnsmasq@mumble.net>
-rw-r--r--dns/dnsmasq/Makefile2
-rw-r--r--dns/dnsmasq/files/patch-00be8b39e240934e404533deda08cbae2aae25a846
-rw-r--r--dns/dnsmasq/files/patch-137ae2e9cf0dc3596641e7c8b91d15307a35319e218
-rw-r--r--dns/dnsmasq/files/patch-7d6b68c5d7016aca5372f12e9f0c25f0a108644d33
-rw-r--r--dns/dnsmasq/files/patch-997982f78bd3f8c311b9557e1ef825555e7290bb41
-rw-r--r--dns/dnsmasq/files/patch-eb92fb32b746f2104b0f370b5b295bb8dd4bd5e543
-rw-r--r--dns/dnsmasq/files/patch-ef8e930e4295265b8f46898a8e166f17d7f8ddc854
-rw-r--r--dns/dnsmasq/files/patch-f5ef0f064c3f06b250a9eeda36dc239227658b0056
8 files changed, 492 insertions, 1 deletions
diff --git a/dns/dnsmasq/Makefile b/dns/dnsmasq/Makefile
index 3752dda7c16d..4491bf4e1b05 100644
--- a/dns/dnsmasq/Makefile
+++ b/dns/dnsmasq/Makefile
@@ -1,7 +1,7 @@
PORTNAME= dnsmasq
DISTVERSION= 2.89
# Leave the PORTREVISION in even if 0 to avoid accidental PORTEPOCH bumps:
-PORTREVISION= 0
+PORTREVISION= 1
PORTEPOCH= 1
CATEGORIES= dns
MASTER_SITES= https://www.thekelleys.org.uk/dnsmasq/ \
diff --git a/dns/dnsmasq/files/patch-00be8b39e240934e404533deda08cbae2aae25a8 b/dns/dnsmasq/files/patch-00be8b39e240934e404533deda08cbae2aae25a8
new file mode 100644
index 000000000000..d638532fadc3
--- /dev/null
+++ b/dns/dnsmasq/files/patch-00be8b39e240934e404533deda08cbae2aae25a8
@@ -0,0 +1,46 @@
+From 00be8b39e240934e404533deda08cbae2aae25a8 Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Wed, 15 Mar 2023 21:12:55 +0000
+Subject: [PATCH] Fix DHCPv6 "use multicast" response which previously failed
+ to set the message type correctly.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=utf8
+Content-Transfer-Encoding: 8bit
+
+Thanks to Petr Menšík for spotting the problem.
+---
+ src/rfc3315.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/src/rfc3315.c b/src/rfc3315.c
+index 8754481..477df91 100644
+--- a/src/rfc3315.c
++++ b/src/rfc3315.c
+@@ -353,7 +353,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu
+ put_opt6_short(DHCP6USEMULTI);
+ put_opt6_string("Use multicast");
+ end_opt6(o1);
+- return 1;
++ goto done;
+ }
+
+ /* match vendor and user class options */
+@@ -1277,12 +1277,14 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu
+
+ }
+
++ log_tags(tagif, state->xid);
++
++ done:
+ /* Fill in the message type. Note that we store the offset,
+ not a direct pointer, since the packet memory may have been
+ reallocated. */
+ ((unsigned char *)(daemon->outpacket.iov_base))[start_msg] = outmsgtype;
+
+- log_tags(tagif, state->xid);
+ log6_opts(0, state->xid, daemon->outpacket.iov_base + start_opts, daemon->outpacket.iov_base + save_counter(-1));
+
+ return 1;
+--
+2.20.1
+
diff --git a/dns/dnsmasq/files/patch-137ae2e9cf0dc3596641e7c8b91d15307a35319e b/dns/dnsmasq/files/patch-137ae2e9cf0dc3596641e7c8b91d15307a35319e
new file mode 100644
index 000000000000..d87d90c8238f
--- /dev/null
+++ b/dns/dnsmasq/files/patch-137ae2e9cf0dc3596641e7c8b91d15307a35319e
@@ -0,0 +1,218 @@
+From 137ae2e9cf0dc3596641e7c8b91d15307a35319e Mon Sep 17 00:00:00 2001
+From: Taylor R Campbell <campbell+dnsmasq@mumble.net>
+Date: Sat, 25 Feb 2023 15:00:30 +0000
+Subject: [PATCH] Avoid undefined behaviour with the ctype(3) functions.
+
+As defined in the C standard:
+
+ In all cases the argument is an int, the value of which shall
+ be representable as an unsigned char or shall equal the value
+ of the macro EOF. If the argument has any other value, the
+ behavior is undefined.
+
+This is because they're designed to work with the int values returned
+by getc or fgetc; they need extra work to handle a char value.
+
+If EOF is -1 (as it almost always is), with 8-bit bytes, the allowed
+inputs to the ctype(3) functions are:
+
+ {-1, 0, 1, 2, 3, ..., 255}.
+
+However, on platforms where char is signed, such as x86 with the
+usual ABI, code like
+
+ char *arg = ...;
+ ... isspace(*arg) ...
+
+may pass in values in the range:
+
+ {-128, -127, -126, ..., -2, -1, 0, 1, ..., 127}.
+
+This has two problems:
+
+1. Inputs in the set {-128, -127, -126, ..., -2} are forbidden.
+
+2. The non-EOF byte 0xff is conflated with the value EOF = -1, so
+ even though the input is not forbidden, it may give the wrong
+ answer.
+
+Casting char to int first before passing the result to ctype(3)
+doesn't help: inputs like -128 are unchanged by this cast. It is
+necessary to cast char inputs to unsigned char first; you can then
+cast to int if you like but there's no need because the functions
+will always convert the argument to int by definition. So the above
+fragment needs to be:
+
+ char *arg = ...;
+ ... isspace((unsigned char)*arg) ...
+
+This patch inserts unsigned char casts where necessary, and changes
+int casts to unsigned char casts where the input is char.
+
+I left alone int casts where the input is unsigned char already --
+they're not immediately harmful, although they would have the effect
+of suppressing some compiler warnings if the input is ever changed to
+be char instead of unsigned char, so it might be better to remove
+those casts too.
+
+I also left alone calls where the input is int to begin with because
+it came from getc; casting to unsigned char here would be wrong, of
+course.
+---
+ src/dhcp-common.c | 6 +++---
+ src/dhcp.c | 6 +++---
+ src/loop.c | 2 +-
+ src/option.c | 8 ++++----
+ src/rfc1035.c | 2 +-
+ src/rfc2131.c | 2 +-
+ src/tftp.c | 2 +-
+ 7 files changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/src/dhcp-common.c b/src/dhcp-common.c
+index 84081ce..b4d255e 100644
+--- a/src/dhcp-common.c
++++ b/src/dhcp-common.c
+@@ -838,7 +838,7 @@ char *option_string(int prot, unsigned int opt, unsigned char *val, int opt_len,
+ for (i = 0, j = 0; i < opt_len && j < buf_len ; i++)
+ {
+ char c = val[i];
+- if (isprint((int)c))
++ if (isprint((unsigned char)c))
+ buf[j++] = c;
+ }
+ #ifdef HAVE_DHCP6
+@@ -852,7 +852,7 @@ char *option_string(int prot, unsigned int opt, unsigned char *val, int opt_len,
+ for (k = i + 1; k < opt_len && k < l && j < buf_len ; k++)
+ {
+ char c = val[k];
+- if (isprint((int)c))
++ if (isprint((unsigned char)c))
+ buf[j++] = c;
+ }
+ i = l;
+@@ -873,7 +873,7 @@ char *option_string(int prot, unsigned int opt, unsigned char *val, int opt_len,
+ for (k = 0; k < len && j < buf_len; k++)
+ {
+ char c = *p++;
+- if (isprint((int)c))
++ if (isprint((unsigned char)c))
+ buf[j++] = c;
+ }
+ i += len +2;
+diff --git a/src/dhcp.c b/src/dhcp.c
+index 42d819f..e578391 100644
+--- a/src/dhcp.c
++++ b/src/dhcp.c
+@@ -916,14 +916,14 @@ void dhcp_read_ethers(void)
+
+ lineno++;
+
+- while (strlen(buff) > 0 && isspace((int)buff[strlen(buff)-1]))
++ while (strlen(buff) > 0 && isspace((unsigned char)buff[strlen(buff)-1]))
+ buff[strlen(buff)-1] = 0;
+
+ if ((*buff == '#') || (*buff == '+') || (*buff == 0))
+ continue;
+
+- for (ip = buff; *ip && !isspace((int)*ip); ip++);
+- for(; *ip && isspace((int)*ip); ip++)
++ for (ip = buff; *ip && !isspace((unsigned char)*ip); ip++);
++ for(; *ip && isspace((unsigned char)*ip); ip++)
+ *ip = 0;
+ if (!*ip || parse_hex(buff, hwaddr, ETHER_ADDR_LEN, NULL, NULL) != ETHER_ADDR_LEN)
+ {
+diff --git a/src/loop.c b/src/loop.c
+index cd4855e..19bfae0 100644
+--- a/src/loop.c
++++ b/src/loop.c
+@@ -92,7 +92,7 @@ int detect_loop(char *query, int type)
+ return 0;
+
+ for (i = 0; i < 8; i++)
+- if (!isxdigit(query[i]))
++ if (!isxdigit((unsigned char)query[i]))
+ return 0;
+
+ uid = strtol(query, NULL, 16);
+diff --git a/src/option.c b/src/option.c
+index e4810fd..1090bca 100644
+--- a/src/option.c
++++ b/src/option.c
+@@ -2751,7 +2751,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
+ ret_err(gen_err);
+
+ for (p = arg; *p; p++)
+- if (!isxdigit((int)*p))
++ if (!isxdigit((unsigned char)*p))
+ ret_err(gen_err);
+
+ set_option_bool(OPT_UMBRELLA_DEVID);
+@@ -4836,7 +4836,7 @@ err:
+ new->target = target;
+ new->ttl = ttl;
+
+- for (arg += arglen+1; *arg && isspace(*arg); arg++);
++ for (arg += arglen+1; *arg && isspace((unsigned char)*arg); arg++);
+ }
+
+ break;
+@@ -5227,7 +5227,7 @@ err:
+ unhide_metas(keyhex);
+ /* 4034: "Whitespace is allowed within digits" */
+ for (cp = keyhex; *cp; )
+- if (isspace(*cp))
++ if (isspace((unsigned char)*cp))
+ for (cp1 = cp; *cp1; cp1++)
+ *cp1 = *(cp1+1);
+ else
+@@ -5315,7 +5315,7 @@ static void read_file(char *file, FILE *f, int hard_opt, int from_script)
+ memmove(p, p+1, strlen(p+1)+1);
+ }
+
+- if (isspace(*p))
++ if (isspace((unsigned char)*p))
+ {
+ *p = ' ';
+ white = 1;
+diff --git a/src/rfc1035.c b/src/rfc1035.c
+index 5c0df56..1693253 100644
+--- a/src/rfc1035.c
++++ b/src/rfc1035.c
+@@ -519,7 +519,7 @@ static int print_txt(struct dns_header *header, const size_t qlen, char *name,
+ /* make counted string zero-term and sanitise */
+ for (i = 0; i < len; i++)
+ {
+- if (!isprint((int)*(p3+1)))
++ if (!isprint((unsigned char)*(p3+1)))
+ break;
+ *p3 = *(p3+1);
+ p3++;
+diff --git a/src/rfc2131.c b/src/rfc2131.c
+index 17e97b5..5190982 100644
+--- a/src/rfc2131.c
++++ b/src/rfc2131.c
+@@ -1678,7 +1678,7 @@ static int sanitise(unsigned char *opt, char *buf)
+ for (i = option_len(opt); i > 0; i--)
+ {
+ char c = *p++;
+- if (isprint((int)c))
++ if (isprint((unsigned char)c))
+ *buf++ = c;
+ }
+ *buf = 0; /* add terminator */
+diff --git a/src/tftp.c b/src/tftp.c
+index 0861f37..8e1dc4a 100644
+--- a/src/tftp.c
++++ b/src/tftp.c
+@@ -405,7 +405,7 @@ void tftp_request(struct listener *listen, time_t now)
+ if (*p == '\\')
+ *p = '/';
+ else if (option_bool(OPT_TFTP_LC))
+- *p = tolower(*p);
++ *p = tolower((unsigned char)*p);
+
+ strcpy(daemon->namebuff, "/");
+ if (prefix)
+--
+2.20.1
+
diff --git a/dns/dnsmasq/files/patch-7d6b68c5d7016aca5372f12e9f0c25f0a108644d b/dns/dnsmasq/files/patch-7d6b68c5d7016aca5372f12e9f0c25f0a108644d
new file mode 100644
index 000000000000..5534e1ffbabd
--- /dev/null
+++ b/dns/dnsmasq/files/patch-7d6b68c5d7016aca5372f12e9f0c25f0a108644d
@@ -0,0 +1,33 @@
+From 7d6b68c5d7016aca5372f12e9f0c25f0a108644d Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Mon, 6 Mar 2023 13:06:03 +0000
+Subject: [PATCH] Document suppressing deafult options in --dhcp-option.
+
+---
+ man/dnsmasq.8 | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
+index 3d1d96a..41e2e04 100644
+--- a/man/dnsmasq.8
++++ b/man/dnsmasq.8
+@@ -1297,7 +1297,15 @@ and to set the time-server address to 192.168.0.4, do
+ or
+ .B --dhcp-option = option:ntp-server, 192.168.0.4
+ The special address 0.0.0.0 is taken to mean "the address of the
+-machine running dnsmasq".
++machine running dnsmasq".
++
++An option without data is valid, and includes just the option without data.
++(There is only one option with a zero length data field currently defined for DHCPv4, 80:rapid commit, so this feature is not very useful in practice). Options for which dnsmasq normally
++provides default values can be ommitted by defining the option with no data. These are
++netmask, broadcast, router, DNS server, domainname and hostname. Thus, for DHCPv4
++.B --dhcp-option = option:router
++will result in no router option being sent, rather than the default of the host on which dnsmasq is running. For DHCPv6, the same is true of the options DNS server and refresh time.
++
+
+ Data types allowed are comma separated
+ dotted-quad IPv4 addresses, []-wrapped IPv6 addresses, a decimal number, colon-separated hex digits
+--
+2.20.1
+
diff --git a/dns/dnsmasq/files/patch-997982f78bd3f8c311b9557e1ef825555e7290bb b/dns/dnsmasq/files/patch-997982f78bd3f8c311b9557e1ef825555e7290bb
new file mode 100644
index 000000000000..aeb8e8568069
--- /dev/null
+++ b/dns/dnsmasq/files/patch-997982f78bd3f8c311b9557e1ef825555e7290bb
@@ -0,0 +1,41 @@
+From 997982f78bd3f8c311b9557e1ef825555e7290bb Mon Sep 17 00:00:00 2001
+From: Dominik Derigs <dl6er@dl6er.de>
+Date: Fri, 3 Mar 2023 18:05:26 +0100
+Subject: [PATCH] Fix --rev-server option. It was broken in
+ 1db9943c6879c160a5fbef885d5ceadd3668b74d when resolving upstream servers by
+ name was extended to --rev-server without accounting for the fact that
+ re-using one and the same upstream server for each of the x.y.z.in-addr.arpa
+ is actually a wanted feature
+
+Signed-off-by: DL6ER <dl6er@dl6er.de>
+---
+ src/option.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/src/option.c b/src/option.c
+index 1090bca..2e208ba 100644
+--- a/src/option.c
++++ b/src/option.c
+@@ -1159,6 +1159,9 @@ static char *domain_rev4(int from_file, char *server, struct in_addr *addr4, int
+ }
+ else
+ {
++ /* Always reset server as valid here, so we can add the same upstream
++ server address multiple times for each x.y.z.in-addr.arpa */
++ sdetails.valid = 1;
+ while (parse_server_next(&sdetails))
+ {
+ if ((string = parse_server_addr(&sdetails)))
+@@ -1244,6 +1247,9 @@ static char *domain_rev6(int from_file, char *server, struct in6_addr *addr6, in
+ }
+ else
+ {
++ /* Always reset server as valid here, so we can add the same upstream
++ server address multiple times for each x.y.z.ip6.arpa */
++ sdetails.valid = 1;
+ while (parse_server_next(&sdetails))
+ {
+ if ((string = parse_server_addr(&sdetails)))
+--
+2.20.1
+
diff --git a/dns/dnsmasq/files/patch-eb92fb32b746f2104b0f370b5b295bb8dd4bd5e5 b/dns/dnsmasq/files/patch-eb92fb32b746f2104b0f370b5b295bb8dd4bd5e5
new file mode 100644
index 000000000000..9251423ff89f
--- /dev/null
+++ b/dns/dnsmasq/files/patch-eb92fb32b746f2104b0f370b5b295bb8dd4bd5e5
@@ -0,0 +1,43 @@
+From eb92fb32b746f2104b0f370b5b295bb8dd4bd5e5 Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Tue, 7 Mar 2023 22:07:46 +0000
+Subject: [PATCH] Set the default maximum DNS UDP packet size to 1232.
+
+http://www.dnsflagday.net/2020/ refers.
+
+Thanks to Xiang Li for the prompt.
+---
+ man/dnsmasq.8 | 3 ++-
+ src/config.h | 2 +-
+ 3 files changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
+index 41e2e04..5acb935 100644
+--- a/man/dnsmasq.8
++++ b/man/dnsmasq.8
+@@ -183,7 +183,8 @@ to zero completely disables DNS function, leaving only DHCP and/or TFTP.
+ .TP
+ .B \-P, --edns-packet-max=<size>
+ Specify the largest EDNS.0 UDP packet which is supported by the DNS
+-forwarder. Defaults to 4096, which is the RFC5625-recommended size.
++forwarder. Defaults to 1232, which is the recommended size following the
++DNS flag day in 2020. Only increase if you know what you are doing.
+ .TP
+ .B \-Q, --query-port=<query_port>
+ Send outbound DNS queries from, and listen for their replies on, the
+diff --git a/src/config.h b/src/config.h
+index 1e7b30f..37b374e 100644
+--- a/src/config.h
++++ b/src/config.h
+@@ -19,7 +19,7 @@
+ #define CHILD_LIFETIME 150 /* secs 'till terminated (RFC1035 suggests > 120s) */
+ #define TCP_MAX_QUERIES 100 /* Maximum number of queries per incoming TCP connection */
+ #define TCP_BACKLOG 32 /* kernel backlog limit for TCP connections */
+-#define EDNS_PKTSZ 4096 /* default max EDNS.0 UDP packet from RFC5625 */
++#define EDNS_PKTSZ 1232 /* default max EDNS.0 UDP packet from from /dnsflagday.net/2020 */
+ #define SAFE_PKTSZ 1232 /* "go anywhere" UDP packet size, see https://dnsflagday.net/2020/ */
+ #define KEYBLOCK_LEN 40 /* choose to minimise fragmentation when storing DNSSEC keys */
+ #define DNSSEC_WORK 50 /* Max number of queries to validate one question */
+--
+2.20.1
+
diff --git a/dns/dnsmasq/files/patch-ef8e930e4295265b8f46898a8e166f17d7f8ddc8 b/dns/dnsmasq/files/patch-ef8e930e4295265b8f46898a8e166f17d7f8ddc8
new file mode 100644
index 000000000000..d14c863556f8
--- /dev/null
+++ b/dns/dnsmasq/files/patch-ef8e930e4295265b8f46898a8e166f17d7f8ddc8
@@ -0,0 +1,54 @@
+From ef8e930e4295265b8f46898a8e166f17d7f8ddc8 Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Tue, 7 Mar 2023 22:46:44 +0000
+Subject: [PATCH] Generalise cached NXDOMAIN replies.
+
+We can cache an NXDOMAIN reply to a query for any RRTYPE
+and reply from a cached NXDOMAIN to any RRTYPE.
+---
+ src/rfc1035.c | 22 ++++++++++++++++++----
+ 1 file changed, 18 insertions(+), 4 deletions(-)
+
+diff --git a/src/rfc1035.c b/src/rfc1035.c
+index 1693253..3d82ad9 100644
+--- a/src/rfc1035.c
++++ b/src/rfc1035.c
+@@ -894,9 +894,8 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
+ {
+ flags &= ~(F_IPV4 | F_IPV6 | F_SRV);
+
+- /* Can store NXDOMAIN reply to CNAME or ANY query. */
+- if (qtype == T_CNAME || qtype == T_ANY)
+- insert = 1;
++ /* Can store NXDOMAIN reply for any qtype. */
++ insert = 1;
+ }
+
+ log_query(F_UPSTREAM | F_FORWARD | F_NEG | flags | (secure ? F_DNSSECOK : 0), name, NULL, NULL, 0);
+@@ -2081,7 +2080,22 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
+ }
+
+ if (!ans)
+- return 0; /* failed to answer a question */
++ {
++ /* We may know that the domain doesn't exist for any RRtype. */
++ if ((crecp = cache_find_by_name(NULL, name, now, F_NXDOMAIN)))
++ {
++ ans = nxdomain = 1;
++ auth = 0;
++
++ if (!(crecp->flags & F_DNSSECOK))
++ sec_data = 0;
++
++ if (!dryrun)
++ log_query(F_NXDOMAIN | F_NEG, name, NULL, NULL, 0);
++ }
++ else
++ return 0; /* failed to answer a question */
++ }
+ }
+
+ if (dryrun)
+--
+2.20.1
+
diff --git a/dns/dnsmasq/files/patch-f5ef0f064c3f06b250a9eeda36dc239227658b00 b/dns/dnsmasq/files/patch-f5ef0f064c3f06b250a9eeda36dc239227658b00
new file mode 100644
index 000000000000..34baa142f5ed
--- /dev/null
+++ b/dns/dnsmasq/files/patch-f5ef0f064c3f06b250a9eeda36dc239227658b00
@@ -0,0 +1,56 @@
+From f5ef0f064c3f06b250a9eeda36dc239227658b00 Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Mon, 6 Mar 2023 23:00:58 +0000
+Subject: [PATCH] Fix possible SEGV when no servers defined.
+
+If there exists a --address=/<domain>/ or --server=/<domain>/#
+configuration but no upstream server config unqualified by
+domain then when a query which doesnt match the domain is
+recieved it will use the qualfied server config and in the process
+possibly make an out-of-bounds memory access.
+
+Thanks to Daniel Danzberger for spotting the bug.
+---
+ CHANGELOG | 11 +++++++++++
+ src/domain-match.c | 5 +++--
+ 2 files changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/CHANGELOG b/CHANGELOG
+index de9c5e0..3af20cf 100644
+--- a/CHANGELOG
++++ b/CHANGELOG
+@@ -1,3 +1,14 @@
++version 2.90
++ Fix reversion in --rev-server introduced in 2.88 which
++ caused breakage if the prefix length is not exactly divisible
++ by 8 (IPv4) or 4 (IPv6).
++
++ Fix possible SEGV when there server(s) for a particular
++ domain are configured, but no server which is not qualified
++ for a particular domain. Thanks to Daniel Danzberger for
++ spotting this bug.
++
++
+ version 2.89
+ Fix bug introduced in 2.88 (commit fe91134b) which can result
+ in corruption of the DNS cache internal data structures and
+diff --git a/src/domain-match.c b/src/domain-match.c
+index fe8e25a..9cc51e6 100644
+--- a/src/domain-match.c
++++ b/src/domain-match.c
+@@ -253,9 +253,10 @@ int lookup_domain(char *domain, int flags, int *lowout, int *highout)
+ if (highout)
+ *highout = nhigh;
+
+- if (nlow == nhigh)
++ /* qlen == -1 when we failed to match even an empty query, if there are no default servers. */
++ if (nlow == nhigh || qlen == -1)
+ return 0;
+-
++
+ return 1;
+ }
+
+--
+2.20.1
+