import UBI dnsmasq-2.90-7.el10_2

This commit is contained in:
AlmaLinux RelEng Bot 2026-05-19 19:33:56 -04:00
parent 697a96b620
commit cc6422580f
9 changed files with 373 additions and 1 deletions

View File

@ -0,0 +1,36 @@
From b8544d5802e56186eb144fbcdd18070b01dc9ab0 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Fri, 10 Apr 2026 16:29:31 +0100
Subject: [PATCH 1/5] Fix buffer overflow in struct bigname. CVE-2026-2291
All buffers capable of holding a domain name should be
at least MAXDNAME*2 + 1 bytes long, where MAXDNAME is the maximum
size of a domain name. The accounts for the trailing zero and the
fact that some characters are escaped in the internal representation
of a domain name in dnsmasq.
The declaration of struct bigname get this wrong, with the effect
that a remote attacker capable of asking DNS queries or answering DNS
queries can cause a large OOB write in the heap.
This was first spotted by Andrew S. Fasano.
---
src/dnsmasq.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index e455c3f..be8cf2a 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -467,7 +467,7 @@ struct interface_name {
};
union bigname {
- char name[MAXDNAME];
+ char name[(2*MAXDNAME) + 1];
union bigname *next; /* freelist */
};
--
2.54.0

View File

@ -0,0 +1,70 @@
From 09fe631edd6d95630efc11bec8c5017705e68a10 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Fri, 10 Apr 2026 22:16:45 +0100
Subject: [PATCH 2/5] Fix NSEC bitmap parsing infinite loop. CVE-2026-4890
Report from Royce M <royce@xchglabs.com>.
Location: dnssec.c:1290-1306, dnssec.c:1450-1463
The bitmap window iteration advances by p[1] instead of p[1]+2 (missing the 2-byte window header). With bitmap_length=0, both rdlen and p are
unchanged, causing an infinite loop and dnsmasq stops responding to all queries.
The same code accesses p[2] after only checking rdlen >= 2 without verifying p[1] >= 1, causing OOB reads at 6 locations.
Both bugs are reachable before RRSIG validation (confirmed by the source comment at line 2125), so no valid DNSSEC signatures are needed.
---
src/dnssec.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/dnssec.c b/src/dnssec.c
index ed2f53f..68f1b5d 100644
--- a/src/dnssec.c
+++ b/src/dnssec.c
@@ -1270,10 +1270,10 @@ static int prove_non_existence_nsec(struct dns_header *header, size_t plen, unsi
packet checked to be as long as rdlen implies in prove_non_existence() */
/* If we can prove that there's no NS record, return that information. */
- if (nons && rdlen >= 2 && p[0] == 0 && (p[2] & (0x80 >> T_NS)) != 0)
+ if (nons && rdlen >= 2 && p[0] == 0 && p[1] >= 1 && (p[2] & (0x80 >> T_NS)) != 0)
*nons = 0;
- if (rdlen >= 2 && p[0] == 0)
+ if (rdlen >= 2 && p[0] == 0 && p[1] >= 1)
{
/* A CNAME answer would also be valid, so if there's a CNAME is should
have been returned. */
@@ -1301,8 +1301,8 @@ static int prove_non_existence_nsec(struct dns_header *header, size_t plen, unsi
break; /* finished checking */
}
- rdlen -= p[1];
- p += p[1];
+ rdlen -= p[1] + 2;
+ p += p[1] + 2;
}
return 0;
@@ -1429,7 +1429,7 @@ static int check_nsec3_coverage(struct dns_header *header, size_t plen, int dige
p += hash_len; /* skip next-domain hash */
rdlen -= p - psave;
- if (rdlen >= 2 && p[0] == 0)
+ if (rdlen >= 2 && p[0] == 0 && p[1] >= 1)
{
/* If we can prove that there's no NS record, return that information. */
if (nons && (p[2] & (0x80 >> T_NS)) != 0)
@@ -1458,8 +1458,8 @@ static int check_nsec3_coverage(struct dns_header *header, size_t plen, int dige
break; /* finished checking */
}
- rdlen -= p[1];
- p += p[1];
+ rdlen -= p[1] + 2;
+ p += p[1] + 2;
}
return 1;
--
2.54.0

View File

@ -0,0 +1,39 @@
From 2efe6d3acaf840fa06d58b6fad21ad73d0865716 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Wed, 25 Mar 2026 23:04:08 +0000
Subject: [PATCH 3/5] Verify rdlen field in RRSIG packets. CVE-2026-4891
Bug report from Royce M <royce@xchglabs.com>
This avoids crafted packets which give a value for rdlen _less_
then the space taken up by the fixed data and the signer's name
and engender a negative calculated length for the signature.
---
src/dnssec.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/dnssec.c b/src/dnssec.c
index 68f1b5d..d32db5b 100644
--- a/src/dnssec.c
+++ b/src/dnssec.c
@@ -546,10 +546,14 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
*ttl_out = ttl;
}
-
+
+ /* Don't trust rdlen not to be too small and give us a negative sig_len
+ It has already been checked that it doesn't run us off the end
+ of the packet. */
+ if ((sig_len = rdlen - (p - psav)) <= 0)
+ return STAT_BOGUS;
+
sig = p;
- sig_len = rdlen - (p - psav);
-
nsigttl = htonl(orig_ttl);
hash->update(ctx, 18, psav);
--
2.54.0

View File

@ -0,0 +1,36 @@
From e0a5f7bef040d25631ffff9abaf8424091b768bc Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Wed, 25 Mar 2026 23:16:35 +0000
Subject: [PATCH 4/5] Fix buffer overflow in helper.c with large CLIDs.
CVE-2026-4892
Bug reported bt Royce M <royce@xchglabs.com>
Location: helper.c:265-270
DHCPv6 CLIDs can be up to 65535 bytes. When --dhcp-script is configured,
the helper hex-encodes raw CLID bytes via sprintf("%.2x") into daemon->packet (5131 bytes).
A 1000-byte CLID writes ~3000 bytes. The helper process retains root privileges.
Note: log6_packet() correctly caps CLID to 100 bytes for logging, but the helper code path was missed.
---
src/helper.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/helper.c b/src/helper.c
index b9da225..3a31e61 100644
--- a/src/helper.c
+++ b/src/helper.c
@@ -261,8 +261,8 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
data.hostname_len + data.ed_len + data.clid_len, 1))
continue;
- /* CLID into packet */
- for (p = daemon->packet, i = 0; i < data.clid_len; i++)
+ /* CLID into packet: limit to 100 bytes to avoid overflowing buffer. */
+ for (p = daemon->packet, i = 0; i < data.clid_len && i < 100; i++)
{
p += sprintf(p, "%.2x", buf[i]);
if (i != data.clid_len - 1)
--
2.54.0

View File

@ -0,0 +1,33 @@
From a3f7490baf68fc52c839b9257d20f0b35c38cc27 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Wed, 25 Mar 2026 23:22:37 +0000
Subject: [PATCH 5/5] Fix broken client subnet validation. CVE-2026-4893
Bug report from Royce M <royce@xchglabs.com>
Location: forward.c:713, edns0.c:421
With --add-subnet enabled, process_reply() passes the OPT record
length (~23 bytes) instead of the packet length to check_source().
All internal bounds checks fail, and the function always returns 1.
ECS source validation per RFC 7871 Section 9.2 is completely bypassed.
---
src/forward.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/forward.c b/src/forward.c
index 32f37e4..19ff440 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
/* Get extended RCODE. */
rcode |= sizep[2] << 4;
- if (option_bool(OPT_CLIENT_SUBNET) && !check_source(header, plen, pheader, query_source))
+ if (option_bool(OPT_CLIENT_SUBNET) && !check_source(header, n, pheader, query_source))
{
my_syslog(LOG_WARNING, _("discarding DNS reply: subnet option mismatch"));
return 0;
--
2.54.0

View File

@ -0,0 +1,33 @@
From 9530d9ac81596521c450862a31a95e9025336e59 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Mon, 30 Mar 2026 16:24:33 +0100
Subject: [PATCH] Fix buffer overflow vulnerability in extract_addresses()
CVE-2026-5172
Thanks to Hugo Martinez Ray for spotting this.
The value of rdlen for an RR can be a lie, allowing the
call to extract_name() at rfc1025.c:952 to advance the value of p1
past the calculated end of the record. The makes the calculation
of bytes remaining in the RR underflow to a huge number and results
in a massive heap OOB read and certain crash.
---
src/rfc1035.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/rfc1035.c b/src/rfc1035.c
index ad70f6c..a6fdfe2 100644
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -932,7 +932,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
/* Name, extract it then re-encode. */
int len;
- if (!extract_name(header, qlen, &p1, name, 1, 0))
+ if (!extract_name(header, qlen, &p1, name, 1, 0) || (p1 > endrr))
{
blockdata_free(addr.rrblock.rrdata);
return 2;
--
2.54.0

View File

@ -0,0 +1,95 @@
From 74b2a7d33baa96761c14433671916c1c153d6017 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Tue, 24 Feb 2026 20:36:04 +0100
Subject: [PATCH] Fix improper validated wire format of DNS name
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ensure extract_name stops whenever name is longer than 255 bytes. That
is defined by RFC 1035 and MAXDNAME is derived from that length. Dnsmasq
until now relied on upstream servers filtering similar responses to be
filtered out.
Stop immediately if the packet is big enough, but binary name length
exceeds 255 bytes. That is prerequisite for escaped name to become
longer than existing buffer long MAXDNAME. Introduce new MAXWNAME
constant for on-wire length limit. MAXDNAME remains escaped
"presentation" format limit, possibly containing IDN or escaping.
Standard escaping is \ddd, where ddd are decadic value of that byte.
Such escaping is not implemented by dnsmasq. MAXDNAME should be large
enough for any escaped names as long as MAXWNAME cannot exceed defined
length.
Signed-off-by: Petr Menšík <pemensik@redhat.com>
---
src/dns-protocol.h | 1 +
src/rfc1035.c | 2 +-
src/rrfilter.c | 14 ++++++++++----
3 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/src/dns-protocol.h b/src/dns-protocol.h
index e71bedc4..8103b558 100644
--- a/src/dns-protocol.h
+++ b/src/dns-protocol.h
@@ -23,6 +23,7 @@
#define INADDRSZ 4
#define PACKETSZ 512 /* maximum packet size */
+#define MAXWNAME 255 /* maximum on-wire domain name */
#define MAXDNAME 1025 /* maximum presentation domain name */
#define RRFIXEDSZ 10 /* #/bytes of fixed data in r record */
#define MAXLABEL 63 /* maximum length of domain label */
diff --git a/src/rfc1035.c b/src/rfc1035.c
index f0e10822..bea30380 100644
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -109,7 +109,7 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
else if (label_type == 0x00)
{ /* label_type = 0 -> label. */
namelen += l + 1; /* include period */
- if (namelen >= MAXDNAME)
+ if (namelen > MAXWNAME)
return 0;
if (!CHECK_LEN(header, p, plen, l))
return 0;
diff --git a/src/rrfilter.c b/src/rrfilter.c
index 29f69c74..b8093cf5 100644
--- a/src/rrfilter.c
+++ b/src/rrfilter.c
@@ -23,6 +23,7 @@
static int check_name(unsigned char **namep, struct dns_header *header, size_t plen, int fixup, unsigned char **rrs, int rr_count)
{
unsigned char *ansp = *namep;
+ unsigned int namelen = 0;
while(1)
{
@@ -84,15 +85,20 @@ static int check_name(unsigned char **namep, struct dns_header *header, size_t p
count = *(ansp++); /* Bits in bitstring */
if (count == 0) /* count == 0 means 256 bits */
- ansp += 32;
+ count = 32;
else
- ansp += ((count-1)>>3)+1;
+ count = ((count-1)>>3)+1;
+ namelen += count + 1;
+ if (namelen > MAXWNAME)
+ return 0;
+ ansp += count;
}
else
{ /* label type == 0 Bottom six bits is length */
unsigned int len = (*ansp++) & 0x3f;
-
- if (!ADD_RDLEN(header, ansp, plen, len))
+
+ namelen += len + 1;
+ if (!ADD_RDLEN(header, ansp, plen, len) || namelen > MAXWNAME)
return 0;
if (len == 0)
--
2.53.0

View File

@ -23,7 +23,7 @@
Name: dnsmasq
Version: 2.90
Release: 4%{?extraversion:.%{extraversion}}%{?dist}
Release: 7%{?extraversion:.%{extraversion}}%{?dist}
Summary: A lightweight DHCP/caching DNS server
# SPDX identifiers already
@ -40,12 +40,21 @@ Source4: %{url}%{?extrapath}test-release-public-key
%else
Source4: http://www.thekelleys.org.uk/srkgpg.txt
%endif
Source5: tmpfiles-dnsmasq.conf
# https://bugzilla.redhat.com/show_bug.cgi?id=1495409
Patch1: dnsmasq-2.77-underflow.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1852373
Patch2: dnsmasq-2.81-configuration.patch
Patch3: dnsmasq-2.78-fips.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2439088
Patch4: dnsmasq-CVE-2026-2291.patch
Patch5: dnsmasq-2.93-CVE-2026-2291.patch
Patch6: dnsmasq-2.93-CVE-2026-4890.patch
Patch7: dnsmasq-2.93-CVE-2026-4891.patch
Patch8: dnsmasq-2.93-CVE-2026-4892.patch
Patch9: dnsmasq-2.93-CVE-2026-4893.patch
Patch10: dnsmasq-2.93-CVE-2026-5172.patch
Requires: nettle
@ -174,6 +183,9 @@ rm -rf %{buildroot}%{_initrddir}
#install systemd sysuser file
install -Dpm 644 %{SOURCE2} %{buildroot}%{_sysusersdir}/%{name}.conf
# install tmpfiles.d config
install -Dpm 644 %{SOURCE5} %{buildroot}%{_tmpfilesdir}/%{name}.conf
%if %{with i18n}
%make_install PREFIX=/usr install-i18n
%find_lang %{name} --with-man
@ -205,6 +217,7 @@ install -Dpm 644 %{SOURCE2} %{buildroot}%{_sysusersdir}/%{name}.conf
%dir %{_datadir}/%{name}
%{_datadir}/%{name}/trust-anchors.conf
%{_sysusersdir}/dnsmasq.conf
%{_tmpfilesdir}/dnsmasq.conf
%files utils
%license COPYING COPYING-v3
@ -216,6 +229,22 @@ install -Dpm 644 %{SOURCE2} %{buildroot}%{_sysusersdir}/%{name}.conf
%endif
%changelog
* Tue May 05 2026 Petr Menšík <pemensik@redhat.com> - 2.90-7
- Prevent overflow in extract_name function (CVE-2026-2291)
- Prevent DoS in DNSSEC validation (CVE-2026-4890)
- Prevent out-of-bounds read in DNSSEC validation (CVE-2026-4891)
- Prevent out-of-bounds write in DHCPv6 server (CVE-2026-4892)
- Prevent source check avoidance by RFC 7871 client-subnet (CVE-2026-4893)
- Prevent out-of-bounds read in extract_addresses (CVE-2026-5172)
* Wed Mar 18 2026 Petr Menšík <pemensik@redhat.com> - 2.90-6
- Prevent heap buffer overflow in cache via NAME_ESCAPE expansion
(CVE-2026-2291)
* Fri Dec 05 2025 Fedor Vorobev <fvorobev@redhat.com> - 2.90-5
- Added installation of tmpfiles.d config
Resolves: RHEL-122843
* Tue Oct 29 2024 Troy Dawson <tdawson@redhat.com> - 2.90-4
- Bump release for October 2024 mass rebuild:
Resolves: RHEL-64018

1
tmpfiles-dnsmasq.conf Normal file
View File

@ -0,0 +1 @@
d /var/lib/dnsmasq 0755 root dnsmasq -