From 90dbdf56829c09ef092ad1ffe7b3813af7ec4554 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= Date: Wed, 6 Aug 2025 18:06:35 +0200 Subject: [PATCH] Backport filter-A and filter-AAAA options Upstream commit: http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=eb1fe15ca80b6bc43cd6bfdf309ec6c590aff811 Discussion: https://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2021q2/015107.html Resolves: RHEL-105367 --- dnsmasq-2.87-filter-AAAA.patch | 210 +++++++++++++++++++++++++++++++++ dnsmasq.spec | 8 +- 2 files changed, 217 insertions(+), 1 deletion(-) create mode 100644 dnsmasq-2.87-filter-AAAA.patch diff --git a/dnsmasq-2.87-filter-AAAA.patch b/dnsmasq-2.87-filter-AAAA.patch new file mode 100644 index 0000000..dbad08e --- /dev/null +++ b/dnsmasq-2.87-filter-AAAA.patch @@ -0,0 +1,210 @@ +From b4102039739ffbf9654b25ac974edca24e98c27c Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Thu, 7 Oct 2021 23:12:59 +0100 +Subject: [PATCH] Add --filter and --filter-AAAA options. + +(cherry picked from commit 37a70d39e0cd49f086b757937fa8735e6263cd7a) +--- + man/dnsmasq.8 | 6 ++++++ + src/dnsmasq.h | 10 ++++++++-- + src/edns0.c | 2 +- + src/forward.c | 16 +++++++++++++--- + src/option.c | 8 +++++++- + src/rrfilter.c | 37 +++++++++++++++++++++++++++---------- + 6 files changed, 62 insertions(+), 17 deletions(-) + +diff --git a/man/dnsmasq.8 b/man/dnsmasq.8 +index 8bb81b6..e47ee5f 100644 +--- a/man/dnsmasq.8 ++++ b/man/dnsmasq.8 +@@ -348,6 +348,12 @@ the public DNS and can cause problems by triggering dial-on-demand links. This f + to filter such requests. The requests blocked are for records of types SOA and SRV, and type ANY where the + requested name has underscores, to catch LDAP requests. + .TP ++.B --filter-A ++Remove A records from answers. No IPv4 addresses will be returned. ++.TP ++.B --filter-AAAA ++Remove AAAA records from answers. No IPv6 addresses will be returned. ++.TP + .B \-r, --resolv-file= + Read the IP addresses of the upstream nameservers from , instead of + /etc/resolv.conf. For the format of this file see +diff --git a/src/dnsmasq.h b/src/dnsmasq.h +index 6fa2593..5f6d63b 100644 +--- a/src/dnsmasq.h ++++ b/src/dnsmasq.h +@@ -270,7 +270,9 @@ struct event_desc { + #define OPT_SINGLE_PORT 60 + #define OPT_LEASE_RENEW 61 + #define OPT_LOG_DEBUG 62 +-#define OPT_LAST 63 ++#define OPT_FILTER_A 67 ++#define OPT_FILTER_AAAA 68 ++#define OPT_LAST 69 + + #define OPTION_BITS (sizeof(unsigned int)*8) + #define OPTION_SIZE ( (OPT_LAST/OPTION_BITS)+((OPT_LAST%OPTION_BITS)!=0) ) +@@ -1706,7 +1708,11 @@ int do_poll(int timeout); + size_t rrfilter(struct dns_header *header, size_t plen, int mode); + short *rrfilter_desc(int type); + int expand_workspace(unsigned char ***wkspc, int *szp, int new); +- ++/* modes. */ ++#define RRFILTER_EDNS0 0 ++#define RRFILTER_DNSSEC 1 ++#define RRFILTER_A 2 ++#define RRFILTER_AAAA 3 + /* edns0.c */ + unsigned char *find_pseudoheader(struct dns_header *header, size_t plen, + size_t *len, unsigned char **p, int *is_sign, int *is_last); +diff --git a/src/edns0.c b/src/edns0.c +index 33b5283..b1615ae 100644 +--- a/src/edns0.c ++++ b/src/edns0.c +@@ -178,7 +178,7 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l + memcpy(buff, datap, rdlen); + + /* now, delete OPT RR */ +- plen = rrfilter(header, plen, 0); ++ plen = rrfilter(header, plen, RRFILTER_EDNS0); + + /* Now, force addition of a new one */ + p = NULL; +diff --git a/src/forward.c b/src/forward.c +index 388b0c3..36c769a 100644 +--- a/src/forward.c ++++ b/src/forward.c +@@ -710,7 +710,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server + if (added_pheader) + { + /* client didn't send EDNS0, we added one, strip it off before returning answer. */ +- n = rrfilter(header, n, 0); ++ n = rrfilter(header, n, RRFILTER_EDNS0); + pheader = NULL; + } + else +@@ -793,7 +793,17 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server + SET_RCODE(header, NOERROR); + cache_secure = 0; + } +- ++ ++ /* Before extract_addresses() */ ++ if (rcode == NOERROR) ++ { ++ if (option_bool(OPT_FILTER_A)) ++ n = rrfilter(header, n, RRFILTER_A); ++ ++ if (option_bool(OPT_FILTER_AAAA)) ++ n = rrfilter(header, n, RRFILTER_AAAA); ++ } ++ + if (extract_addresses(header, n, daemon->namebuff, now, sets, is_sign, check_rebind, no_cache, cache_secure, &doctored)) + { + my_syslog(LOG_WARNING, _("possible DNS-rebind attack detected: %s"), daemon->namebuff); +@@ -822,7 +832,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server + + /* If the requestor didn't set the DO bit, don't return DNSSEC info. */ + if (!do_bit) +- n = rrfilter(header, n, 1); ++ n = rrfilter(header, n, RRFILTER_DNSSEC); + } + #endif + +diff --git a/src/option.c b/src/option.c +index 8b40332..44bc46f 100644 +--- a/src/option.c ++++ b/src/option.c +@@ -171,7 +171,9 @@ struct myoption { + #define LOPT_DYNHOST 362 + #define LOPT_LOG_DEBUG 363 + #define LOPT_DNSSEC_LIMITS 364 +- ++#define LOPT_FILTER_A 369 ++#define LOPT_FILTER_AAAA 370 ++ + #ifdef HAVE_GETOPT_LONG + static const struct option opts[] = + #else +@@ -208,6 +210,8 @@ static const struct myoption opts[] = + { "ignore-address", 1, 0, LOPT_IGNORE_ADDR }, + { "selfmx", 0, 0, 'e' }, + { "filterwin2k", 0, 0, 'f' }, ++ { "filter-A", 0, 0, LOPT_FILTER_A }, ++ { "filter-AAAA", 0, 0, LOPT_FILTER_AAAA }, + { "pid-file", 2, 0, 'x' }, + { "strict-order", 0, 0, 'o' }, + { "server", 1, 0, 'S' }, +@@ -374,6 +378,8 @@ static struct { + { 'e', OPT_SELFMX, NULL, gettext_noop("Return self-pointing MX records for local hosts."), NULL }, + { 'E', OPT_EXPAND, NULL, gettext_noop("Expand simple names in /etc/hosts with domain-suffix."), NULL }, + { 'f', OPT_FILTER, NULL, gettext_noop("Don't forward spurious DNS requests from Windows hosts."), NULL }, ++ { LOPT_FILTER_A, OPT_FILTER_A, NULL, gettext_noop("Don't include IPv4 addresses in DNS answers."), NULL }, ++ { LOPT_FILTER_AAAA, OPT_FILTER_AAAA, NULL, gettext_noop("Don't include IPv6 addresses in DNS answers."), NULL }, + { 'F', ARG_DUP, ",...", gettext_noop("Enable DHCP in the range given with lease duration."), NULL }, + { 'g', ARG_ONE, "", gettext_noop("Change to this group after startup (defaults to %s)."), CHGRP }, + { 'G', ARG_DUP, "", gettext_noop("Set address or hostname for a specified machine."), NULL }, +diff --git a/src/rrfilter.c b/src/rrfilter.c +index 32ef34a..262c114 100644 +--- a/src/rrfilter.c ++++ b/src/rrfilter.c +@@ -156,7 +156,7 @@ static int check_rrs(unsigned char *p, struct dns_header *header, size_t plen, i + } + + +-/* mode is 0 to remove EDNS0, 1 to filter DNSSEC RRs */ ++/* mode may be remove EDNS0 or DNSSEC RRs or remove A or AAAA from answer section. */ + size_t rrfilter(struct dns_header *header, size_t plen, int mode) + { + static unsigned char **rrs; +@@ -192,20 +192,37 @@ size_t rrfilter(struct dns_header *header, size_t plen, int mode) + if (!ADD_RDLEN(header, p, plen, rdlen)) + return plen; + +- /* Don't remove the answer. */ +- if (i < ntohs(header->ancount) && type == qtype && class == qclass) +- continue; +- +- if (mode == 0) /* EDNS */ ++ if (mode == RRFILTER_EDNS0) /* EDNS */ + { + /* EDNS mode, remove T_OPT from additional section only */ + if (i < (ntohs(header->nscount) + ntohs(header->ancount)) || type != T_OPT) + continue; + } +- else if (type != T_NSEC && type != T_NSEC3 && type != T_RRSIG) +- /* DNSSEC mode, remove SIGs and NSECs from all three sections. */ +- continue; +- ++ else if (mode == RRFILTER_DNSSEC) ++ { ++ if (type != T_NSEC && type != T_NSEC3 && type != T_RRSIG) ++ /* DNSSEC mode, remove SIGs and NSECs from all three sections. */ ++ continue; ++ ++ /* Don't remove the answer. */ ++ if (i < ntohs(header->ancount) && type == qtype && class == qclass) ++ continue; ++ } ++ else ++ { ++ /* Only looking at answer section now. */ ++ if (i >= ntohs(header->ancount)) ++ break; ++ ++ if (class != C_IN) ++ continue; ++ ++ if (mode == RRFILTER_A && type != T_A) ++ continue; ++ ++ if (mode == RRFILTER_AAAA && type != T_AAAA) ++ continue; ++ } + + if (!expand_workspace(&rrs, &rr_sz, rr_found + 1)) + return plen; +-- +2.50.1 + diff --git a/dnsmasq.spec b/dnsmasq.spec index a9dc92a..214d643 100644 --- a/dnsmasq.spec +++ b/dnsmasq.spec @@ -20,7 +20,7 @@ Name: dnsmasq Version: 2.85 -Release: 16%{?extraversion:.%{extraversion}}%{?dist} +Release: 17%{?extraversion:.%{extraversion}}%{?dist} Summary: A lightweight DHCP/caching DNS server License: GPLv2 or GPLv3 @@ -73,6 +73,9 @@ Patch15: dnsmasq-2.87-coverity-forward-cache.patch Patch16: dnsmasq-2.86-tcp-free-fd-rh2188443.patch # https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=214a046f47b9f7dd56f5eef3a8678ccbd6e973b7 Patch17: dnsmasq-2.90-CVE-2023-50387-CVE-2023-50868.patch +# https://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2021q2/015107.html +# http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=eb1fe15ca80b6bc43cd6bfdf309ec6c590aff811 +Patch18: dnsmasq-2.87-filter-AAAA.patch # This is workaround to nettle bug #1549190 # https://bugzilla.redhat.com/show_bug.cgi?id=1549190 @@ -216,6 +219,9 @@ install -Dpm 644 %{SOURCE2} %{buildroot}%{_sysusersdir}/%{name}.conf %{_mandir}/man1/dhcp_* %changelog +* Wed Aug 06 2025 Petr Menšík - 2.85-17 +- Backport filter-A and filter-AAAA options (RHEL-105367) + * Fri Mar 15 2024 Tomas Korbar - 2.85-16 - Fix CVE 2023-50387 and CVE 2023-50868 - Resolves: RHEL-25639