import dnsmasq-2.79-18.el8

This commit is contained in:
CentOS Sources 2021-07-21 10:21:24 +00:00 committed by Andrew Lukoshko
parent be6f1fcb4e
commit 8705058ce9
5 changed files with 1439 additions and 1 deletions

View File

@ -0,0 +1,79 @@
From 4348c43be45d20aba87ee5564ecdde10aff7e5e7 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Fri, 22 Jan 2021 16:49:12 +0000
Subject: [PATCH] Move fd into frec_src, fixes
15b60ddf935a531269bb8c68198de012a4967156
If identical queries from IPv4 and IPv6 sources are combined by the
new code added in 15b60ddf935a531269bb8c68198de012a4967156 then replies
can end up being sent via the wrong family of socket. The ->fd
should be per query, not per-question.
In bind-interfaces mode, this could also result in replies being sent
via the wrong socket even when IPv4/IPV6 issues are not in play.
(cherry picked from commit 04490bf622ac84891aad6f2dd2edf83725decdee)
Fix for 12af2b171de0d678d98583e2190789e544440e02
(cherry picked from commit 3f535da79e7a42104543ef5c7b5fa2bed819a78b)
---
src/dnsmasq.h | 3 ++-
src/forward.c | 5 +++--
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index f3bbb4e..e7e1693 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -632,6 +632,7 @@ struct frec {
union mysockaddr source;
struct all_addr dest;
unsigned int iface, log_id;
+ int fd;
unsigned short orig_id;
struct frec_src *next;
} frec_src;
@@ -641,7 +642,7 @@ struct frec {
struct randfd *rfd6;
#endif
unsigned short new_id;
- int fd, forwardall, flags;
+ int forwardall, flags;
time_t time;
unsigned char *hash[HASH_SIZE];
#ifdef HAVE_DNSSEC
diff --git a/src/forward.c b/src/forward.c
index 9d249c0..82dd850 100644
--- a/src/forward.c
+++ b/src/forward.c
@@ -368,6 +368,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
new->dest = *dst_addr;
new->log_id = daemon->log_id;
new->iface = dst_iface;
+ new->fd = udpfd;
}
return 1;
@@ -392,8 +393,8 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
forward->frec_src.dest = *dst_addr;
forward->frec_src.iface = dst_iface;
forward->frec_src.next = NULL;
+ forward->frec_src.fd = udpfd;
forward->new_id = get_id();
- forward->fd = udpfd;
memcpy(forward->hash, hash, HASH_SIZE);
forward->forwardall = 0;
forward->flags = fwd_flags;
@@ -1175,7 +1176,7 @@ void reply_query(int fd, int family, time_t now)
{
header->id = htons(src->orig_id);
- send_from(forward->fd, option_bool(OPT_NOWILD) || option_bool (OPT_CLEVERBIND), daemon->packet, nn,
+ send_from(src->fd, option_bool(OPT_NOWILD) || option_bool (OPT_CLEVERBIND), daemon->packet, nn,
&src->source, &src->dest, src->iface);
if (option_bool(OPT_EXTRALOG) && src != &forward->frec_src)
--
2.26.2

View File

@ -0,0 +1,45 @@
From 595b2e2e87f152c4ade7e2d66cb78915096f60c2 Mon Sep 17 00:00:00 2001
From: Donald Sharp <donaldsharp72@gmail.com>
Date: Mon, 2 Mar 2020 11:23:36 -0500
Subject: [PATCH] Ignore routes in non-main tables
Route lookup in Linux is bounded by `ip rules` as well
as the contents of specific routing tables. With the
advent of vrf's(l3mdev's) non-default tables are regularly being
used for routing purposes.
dnsmasq listens to all route changes on the box and responds
to each one with an event. This is *expensive* when a full
BGP routing table is placed into the linux kernel, moreso
when dnsmasq is responding to events in tables that it will
never actually need to respond to, since dnsmasq at this
point in time has no concept of vrf's and would need
to be programmed to understand them. Help alleviate this load
by reducing the set of data that dnsmasq pays attention to
when we know there are events that are not useful at this
point in time.
Signed-off-by: Donald Sharp <donaldsharp72@gmail.com>
(cherry picked from commit b2ed691eb3ca6488a8878f5f3dd950a07b14a9db)
---
src/netlink.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/netlink.c b/src/netlink.c
index 8cd51af..0a3da3e 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -363,7 +363,9 @@ static void nl_async(struct nlmsghdr *h)
failing. */
struct rtmsg *rtm = NLMSG_DATA(h);
- if (rtm->rtm_type == RTN_UNICAST && rtm->rtm_scope == RT_SCOPE_LINK)
+ if (rtm->rtm_type == RTN_UNICAST && rtm->rtm_scope == RT_SCOPE_LINK &&
+ (rtm->rtm_table == RT_TABLE_MAIN ||
+ rtm->rtm_table == RT_TABLE_LOCAL))
queue_event(EVENT_NEWROUTE);
}
else if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR)
--
2.26.2

View File

@ -0,0 +1,237 @@
From 5010c42c47b7b5a3d68d83369d6c17ed0bc11cff Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Wed, 17 Feb 2021 11:47:28 +0100
Subject: [PATCH] Correct occasional --bind-dynamic synchronization break
Request only one re-read of addresses and/or routes
Previous implementation re-reads systemd addresses exactly the same
number of time equal number of notifications received.
This is not necessary, we need just notification of change, then re-read
the current state and adapt listeners. Repeated re-reading slows netlink
processing and highers CPU usage on mass interface changes.
Continue reading multicast events from netlink, even when ENOBUFS
arrive. Broadcasts are not trusted anyway and refresh would be done in
iface_enumerate. Save queued events sent again.
Remove sleeping on netlink ENOBUFS
With reduced number of written events netlink should receive ENOBUFS
rarely. It does not make sense to wait if it is received. It is just a
signal some packets got missing. Fast reading all pending packets is required,
seq checking ensures it already. Finishes changes by
commit 1d07667ac77c55b9de56b1b2c385167e0e0ec27a.
Move restart from iface_enumerate to enumerate_interfaces
When ENOBUFS is received, restart of reading addresses is done. But
previously found addresses might not have been found this time. In order
to catch this, restart both IPv4 and IPv6 enumeration with clearing
found interfaces first. It should deliver up-to-date state also after
ENOBUFS.
Read all netlink messages before netlink restart
Before writing again into netlink socket, try fetching all pending
messages. They would be ignored, only might trigger new address
synchronization. Should ensure new try has better chance to succeed.
Request sending ENOBUFS again
ENOBUFS error handling was improved. Netlink is correctly drained before
sending a new request again. It seems ENOBUFS supression is no longer
necessary or wanted. Let kernel tell us when it failed and handle it a
good way.
---
src/netlink.c | 67 ++++++++++++++++++++++++++++++++++++---------------
src/network.c | 11 +++++++--
2 files changed, 57 insertions(+), 21 deletions(-)
diff --git a/src/netlink.c b/src/netlink.c
index ac1a1c5..f95f3e8 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -32,13 +32,21 @@
#ifndef NDA_RTA
# define NDA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg))))
-#endif
+#endif
+
+/* Used to request refresh of addresses or routes just once,
+ * when multiple changes might be announced. */
+enum async_states {
+ STATE_NEWADDR = (1 << 0),
+ STATE_NEWROUTE = (1 << 1),
+};
static struct iovec iov;
static u32 netlink_pid;
-static void nl_async(struct nlmsghdr *h);
+static unsigned nl_async(struct nlmsghdr *h, unsigned state);
+static void nl_multicast_state(unsigned state);
void netlink_init(void)
{
@@ -135,7 +143,9 @@ static ssize_t netlink_recv(void)
/* family = AF_UNSPEC finds ARP table entries.
- family = AF_LOCAL finds MAC addresses. */
+ family = AF_LOCAL finds MAC addresses.
+ returns 0 on failure, 1 on success, -1 when restart is required
+*/
int iface_enumerate(int family, void *parm, int (*callback)())
{
struct sockaddr_nl addr;
@@ -143,6 +153,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
ssize_t len;
static unsigned int seq = 0;
int callback_ok = 1;
+ unsigned state = 0;
struct {
struct nlmsghdr nlh;
@@ -154,7 +165,6 @@ int iface_enumerate(int family, void *parm, int (*callback)())
addr.nl_groups = 0;
addr.nl_pid = 0; /* address to kernel */
- again:
if (family == AF_UNSPEC)
req.nlh.nlmsg_type = RTM_GETNEIGH;
else if (family == AF_LOCAL)
@@ -181,8 +191,8 @@ int iface_enumerate(int family, void *parm, int (*callback)())
{
if (errno == ENOBUFS)
{
- sleep(1);
- goto again;
+ nl_multicast_state(state);
+ return -1;
}
return 0;
}
@@ -191,7 +201,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
if (h->nlmsg_pid != netlink_pid || h->nlmsg_type == NLMSG_ERROR)
{
/* May be multicast arriving async */
- nl_async(h);
+ state = nl_async(h, state);
}
else if (h->nlmsg_seq != seq)
{
@@ -327,26 +337,36 @@ int iface_enumerate(int family, void *parm, int (*callback)())
}
}
-void netlink_multicast(void)
+static void nl_multicast_state(unsigned state)
{
ssize_t len;
struct nlmsghdr *h;
int flags;
-
- /* don't risk blocking reading netlink messages here. */
+
if ((flags = fcntl(daemon->netlinkfd, F_GETFL)) == -1 ||
fcntl(daemon->netlinkfd, F_SETFL, flags | O_NONBLOCK) == -1)
return;
+
+ do {
+ /* don't risk blocking reading netlink messages here. */
+ while ((len = netlink_recv()) != -1)
- if ((len = netlink_recv()) != -1)
- for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len))
- nl_async(h);
-
+ for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len))
+ state = nl_async(h, state);
+ } while (errno == ENOBUFS);
+
/* restore non-blocking status */
fcntl(daemon->netlinkfd, F_SETFL, flags);
}
-static void nl_async(struct nlmsghdr *h)
+void netlink_multicast(void)
+{
+ unsigned state = 0;
+ nl_multicast_state(state);
+}
+
+
+static unsigned nl_async(struct nlmsghdr *h, unsigned state)
{
if (h->nlmsg_type == NLMSG_ERROR)
{
@@ -354,7 +374,8 @@ static void nl_async(struct nlmsghdr *h)
if (err->error != 0)
my_syslog(LOG_ERR, _("netlink returns error: %s"), strerror(-(err->error)));
}
- else if (h->nlmsg_pid == 0 && h->nlmsg_type == RTM_NEWROUTE)
+ else if (h->nlmsg_pid == 0 && h->nlmsg_type == RTM_NEWROUTE &&
+ (state & STATE_NEWROUTE)==0)
{
/* We arrange to receive netlink multicast messages whenever the network route is added.
If this happens and we still have a DNS packet in the buffer, we re-send it.
@@ -366,10 +387,18 @@ static void nl_async(struct nlmsghdr *h)
if (rtm->rtm_type == RTN_UNICAST && rtm->rtm_scope == RT_SCOPE_LINK &&
(rtm->rtm_table == RT_TABLE_MAIN ||
rtm->rtm_table == RT_TABLE_LOCAL))
- queue_event(EVENT_NEWROUTE);
+ {
+ queue_event(EVENT_NEWROUTE);
+ state |= STATE_NEWROUTE;
+ }
+ }
+ else if ((h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR) &&
+ (state & STATE_NEWADDR)==0)
+ {
+ queue_event(EVENT_NEWADDR);
+ state |= STATE_NEWADDR;
}
- else if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR)
- queue_event(EVENT_NEWADDR);
+ return state;
}
#endif
diff --git a/src/network.c b/src/network.c
index c6e7d89..47caf38 100644
--- a/src/network.c
+++ b/src/network.c
@@ -656,7 +656,8 @@ int enumerate_interfaces(int reset)
if ((param.fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
return 0;
-
+
+again:
/* Mark interfaces for garbage collection */
for (iface = daemon->interfaces; iface; iface = iface->next)
iface->found = 0;
@@ -709,10 +710,16 @@ int enumerate_interfaces(int reset)
#ifdef HAVE_IPV6
ret = iface_enumerate(AF_INET6, &param, iface_allowed_v6);
+ if (ret < 0)
+ goto again;
#endif
if (ret)
- ret = iface_enumerate(AF_INET, &param, iface_allowed_v4);
+ {
+ ret = iface_enumerate(AF_INET, &param, iface_allowed_v4);
+ if (ret < 0)
+ goto again;
+ }
errsave = errno;
close(param.fd);
--
2.26.2

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,7 @@
Name: dnsmasq
Version: 2.79
Release: 15%{?extraversion:.%{extraversion}}%{?dist}
Release: 18%{?extraversion:.%{extraversion}}%{?dist}
Summary: A lightweight DHCP/caching DNS server
License: GPLv2 or GPLv3
@ -57,6 +57,14 @@ Patch23: dnsmasq-2.79-CVE-2020-25684.patch
Patch24: dnsmasq-2.79-CVE-2020-25685.patch
Patch25: dnsmasq-2.79-CVE-2020-25686.patch
Patch26: dnsmasq-2.79-CVE-2020-25686-2.patch
# http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=3f535da79e7a42104543ef5c7b5fa2bed819a78b
# http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=04490bf622ac84891aad6f2dd2edf83725decdee
Patch27: dnsmasq-2.79-mixed-family-failed.patch
# http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=b2ed691eb3ca6488a8878f5f3dd950a07b14a9db
Patch28: dnsmasq-2.81-netlink-table.patch
Patch29: dnsmasq-2.84-bind-dynamic-netlink.patch
# http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=74d4fcd756a85bc1823232ea74334f7ccfb9d5d2
Patch30: dnsmasq-2.85-CVE-2021-3448.patch
# This is workaround to nettle bug #1549190
# https://bugzilla.redhat.com/show_bug.cgi?id=1549190
@ -116,6 +124,10 @@ server's leases.
%patch24 -p1 -b .CVE-2020-25685
%patch25 -p1 -b .CVE-2020-25686
%patch26 -p1 -b .CVE-2020-25686-2
%patch27 -p1 -b .rh1921153
%patch28 -p1 -b .rh1887649-table
%patch29 -p1 -b .rh1887649
%patch30 -p1 -b .CVE-2021-3448
# use /var/lib/dnsmasq instead of /var/lib/misc
for file in dnsmasq.conf.example man/dnsmasq.8 man/es/dnsmasq.8 src/config.h; do
@ -215,6 +227,15 @@ install -Dpm 644 %{SOURCE2} %{buildroot}%{_sysusersdir}/dnsmasq.conf
%{_mandir}/man1/dhcp_*
%changelog
* Thu Mar 18 2021 Petr Menšík <pemensik@redhat.com> - 2.79-18
- Properly randomize outgoing ports also with bound interface (CVE-2021-3448)
* Fri Feb 12 2021 Petr Menšík <pemensik@redhat.com> - 2.79-17
- Fix sporadic bind-dynamic failures (#1887649)
* Wed Jan 27 2021 Petr Menšík <pemensik@redhat.com> - 2.79-16
- Fix network errors on queries both from ipv4 and ipv6 (#1921153)
* Wed Nov 25 2020 Petr Menšík <pemensik@redhat.com> - 2.79-15
- Fix various issues in dnssec validation (CVE-2020-25681)
- Accept responses only on correct sockets (CVE-2020-25684)