[selinux-policy: 2686/3172] dnsmasq patch from Dan Walsh - cron_manage_pid_files call removed until further explanation
by Daniel J Walsh
commit 37194ac0559b5e59ae3d32b947bac2afee79bc83
Author: Jeremy Solt <jsolt(a)tresys.com>
Date: Fri May 21 17:02:24 2010 -0400
dnsmasq patch from Dan Walsh
- cron_manage_pid_files call removed until further explanation
policy/modules/services/dnsmasq.fc | 2 ++
policy/modules/services/dnsmasq.if | 6 +++---
policy/modules/services/dnsmasq.te | 18 ++++++++++++++++--
3 files changed, 21 insertions(+), 5 deletions(-)
---
diff --git a/policy/modules/services/dnsmasq.fc b/policy/modules/services/dnsmasq.fc
index 21089ca..b886676 100644
--- a/policy/modules/services/dnsmasq.fc
+++ b/policy/modules/services/dnsmasq.fc
@@ -6,5 +6,7 @@
/var/lib/misc/dnsmasq\.leases -- gen_context(system_u:object_r:dnsmasq_lease_t,s0)
/var/lib/dnsmasq(/.*)? gen_context(system_u:object_r:dnsmasq_lease_t,s0)
+/var/log/dnsmasq\.log gen_context(system_u:object_r:dnsmasq_var_log_t,s0)
+
/var/run/dnsmasq\.pid -- gen_context(system_u:object_r:dnsmasq_var_run_t,s0)
/var/run/libvirt/network(/.*)? gen_context(system_u:object_r:dnsmasq_var_run_t,s0)
diff --git a/policy/modules/services/dnsmasq.if b/policy/modules/services/dnsmasq.if
index 5681e65..a5c426b 100644
--- a/policy/modules/services/dnsmasq.if
+++ b/policy/modules/services/dnsmasq.if
@@ -111,7 +111,7 @@ interface(`dnsmasq_read_config',`
type dnsmasq_etc_t;
')
- allow $1 dnsmasq_etc_t:file read_file_perms;
+ read_files_pattern($1, dnsmasq_etc_t, dnsmasq_etc_t)
files_search_etc($1)
')
@@ -130,7 +130,7 @@ interface(`dnsmasq_write_config',`
type dnsmasq_etc_t;
')
- allow $1 dnsmasq_etc_t:file write_file_perms;
+ write_files_pattern($1, dnsmasq_etc_t, dnsmasq_etc_t)
files_search_etc($1)
')
@@ -174,7 +174,7 @@ interface(`dnsmasq_read_pid_files',`
########################################
## <summary>
-## All of the rules required to administrate
+## All of the rules required to administrate
## an dnsmasq environment
## </summary>
## <param name="domain">
diff --git a/policy/modules/services/dnsmasq.te b/policy/modules/services/dnsmasq.te
index 2865f04..c8fb14d 100644
--- a/policy/modules/services/dnsmasq.te
+++ b/policy/modules/services/dnsmasq.te
@@ -19,6 +19,9 @@ files_config_file(dnsmasq_etc_t)
type dnsmasq_lease_t;
files_type(dnsmasq_lease_t)
+type dnsmasq_var_log_t;
+logging_log_file(dnsmasq_var_log_t)
+
type dnsmasq_var_run_t;
files_pid_file(dnsmasq_var_run_t)
@@ -27,7 +30,7 @@ files_pid_file(dnsmasq_var_run_t)
# Local policy
#
-allow dnsmasq_t self:capability { net_admin setgid setuid net_bind_service net_raw };
+allow dnsmasq_t self:capability { chown dac_override net_admin setgid setuid net_bind_service net_raw };
dontaudit dnsmasq_t self:capability sys_tty_config;
allow dnsmasq_t self:process { getcap setcap signal_perms };
allow dnsmasq_t self:fifo_file rw_fifo_file_perms;
@@ -37,12 +40,15 @@ allow dnsmasq_t self:udp_socket create_socket_perms;
allow dnsmasq_t self:packet_socket create_socket_perms;
allow dnsmasq_t self:rawip_socket create_socket_perms;
-allow dnsmasq_t dnsmasq_etc_t:file read_file_perms;
+read_files_pattern(dnsmasq_t, dnsmasq_etc_t, dnsmasq_etc_t)
# dhcp leases
manage_files_pattern(dnsmasq_t, dnsmasq_lease_t, dnsmasq_lease_t)
files_var_lib_filetrans(dnsmasq_t, dnsmasq_lease_t, file)
+manage_files_pattern(dnsmasq_t, dnsmasq_var_log_t, dnsmasq_var_log_t)
+logging_log_filetrans(dnsmasq_t, dnsmasq_var_log_t, file)
+
manage_files_pattern(dnsmasq_t, dnsmasq_var_run_t, dnsmasq_var_run_t)
files_pid_filetrans(dnsmasq_t, dnsmasq_var_run_t, file)
@@ -87,6 +93,14 @@ userdom_dontaudit_use_unpriv_user_fds(dnsmasq_t)
userdom_dontaudit_search_user_home_dirs(dnsmasq_t)
optional_policy(`
+ cobbler_read_lib_files(dnsmasq_t)
+')
+
+optional_policy(`
+ dbus_system_bus_client(dnsmasq_t)
+')
+
+optional_policy(`
seutil_sigchld_newrole(dnsmasq_t)
')
13 years, 8 months
[dnsmasq/f18] dhcp6 support fixes (#867054)
by Tomas Hozza
commit d474b81de672a7f630929bc45172ccc5538debf7
Author: Tomas Hozza <thozza(a)redhat.com>
Date: Mon Nov 19 10:43:01 2012 +0100
dhcp6 support fixes (#867054)
dnsmasq-2.63-dhcp6-access-control.patch | 91 +++++++++++++++++++++++++++++++
dnsmasq-2.63-ip6-reuseaddr.patch | 36 ++++++++++++
dnsmasq.spec | 12 ++++-
3 files changed, 138 insertions(+), 1 deletions(-)
---
diff --git a/dnsmasq-2.63-dhcp6-access-control.patch b/dnsmasq-2.63-dhcp6-access-control.patch
new file mode 100644
index 0000000..87e900d
--- /dev/null
+++ b/dnsmasq-2.63-dhcp6-access-control.patch
@@ -0,0 +1,91 @@
+diff --git a/src/dhcp6.c b/src/dhcp6.c
+index 718a262..5525ca5 100644
+--- a/src/dhcp6.c
++++ b/src/dhcp6.c
+@@ -21,7 +21,7 @@
+ struct iface_param {
+ struct dhcp_context *current;
+ struct in6_addr fallback;
+- int ind;
++ int ind, addr_match;
+ };
+
+ static int complete_context6(struct in6_addr *local, int prefix,
+@@ -87,7 +87,6 @@ void dhcp6_packet(time_t now)
+ char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
+ } control_u;
+ struct sockaddr_in6 from;
+- struct all_addr dest;
+ ssize_t sz;
+ struct ifreq ifr;
+ struct iname *tmp;
+@@ -114,15 +113,15 @@ void dhcp6_packet(time_t now)
+ p.c = CMSG_DATA(cmptr);
+
+ if_index = p.p->ipi6_ifindex;
+- dest.addr.addr6 = p.p->ipi6_addr;
+ }
+
+ if (!indextoname(daemon->dhcp6fd, if_index, ifr.ifr_name))
+ return;
+
+- if (!iface_check(AF_INET6, (struct all_addr *)&dest, ifr.ifr_name))
+- return;
+-
++ for (tmp = daemon->if_except; tmp; tmp = tmp->next)
++ if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
++ return;
++
+ for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
+ if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
+ return;
+@@ -136,11 +135,23 @@ void dhcp6_packet(time_t now)
+
+ parm.current = NULL;
+ parm.ind = if_index;
++ parm.addr_match = 0;
+ memset(&parm.fallback, 0, IN6ADDRSZ);
+
+ if (!iface_enumerate(AF_INET6, &parm, complete_context6))
+ return;
+
++ if (daemon->if_names || daemon->if_addrs)
++ {
++
++ for (tmp = daemon->if_names; tmp; tmp = tmp->next)
++ if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
++ break;
++
++ if (!tmp && !parm.addr_match)
++ return;
++ }
++
+ lease_prune(NULL, now); /* lose any expired leases */
+
+ port = dhcp6_reply(parm.current, if_index, ifr.ifr_name, &parm.fallback,
+@@ -167,15 +178,23 @@ static int complete_context6(struct in6_addr *local, int prefix,
+ {
+ struct dhcp_context *context;
+ struct iface_param *param = vparam;
+-
++ struct iname *tmp;
++
+ (void)scope; /* warning */
+ (void)dad;
+-
++
+ if (if_index == param->ind &&
+ !IN6_IS_ADDR_LOOPBACK(local) &&
+ !IN6_IS_ADDR_LINKLOCAL(local) &&
+ !IN6_IS_ADDR_MULTICAST(local))
+ {
++ /* if we have --listen-address config, see if the
++ arrival interface has a matching address. */
++ for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
++ if (tmp->addr.sa.sa_family == AF_INET6 &&
++ IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, local))
++ param->addr_match = 1;
++
+ /* Determine a globally address on the arrival interface, even
+ if we have no matching dhcp-context, because we're only
+ allocating on remote subnets via relays. This
diff --git a/dnsmasq-2.63-ip6-reuseaddr.patch b/dnsmasq-2.63-ip6-reuseaddr.patch
new file mode 100644
index 0000000..af2f043
--- /dev/null
+++ b/dnsmasq-2.63-ip6-reuseaddr.patch
@@ -0,0 +1,36 @@
+diff -urp dnsmasq-2.63-orig/src/dhcp6.c dnsmasq-2.63/src/dhcp6.c
+--- dnsmasq-2.63-orig/src/dhcp6.c 2012-08-16 09:04:05.000000000 -0400
++++ dnsmasq-2.63/src/dhcp6.c 2012-11-03 07:55:39.293006824 -0400
+@@ -36,15 +36,31 @@ void dhcp6_init(void)
+ #if defined(IPV6_TCLASS) && defined(IPTOS_CLASS_CS6)
+ int class = IPTOS_CLASS_CS6;
+ #endif
+-
++ int oneopt = 1;
++
+ if ((fd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP)) == -1 ||
+ #if defined(IPV6_TCLASS) && defined(IPTOS_CLASS_CS6)
+ setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &class, sizeof(class)) == -1 ||
+ #endif
++ setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &oneopt, sizeof(oneopt)) == -1 ||
+ !fix_fd(fd) ||
+ !set_ipv6pktinfo(fd))
+ die (_("cannot create DHCPv6 socket: %s"), NULL, EC_BADNET);
+
++ /* When bind-interfaces is set, there might be more than one dnmsasq
++ instance binding port 547. That's OK if they serve different networks.
++ Need to set REUSEADDR to make this posible, or REUSEPORT on *BSD. */
++ if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND))
++ {
++#ifdef SO_REUSEPORT
++ int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &oneopt, sizeof(oneopt));
++#else
++ int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &oneopt, sizeof(oneopt));
++#endif
++ if (rc == -1)
++ die(_("failed to set SO_REUSE{ADDR|PORT} on DHCPv6 socket: %s"), NULL, EC_BADNET);
++ }
++
+ memset(&saddr, 0, sizeof(saddr));
+ #ifdef HAVE_SOCKADDR_SA_LEN
+ saddr.sin6_len = sizeof(struct sockaddr_in6);
diff --git a/dnsmasq.spec b/dnsmasq.spec
index c706791..9880eea 100644
--- a/dnsmasq.spec
+++ b/dnsmasq.spec
@@ -11,7 +11,7 @@
Name: dnsmasq
Version: 2.63
-Release: 2%{?extraversion}%{?dist}
+Release: 3%{?extraversion}%{?dist}
Summary: A lightweight DHCP/caching DNS server
Group: System Environment/Daemons
@@ -19,6 +19,10 @@ License: GPLv2
URL: http://www.thekelleys.org.uk/dnsmasq/
Source0: http://www.thekelleys.org.uk/dnsmasq/%{?extrapath}%{name}-%{version}%{?ex...
Source1: %{name}.service
+
+Patch0: dnsmasq-2.63-ip6-reuseaddr.patch
+Patch1: dnsmasq-2.63-dhcp6-access-control.patch
+
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: dbus-devel
@@ -52,6 +56,9 @@ query/remove a DHCP server's leases.
%prep
%setup -q -n %{name}-%{version}%{?extraversion}
+%patch0 -p1 -b .ip6_reuseaddr
+%patch1 -p1 -b .dhcp6_access_ctrl
+
# 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
sed -i 's|/var/lib/misc/dnsmasq.leases|/var/lib/dnsmasq/dnsmasq.leases|g' "$file"
@@ -130,6 +137,9 @@ rm -rf $RPM_BUILD_ROOT
%{_mandir}/man1/dhcp_*
%changelog
+* Mon Nov 19 2012 Tomas Hozza <thozza(a)redhat.com> - 2.63-3
+- dhcp6 support fixes (#867054)
+
* Tue Oct 23 2012 Tomas Hozza <thozza(a)redhat.com> - 2.63-2
- Introduce new systemd-rpm macros in dnsmasq spec file (#850096)
11 years, 7 months
pemensik pushed to dnsmasq (rawhide). "Add coverity patches (..more)"
by notifications@fedoraproject.org
Notification time stamped 2021-09-09 08:04:29 UTC
From 06b5c95b058e4985a844a72bfc98ab0dd157a364 Mon Sep 17 00:00:00 2001
From: Petr Menšík <pemensik(a)redhat.com>
Date: Sep 09 2021 07:55:19 +0000
Subject: Add coverity patches
Various coverity fixes, not yet sent to upstream.
---
diff --git a/0001-Retry-on-interrupted-error-in-tftp.patch b/0001-Retry-on-interrupted-error-in-tftp.patch
new file mode 100644
index 0000000..f486f2d
--- /dev/null
+++ b/0001-Retry-on-interrupted-error-in-tftp.patch
@@ -0,0 +1,35 @@
+From f5f56c001dddd486859dc6301e6cbe00ba604fe8 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Wed, 18 Aug 2021 10:09:35 +0200
+Subject: [PATCH 01/15] Retry on interrupted error in tftp
+
+Interrupt might arrive when sending error reply. Retry if possible.
+
+Wrong Check of Return Value
+
+10. dnsmasq-2.85/src/tftp.c:603: check_return: Calling "sendto(transfer->sockfd, dnsmasq_daemon->packet, len, 0, __CONST_SOCKADDR_ARG({.__sockaddr__ = &peer.sa}), sa_len(&peer))" without checking return value. This library function may fail and return an error code.
+ # 601| prettyprint_addr(&peer, daemon->addrbuff);
+ # 602| len = tftp_err(ERR_TID, daemon->packet, _("ignoring packet from %s (TID mismatch)"), daemon->addrbuff);
+ # 603|-> sendto(transfer->sockfd, daemon->packet, len, 0, &peer.sa, sa_len(&peer));
+ # 604| }
+ # 605| }
+---
+ src/tftp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/tftp.c b/src/tftp.c
+index 37bdff2..3d87523 100644
+--- a/src/tftp.c
++++ b/src/tftp.c
+@@ -600,7 +600,7 @@ void check_tftp_listeners(time_t now)
+ /* Wrong source address. See rfc1350 para 4. */
+ prettyprint_addr(&peer, daemon->addrbuff);
+ len = tftp_err(ERR_TID, daemon->packet, _("ignoring packet from %s (TID mismatch)"), daemon->addrbuff);
+- sendto(transfer->sockfd, daemon->packet, len, 0, &peer.sa, sa_len(&peer));
++ while(retry_send(sendto(transfer->sockfd, daemon->packet, len, 0, &peer.sa, sa_len(&peer))));
+ }
+ }
+ }
+--
+2.31.1
+
diff --git a/0002-Add-safety-checks-to-places-pointed-by-Coverity.patch b/0002-Add-safety-checks-to-places-pointed-by-Coverity.patch
new file mode 100644
index 0000000..8fc70a5
--- /dev/null
+++ b/0002-Add-safety-checks-to-places-pointed-by-Coverity.patch
@@ -0,0 +1,77 @@
+From 061013293ceddce509ae06a31a045e803103f1ce Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Wed, 18 Aug 2021 14:59:23 +0200
+Subject: [PATCH 02/15] Add safety checks to places pointed by Coverity
+
+GCC Analyzer (experimental)
+
+1. dnsmasq-2.85/src/forward.c:0: scope_hint: In function 'allocate_rfd.part.0'
+2. dnsmasq-2.85/src/forward.c:2321:18: warning[-Wanalyzer-null-dereference]: dereference of NULL 'rfd'
+ # 2319| *fdlp = rfl;
+ # 2320|
+ # 2321|-> return rfl->rfd->fd;
+ # 2322| }
+ # 2323|
+
+1. dnsmasq-2.85/src/cache.c:0: scope_hint: In function 'log_query'
+2. dnsmasq-2.85/src/cache.c:1969:20: warning[-Wanalyzer-null-dereference]: dereference of NULL 'name'
+ # 1967| source = "cached";
+ # 1968|
+ # 1969|-> if (strlen(name) == 0)
+ # 1970| name = ".";
+ # 1971|
+
+1. dnsmasq-2.85/src/cache.c:0: scope_hint: In function 'cache_scan_free'
+2. dnsmasq-2.85/src/cache.c:436:20: warning[-Wanalyzer-null-argument]: use of NULL 'addr' where non-null expected
+40. /usr/include/sys/un.h:37: included_from: Included from here.
+41. dnsmasq-2.85/src/dnsmasq.h:101: included_from: Included from here.
+42. dnsmasq-2.85/src/cache.c:17: included_from: Included from here.
+43. /usr/include/string.h:64:12: note: argument 2 of 'memcmp' must be non-null
+ # 434| (flags & crecp->flags & F_REVERSE) &&
+ # 435| (flags & crecp->flags & (F_IPV4 | F_IPV6)) &&
+ # 436|-> memcmp(&crecp->addr, addr, addrlen) == 0)
+ # 437| {
+ # 438| *up = crecp->hash_next;
+---
+ src/cache.c | 4 ++--
+ src/forward.c | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/src/cache.c b/src/cache.c
+index 8add610..97c51a7 100644
+--- a/src/cache.c
++++ b/src/cache.c
+@@ -433,7 +433,7 @@ static struct crec *cache_scan_free(char *name, union all_addr *addr, unsigned s
+ else if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) &&
+ (flags & crecp->flags & F_REVERSE) &&
+ (flags & crecp->flags & (F_IPV4 | F_IPV6)) &&
+- memcmp(&crecp->addr, addr, addrlen) == 0)
++ addr && memcmp(&crecp->addr, addr, addrlen) == 0)
+ {
+ *up = crecp->hash_next;
+ cache_unlink(crecp);
+@@ -2013,7 +2013,7 @@ void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg)
+ else
+ source = "cached";
+
+- if (strlen(name) == 0)
++ if (name && !name[0])
+ name = ".";
+
+ if (option_bool(OPT_EXTRALOG))
+diff --git a/src/forward.c b/src/forward.c
+index 3d638e4..f07c908 100644
+--- a/src/forward.c
++++ b/src/forward.c
+@@ -2276,7 +2276,7 @@ int allocate_rfd(struct randfd_list **fdlp, struct server *serv)
+ }
+ }
+
+- if (j == daemon->numrrand)
++ if (!rfd) /* should be when j == daemon->numrrand */
+ {
+ struct randfd_list *rfl_poll;
+
+--
+2.31.1
+
diff --git a/0003-Small-safeguard-to-unexpected-data.patch b/0003-Small-safeguard-to-unexpected-data.patch
new file mode 100644
index 0000000..c496640
--- /dev/null
+++ b/0003-Small-safeguard-to-unexpected-data.patch
@@ -0,0 +1,28 @@
+From 920cd815bafea084f68cc4309399aea77bd7f66b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 14:11:42 +0200
+Subject: [PATCH 03/15] Small safeguard to unexpected data
+
+Make sure negative index is not used for comparison. It seems code in
+option parsing does not allow it to be empty, but insist on it also in
+this place.
+---
+ src/dhcp-common.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/dhcp-common.c b/src/dhcp-common.c
+index 73568a9..85b269a 100644
+--- a/src/dhcp-common.c
++++ b/src/dhcp-common.c
+@@ -88,7 +88,7 @@ int match_netid_wild(struct dhcp_netid *check, struct dhcp_netid *pool)
+ for (; check; check = check->next)
+ {
+ const int check_len = strlen(check->net);
+- const int is_wc = (check->net[check_len - 1] == '*');
++ const int is_wc = (check_len > 0 && check->net[check_len - 1] == '*');
+
+ /* '#' for not is for backwards compat. */
+ if (check->net[0] != '!' && check->net[0] != '#')
+--
+2.31.1
+
diff --git a/0004-Fix-bunch-of-warnings-in-auth.c.patch b/0004-Fix-bunch-of-warnings-in-auth.c.patch
new file mode 100644
index 0000000..976255f
--- /dev/null
+++ b/0004-Fix-bunch-of-warnings-in-auth.c.patch
@@ -0,0 +1,153 @@
+From e61af561900b4d2dd976a575b2efd388be092742 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 16:00:35 +0200
+Subject: [PATCH 04/15] Fix bunch of warnings in auth.c
+
+Error: CLANG_WARNING: [#def7]
+dnsmasq-2.86test7/src/auth.c:420:5: warning[deadcode.DeadStores]: Value stored to 'found' is never read
+ # 418| if (!found && is_name_synthetic(flag, name, &addr) )
+ # 419| {
+ # 420|-> found = 1;
+ # 421| nxdomain = 0;
+ # 422|
+
+Error: CLANG_WARNING: [#def8]
+dnsmasq-2.86test7/src/auth.c:436:8: warning[deadcode.DeadStores]: Value stored to 'found' is never read
+ # 434| {
+ # 435| auth = soa = 1; /* inhibits auth section */
+ # 436|-> found = 1;
+ # 437| log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<SOA>");
+ # 438| }
+
+Error: CLANG_WARNING: [#def9]
+dnsmasq-2.86test7/src/auth.c:472:8: warning[deadcode.DeadStores]: Value stored to 'found' is never read
+ # 470| ns = 1; /* ensure we include NS records! */
+ # 471| axfr = 1;
+ # 472|-> found = 1;
+ # 473| axfroffset = nameoffset;
+ # 474| log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<AXFR>");
+
+Error: CLANG_WARNING: [#def10]
+dnsmasq-2.86test7/src/auth.c:480:8: warning[deadcode.DeadStores]: Value stored to 'found' is never read
+ # 478| auth = 1;
+ # 479| ns = 1; /* inhibits auth section */
+ # 480|-> found = 1;
+ # 481| log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<NS>");
+ # 482| }
+
+Error: CLANG_WARNING: [#def11]
+dnsmasq-2.86test7/src/auth.c:501:4: warning[deadcode.DeadStores]: Value stored to 'found' is never read
+ # 499| log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid));
+ # 500| *cut = 0; /* remove domain part */
+ # 501|-> found = 1;
+ # 502| if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+ # 503| daemon->auth_ttl, NULL, qtype, C_IN,
+
+Error: CLANG_WARNING: [#def12]
+dnsmasq-2.86test7/src/auth.c:522:8: warning[deadcode.DeadStores]: Value stored to 'found' is never read
+ # 520| {
+ # 521| log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid));
+ # 522|-> found = 1;
+ # 523| if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+ # 524| daemon->auth_ttl, NULL, qtype, C_IN,
+
+Error: CLANG_WARNING: [#def13]
+dnsmasq-2.86test7/src/auth.c:617:8: warning[deadcode.DeadStores]: Value stored to 'p' is never read
+ # 615| p += sprintf(p, "%u.", a & 0xff);
+ # 616| a = a >> 8;
+ # 617|-> p += sprintf(p, "%u.in-addr.arpa", a & 0xff);
+ # 618|
+ # 619| }
+
+Error: CPPCHECK_WARNING (CWE-758): [#def14]
+dnsmasq-2.86test7/src/auth.c:627: warning[objectIndex]: The address of local variable 'addr6' might be accessed at non-zero index.
+ # 625| for (i = subnet->prefixlen-1; i >= 0; i -= 4)
+ # 626| {
+ # 627|-> int dig = ((unsigned char *)&subnet->addr.addr6)[i>>3];
+ # 628| p += sprintf(p, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
+ # 629| }
+
+Error: CLANG_WARNING: [#def15]
+dnsmasq-2.86test7/src/auth.c:630:8: warning[deadcode.DeadStores]: Value stored to 'p' is never read
+ # 628| p += sprintf(p, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
+ # 629| }
+ # 630|-> p += sprintf(p, "ip6.arpa");
+ # 631|
+ # 632| }
+---
+ src/auth.c | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+diff --git a/src/auth.c b/src/auth.c
+index 172a4b2..4f03c39 100644
+--- a/src/auth.c
++++ b/src/auth.c
+@@ -417,7 +417,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+
+ if (!found && is_name_synthetic(flag, name, &addr) )
+ {
+- found = 1;
+ nxdomain = 0;
+
+ log_query(F_FORWARD | F_CONFIG | flag, name, &addr, NULL);
+@@ -433,7 +432,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ if (qtype == T_SOA)
+ {
+ auth = soa = 1; /* inhibits auth section */
+- found = 1;
+ log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<SOA>");
+ }
+ else if (qtype == T_AXFR)
+@@ -469,7 +467,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ soa = 1; /* inhibits auth section */
+ ns = 1; /* ensure we include NS records! */
+ axfr = 1;
+- found = 1;
+ axfroffset = nameoffset;
+ log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<AXFR>");
+ }
+@@ -477,7 +474,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ {
+ auth = 1;
+ ns = 1; /* inhibits auth section */
+- found = 1;
+ log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<NS>");
+ }
+ }
+@@ -498,7 +494,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ *cut = '.'; /* restore domain part */
+ log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid));
+ *cut = 0; /* remove domain part */
+- found = 1;
+ if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+ daemon->auth_ttl, NULL, qtype, C_IN,
+ qtype == T_A ? "4" : "6", &crecp->addr))
+@@ -519,7 +514,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ if ((crecp->flags & flag) && (local_query || filter_zone(zone, flag, &(crecp->addr))))
+ {
+ log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid));
+- found = 1;
+ if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+ daemon->auth_ttl, NULL, qtype, C_IN,
+ qtype == T_A ? "4" : "6", &crecp->addr))
+@@ -614,7 +608,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ if (subnet->prefixlen >= 16 )
+ p += sprintf(p, "%u.", a & 0xff);
+ a = a >> 8;
+- p += sprintf(p, "%u.in-addr.arpa", a & 0xff);
++ sprintf(p, "%u.in-addr.arpa", a & 0xff);
+
+ }
+ else
+@@ -627,7 +621,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ int dig = ((unsigned char *)&subnet->addr.addr6)[i>>3];
+ p += sprintf(p, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
+ }
+- p += sprintf(p, "ip6.arpa");
++ sprintf(p, "ip6.arpa");
+
+ }
+ }
+--
+2.31.1
+
diff --git a/0005-Fix-few-coverity-warnings-in-lease-tools.patch b/0005-Fix-few-coverity-warnings-in-lease-tools.patch
new file mode 100644
index 0000000..ab24440
--- /dev/null
+++ b/0005-Fix-few-coverity-warnings-in-lease-tools.patch
@@ -0,0 +1,148 @@
+From be7f213066282baeed46cc34223601c462db9cbf Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 16:32:05 +0200
+Subject: [PATCH 05/15] Fix few coverity warnings in lease-tools
+
+Error: UNINIT (CWE-457): [#def2]
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release.c:265: var_decl: Declaring variable "ifr" without initializer.
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release.c:285: uninit_use_in_call: Using uninitialized value "ifr". Field "ifr.ifr_ifru" is uninitialized when calling "setsockopt".
+ # 283| strncpy(ifr.ifr_name, argv[1], sizeof(ifr.ifr_name)-1);
+ # 284| ifr.ifr_name[sizeof(ifr.ifr_name)-1] = '\0';
+ # 285|-> if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) == -1)
+ # 286| {
+ # 287| perror("cannot setup interface");
+
+Error: CHECKED_RETURN (CWE-252): [#def3]
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:346: check_return: Calling "inet_pton" without checking return value (as is done elsewhere 61 out of 72 times).
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:188: example_assign: Example 1: Assigning: "s" = return value from "inet_pton(10, ip, &result.ip)".
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:189: example_checked: Example 1 (cont.): "s" has its value checked in "s <= 0".
+dnsmasq-2.86test7/src/cache.c:1108: example_checked: Example 2: "inet_pton(10, token, &addr)" has its value checked in "inet_pton(10, token, &addr) > 0".
+dnsmasq-2.86test7/src/dbus.c:525: example_checked: Example 3: "inet_pton(2, ipaddr, &addr.addr4)" has its value checked in "inet_pton(2, ipaddr, &addr.addr4)".
+dnsmasq-2.86test7/src/domain.c:138: example_checked: Example 4: "inet_pton(prot, tail, addr)" has its value checked in "inet_pton(prot, tail, addr)".
+dnsmasq-2.86test7/src/lease.c:81: example_checked: Example 5: "inet_pton(10, dnsmasq_daemon->namebuff, &addr.addr6)" has its value checked in "inet_pton(10, dnsmasq_daemon->namebuff, &addr.addr6)".
+ # 344| client_addr.sin6_flowinfo = 0;
+ # 345| client_addr.sin6_scope_id =0;
+ # 346|-> inet_pton(AF_INET6, "::", &client_addr.sin6_addr);
+ # 347| bind(sock, (struct sockaddr*)&client_addr, sizeof(struct sockaddr_in6));
+ # 348| inet_pton(AF_INET6, DHCP6_MULTICAST_ADDRESS, &server_addr.sin6_addr);
+
+Error: CHECKED_RETURN (CWE-252): [#def4]
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:347: check_return: Calling "bind(sock, (struct sockaddr *)&client_addr, 28U)" without checking return value. This library function may fail and return an error code.
+ # 345| client_addr.sin6_scope_id =0;
+ # 346| inet_pton(AF_INET6, "::", &client_addr.sin6_addr);
+ # 347|-> bind(sock, (struct sockaddr*)&client_addr, sizeof(struct sockaddr_in6));
+ # 348| inet_pton(AF_INET6, DHCP6_MULTICAST_ADDRESS, &server_addr.sin6_addr);
+ # 349| server_addr.sin6_port = htons(DHCP6_SERVER_PORT);
+
+Error: CHECKED_RETURN (CWE-252): [#def5]
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:348: check_return: Calling "inet_pton" without checking return value (as is done elsewhere 61 out of 72 times).
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:188: example_assign: Example 1: Assigning: "s" = return value from "inet_pton(10, ip, &result.ip)".
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:189: example_checked: Example 1 (cont.): "s" has its value checked in "s <= 0".
+dnsmasq-2.86test7/src/cache.c:1108: example_checked: Example 2: "inet_pton(10, token, &addr)" has its value checked in "inet_pton(10, token, &addr) > 0".
+dnsmasq-2.86test7/src/dbus.c:525: example_checked: Example 3: "inet_pton(2, ipaddr, &addr.addr4)" has its value checked in "inet_pton(2, ipaddr, &addr.addr4)".
+dnsmasq-2.86test7/src/domain.c:138: example_checked: Example 4: "inet_pton(prot, tail, addr)" has its value checked in "inet_pton(prot, tail, addr)".
+dnsmasq-2.86test7/src/lease.c:81: example_checked: Example 5: "inet_pton(10, dnsmasq_daemon->namebuff, &addr.addr6)" has its value checked in "inet_pton(10, dnsmasq_daemon->namebuff, &addr.addr6)".
+ # 346| inet_pton(AF_INET6, "::", &client_addr.sin6_addr);
+ # 347| bind(sock, (struct sockaddr*)&client_addr, sizeof(struct sockaddr_in6));
+ # 348|-> inet_pton(AF_INET6, DHCP6_MULTICAST_ADDRESS, &server_addr.sin6_addr);
+ # 349| server_addr.sin6_port = htons(DHCP6_SERVER_PORT);
+ # 350| int16_t recv_size = 0;
+
+Error: NEGATIVE_RETURNS (CWE-394): [#def6]
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:360: var_tested_neg: Variable "recv_size" tests negative.
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:373: negative_returns: "recv_size" is passed to a parameter that cannot be negative.
+ # 371| }
+ # 372|
+ # 373|-> int16_t result = parse_packet(response, recv_size);
+ # 374| if (result == NOT_REPLY_CODE)
+ # 375| {
+---
+ contrib/lease-tools/dhcp_release.c | 1 +
+ contrib/lease-tools/dhcp_release6.c | 37 ++++++++++++++++++-----------
+ 2 files changed, 24 insertions(+), 14 deletions(-)
+
+diff --git a/contrib/lease-tools/dhcp_release.c b/contrib/lease-tools/dhcp_release.c
+index c1c835b..84f5610 100644
+--- a/contrib/lease-tools/dhcp_release.c
++++ b/contrib/lease-tools/dhcp_release.c
+@@ -280,6 +280,7 @@ int main(int argc, char **argv)
+
+ /* This voodoo fakes up a packet coming from the correct interface, which really matters for
+ a DHCP server */
++ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, argv[1], sizeof(ifr.ifr_name)-1);
+ ifr.ifr_name[sizeof(ifr.ifr_name)-1] = '\0';
+ if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) == -1)
+diff --git a/contrib/lease-tools/dhcp_release6.c b/contrib/lease-tools/dhcp_release6.c
+index d680222..9b3438f 100644
+--- a/contrib/lease-tools/dhcp_release6.c
++++ b/contrib/lease-tools/dhcp_release6.c
+@@ -318,6 +318,12 @@ void usage(const char* arg, FILE* stream)
+ fprintf (stream, "Usage: %s %s\n", arg, usage_string);
+ }
+
++static void fail_fatal(const char *errstr, int exitcode)
++{
++ perror(errstr);
++ exit(exitcode);
++}
++
+ int send_release_packet(const char* iface, struct dhcp6_packet* packet)
+ {
+ struct sockaddr_in6 server_addr, client_addr;
+@@ -343,18 +349,19 @@ int send_release_packet(const char* iface, struct dhcp6_packet* packet)
+ client_addr.sin6_port = htons(DHCP6_CLIENT_PORT);
+ client_addr.sin6_flowinfo = 0;
+ client_addr.sin6_scope_id =0;
+- inet_pton(AF_INET6, "::", &client_addr.sin6_addr);
+- bind(sock, (struct sockaddr*)&client_addr, sizeof(struct sockaddr_in6));
+- inet_pton(AF_INET6, DHCP6_MULTICAST_ADDRESS, &server_addr.sin6_addr);
++ if (inet_pton(AF_INET6, "::", &client_addr.sin6_addr) <= 0)
++ fail_fatal("inet_pton", 5);
++ if (bind(sock, (struct sockaddr*)&client_addr, sizeof(struct sockaddr_in6)) != 0)
++ perror("bind"); /* continue on bind error */
++ if (inet_pton(AF_INET6, DHCP6_MULTICAST_ADDRESS, &server_addr.sin6_addr) <= 0)
++ fail_fatal("inet_pton", 5);
+ server_addr.sin6_port = htons(DHCP6_SERVER_PORT);
+- int16_t recv_size = 0;
++ ssize_t recv_size = 0;
++ int result;
+ for (i = 0; i < 5; i++)
+ {
+ if (sendto(sock, packet->buf, packet->len, 0, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
+- {
+- perror("sendto failed");
+- exit(4);
+- }
++ fail_fatal("sendto failed", 4);
+
+ recv_size = recvfrom(sock, response, sizeof(response), MSG_DONTWAIT, NULL, 0);
+ if (recv_size == -1)
+@@ -367,16 +374,18 @@ int send_release_packet(const char* iface, struct dhcp6_packet* packet)
+ else
+ {
+ perror("recvfrom");
++ result = UNSPEC_FAIL;
+ }
+ }
+-
+- int16_t result = parse_packet(response, recv_size);
+- if (result == NOT_REPLY_CODE)
++ else
+ {
+- sleep(1);
+- continue;
++ result = parse_packet(response, recv_size);
++ if (result == NOT_REPLY_CODE)
++ {
++ sleep(1);
++ continue;
++ }
+ }
+-
+ close(sock);
+ return result;
+ }
+--
+2.31.1
+
diff --git a/0006-Fix-coverity-formats-issues-in-blockdata.patch b/0006-Fix-coverity-formats-issues-in-blockdata.patch
new file mode 100644
index 0000000..beb0898
--- /dev/null
+++ b/0006-Fix-coverity-formats-issues-in-blockdata.patch
@@ -0,0 +1,48 @@
+From 3a077065ce846e301b532127ebecdd2771ad75ed Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 16:41:00 +0200
+Subject: [PATCH 06/15] Fix coverity formats issues in blockdata
+
+Error: PRINTF_ARGS (CWE-686): [#def16]
+dnsmasq-2.86test7/src/blockdata.c:56: invalid_type: Argument "blockdata_count * 48UL" to format specifier "%u" was expected to have type "unsigned int" but has type "unsigned long".
+ # 54| {
+ # 55| my_syslog(LOG_INFO, _("pool memory in use %u, max %u, allocated %u"),
+ # 56|-> blockdata_count * sizeof(struct blockdata),
+ # 57| blockdata_hwm * sizeof(struct blockdata),
+ # 58| blockdata_alloced * sizeof(struct blockdata));
+
+Error: PRINTF_ARGS (CWE-686): [#def17]
+dnsmasq-2.86test7/src/blockdata.c:57: invalid_type: Argument "blockdata_hwm * 48UL" to format specifier "%u" was expected to have type "unsigned int" but has type "unsigned long".
+ # 55| my_syslog(LOG_INFO, _("pool memory in use %u, max %u, allocated %u"),
+ # 56| blockdata_count * sizeof(struct blockdata),
+ # 57|-> blockdata_hwm * sizeof(struct blockdata),
+ # 58| blockdata_alloced * sizeof(struct blockdata));
+ # 59| }
+
+Error: PRINTF_ARGS (CWE-686): [#def18]
+dnsmasq-2.86test7/src/blockdata.c:58: invalid_type: Argument "blockdata_alloced * 48UL" to format specifier "%u" was expected to have type "unsigned int" but has type "unsigned long".
+ # 56| blockdata_count * sizeof(struct blockdata),
+ # 57| blockdata_hwm * sizeof(struct blockdata),
+ # 58|-> blockdata_alloced * sizeof(struct blockdata));
+ # 59| }
+ # 60|
+---
+ src/blockdata.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/blockdata.c b/src/blockdata.c
+index f7740b5..0986285 100644
+--- a/src/blockdata.c
++++ b/src/blockdata.c
+@@ -52,7 +52,7 @@ void blockdata_init(void)
+
+ void blockdata_report(void)
+ {
+- my_syslog(LOG_INFO, _("pool memory in use %u, max %u, allocated %u"),
++ my_syslog(LOG_INFO, _("pool memory in use %zu, max %zu, allocated %zu"),
+ blockdata_count * sizeof(struct blockdata),
+ blockdata_hwm * sizeof(struct blockdata),
+ blockdata_alloced * sizeof(struct blockdata));
+--
+2.31.1
+
diff --git a/0007-Retry-dhcp6-ping-on-interrupts.patch b/0007-Retry-dhcp6-ping-on-interrupts.patch
new file mode 100644
index 0000000..1beb806
--- /dev/null
+++ b/0007-Retry-dhcp6-ping-on-interrupts.patch
@@ -0,0 +1,32 @@
+From 467b621fb7da6e1318ac7204325b0adb01b3ff19 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 16:48:50 +0200
+Subject: [PATCH 07/15] Retry dhcp6 ping on interrupts
+
+Error: CHECKED_RETURN (CWE-252): [#def35]
+dnsmasq-2.86test7/src/dhcp6.c:295: check_return: Calling "sendto(dnsmasq_daemon->icmp6fd, &neigh, 24UL, 0, __CONST_SOCKADDR_ARG({.__sockaddr__ = &addr.sa}), 28U)" without checking return value. This library function may fail and return an error code.
+ # 293| break;
+ # 294|
+ # 295|-> sendto(daemon->icmp6fd, &neigh, sizeof(neigh), 0, &addr.sa, sizeof(addr));
+ # 296|
+ # 297| ts.tv_sec = 0;
+---
+ src/dhcp6.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/dhcp6.c b/src/dhcp6.c
+index 2be877f..ae1f5c1 100644
+--- a/src/dhcp6.c
++++ b/src/dhcp6.c
+@@ -292,7 +292,7 @@ void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac, unsi
+ if ((maclen = find_mac(&addr, mac, 0, now)) != 0)
+ break;
+
+- sendto(daemon->icmp6fd, &neigh, sizeof(neigh), 0, &addr.sa, sizeof(addr));
++ while(retry_send(sendto(daemon->icmp6fd, &neigh, sizeof(neigh), 0, &addr.sa, sizeof(addr))));
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = 100000000; /* 100ms */
+--
+2.31.1
+
diff --git a/0008-Fix-coverity-warnings-on-dbus.patch b/0008-Fix-coverity-warnings-on-dbus.patch
new file mode 100644
index 0000000..fd02da5
--- /dev/null
+++ b/0008-Fix-coverity-warnings-on-dbus.patch
@@ -0,0 +1,131 @@
+From bbfdf6a435cbd5f71ae76f962ce86786346589aa Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 17:19:05 +0200
+Subject: [PATCH 08/15] Fix coverity warnings on dbus
+
+Error: CLANG_WARNING: [#def30]
+dnsmasq-2.86test7/src/dbus.c:117:3: warning[deadcode.DeadStores]: Value stored to 'w' is never read
+ # 115| daemon->watches = w;
+ # 116|
+ # 117|-> w = data; /* no warning */
+ # 118| return TRUE;
+ # 119| }
+
+Error: CLANG_WARNING: [#def31]
+dnsmasq-2.86test7/src/dbus.c:137:3: warning[deadcode.DeadStores]: Value stored to 'w' is never read
+ # 135| }
+ # 136|
+ # 137|-> w = data; /* no warning */
+ # 138| }
+ # 139|
+
+Error: CHECKED_RETURN (CWE-252): [#def32]
+dnsmasq-2.86test7/src/dbus.c:146: check_return: Calling "dbus_message_iter_init" without checking return value (as is done elsewhere 4 out of 5 times).
+dnsmasq-2.86test7/src/dbus.c:460: example_checked: Example 1: "dbus_message_iter_init(message, &iter)" has its value checked in "dbus_message_iter_init(message, &iter)".
+dnsmasq-2.86test7/src/dbus.c:573: example_checked: Example 2: "dbus_message_iter_init(message, &iter)" has its value checked in "dbus_message_iter_init(message, &iter)".
+dnsmasq-2.86test7/src/dbus.c:257: example_checked: Example 3: "dbus_message_iter_init(message, &iter)" has its value checked in "dbus_message_iter_init(message, &iter)".
+dnsmasq-2.86test7/src/dbus.c:427: example_checked: Example 4: "dbus_message_iter_init(message, &iter)" has its value checked in "dbus_message_iter_init(message, &iter)".
+ # 144| char *domain;
+ # 145|
+ # 146|-> dbus_message_iter_init(message, &iter);
+ # 147|
+ # 148| mark_servers(SERV_FROM_DBUS);
+
+Error: NEGATIVE_RETURNS (CWE-394): [#def33]
+dnsmasq-2.86test7/src/dbus.c:547: negative_return_fn: Function "parse_hex((char *)hwaddr, dhcp_chaddr, 16, NULL, &hw_type)" returns a negative number.
+dnsmasq-2.86test7/src/dbus.c:547: assign: Assigning: "hw_len" = "parse_hex((char *)hwaddr, dhcp_chaddr, 16, NULL, &hw_type)".
+dnsmasq-2.86test7/src/dbus.c:551: negative_returns: "hw_len" is passed to a parameter that cannot be negative.
+ # 549| hw_type = ARPHRD_ETHER;
+ # 550|
+ # 551|-> lease_set_hwaddr(lease, dhcp_chaddr, clid, hw_len, hw_type,
+ # 552| clid_len, now, 0);
+ # 553| lease_set_expires(lease, expires, now);
+
+Error: CLANG_WARNING: [#def34]
+dnsmasq-2.86test7/src/dbus.c:722:3: warning[deadcode.DeadStores]: Value stored to 'method' is never read
+ # 720| clear_cache_and_reload(dnsmasq_time());
+ # 721|
+ # 722|-> method = user_data; /* no warning */
+ # 723|
+ # 724| /* If no reply or no error, return nothing */
+---
+ src/dbus.c | 21 +++++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/src/dbus.c b/src/dbus.c
+index cbdce9c..d746b9a 100644
+--- a/src/dbus.c
++++ b/src/dbus.c
+@@ -114,7 +114,7 @@ static dbus_bool_t add_watch(DBusWatch *watch, void *data)
+ w->next = daemon->watches;
+ daemon->watches = w;
+
+- w = data; /* no warning */
++ (void)data; /* no warning */
+ return TRUE;
+ }
+
+@@ -134,16 +134,20 @@ static void remove_watch(DBusWatch *watch, void *data)
+ up = &(w->next);
+ }
+
+- w = data; /* no warning */
++ (void)data; /* no warning */
+ }
+
+-static void dbus_read_servers(DBusMessage *message)
++static DBusMessage* dbus_read_servers(DBusMessage *message)
+ {
+ DBusMessageIter iter;
+ union mysockaddr addr, source_addr;
+ char *domain;
+
+- dbus_message_iter_init(message, &iter);
++ if (!dbus_message_iter_init(message, &iter))
++ {
++ return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
++ "Failed to initialize dbus message iter");
++ }
+
+ mark_servers(SERV_FROM_DBUS);
+
+@@ -222,6 +226,7 @@ static void dbus_read_servers(DBusMessage *message)
+
+ /* unlink and free anything still marked. */
+ cleanup_servers();
++ return NULL;
+ }
+
+ #ifdef HAVE_LOOP
+@@ -545,6 +550,10 @@ static DBusMessage *dbus_add_lease(DBusMessage* message)
+ "Invalid IP address '%s'", ipaddr);
+
+ hw_len = parse_hex((char*)hwaddr, dhcp_chaddr, DHCP_CHADDR_MAX, NULL, &hw_type);
++ if (hw_len < 0)
++ return dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
++ "Invalid HW address '%s'", hwaddr);
++
+ if (hw_type == 0 && hw_len != 0)
+ hw_type = ARPHRD_ETHER;
+
+@@ -668,7 +677,7 @@ DBusHandlerResult message_handler(DBusConnection *connection,
+ #endif
+ else if (strcmp(method, "SetServers") == 0)
+ {
+- dbus_read_servers(message);
++ reply = dbus_read_servers(message);
+ new_servers = 1;
+ }
+ else if (strcmp(method, "SetServersEx") == 0)
+@@ -719,7 +728,7 @@ DBusHandlerResult message_handler(DBusConnection *connection,
+ if (clear_cache)
+ clear_cache_and_reload(dnsmasq_time());
+
+- method = user_data; /* no warning */
++ (void)user_data; /* no warning */
+
+ /* If no reply or no error, return nothing */
+ if (!reply)
+--
+2.31.1
+
diff --git a/0009-Address-coverity-issues-detected-in-util.c.patch b/0009-Address-coverity-issues-detected-in-util.c.patch
new file mode 100644
index 0000000..cc075c7
--- /dev/null
+++ b/0009-Address-coverity-issues-detected-in-util.c.patch
@@ -0,0 +1,110 @@
+From 7b975696a7bda5b86fcf168644f177544adb6fe9 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 17:38:26 +0200
+Subject: [PATCH 09/15] Address coverity issues detected in util.c
+
+Error: CLANG_WARNING: [#def163]
+dnsmasq-2.86test7/src/util.c:204:9: warning[deadcode.DeadStores]: Although the value stored to 'rc' is used in the enclosing expression, the value is never actually read from 'rc'
+ # 202| *nomem = 0;
+ # 203|
+ # 204|-> if (!(rc = check_name(in)))
+ # 205| return NULL;
+ # 206|
+
+Error: UNREACHABLE (CWE-561): [#def164]
+dnsmasq-2.86test7/src/util.c:239: unreachable: This code cannot be reached: "if (ret = whine_malloc(strl...".
+ # 237| #endif
+ # 238|
+ # 239|-> if ((ret = whine_malloc(strlen(in)+1)))
+ # 240| strcpy(ret, in);
+ # 241| else if (nomem)
+
+Error: CLANG_WARNING: [#def165]
+dnsmasq-2.86test7/src/util.c:531:2: warning[deadcode.DeadStores]: Value stored to 'p' is never read
+ # 529| p += sprintf(&buf[p], "%um", x);
+ # 530| if ((x = t%60))
+ # 531|-> p += sprintf(&buf[p], "%us", x);
+ # 532| }
+ # 533| }
+
+Error: CPPCHECK_WARNING (CWE-456): [#def166]
+dnsmasq-2.86test7/src/util.c:577: error[uninitvar]: Uninitialized variable: sav
+ # 575| for (j = 0; j < bytes; j++)
+ # 576| {
+ # 577|-> char sav = sav;
+ # 578| if (j < bytes - 1)
+ # 579| {
+
+Error: CLANG_WARNING: [#def167]
+dnsmasq-2.86test7/src/util.c:577:9: warning[core.uninitialized.Assign]: Assigned value is garbage or undefined
+ # 575| for (j = 0; j < bytes; j++)
+ # 576| {
+ # 577|-> char sav = sav;
+ # 578| if (j < bytes - 1)
+ # 579| {
+
+Error: MISSING_RESTORE (CWE-573): [#def168]
+dnsmasq-2.86test7/src/util.c:580: save: Saving non-local "in[(j + 1) * 2]" in local "sav".
+dnsmasq-2.86test7/src/util.c:581: modify: Modifying non-local "in[(j + 1) * 2]".
+dnsmasq-2.86test7/src/util.c:586: end_of_scope: Value of non-local "in[(j + 1) * 2]" that was saved in "sav" is not restored as it was along other paths.
+dnsmasq-2.86test7/src/util.c:592: restore_example: The original value of non-local "in[(j + 1) * 2]" was restored here.
+ # 584| is illegal. */
+ # 585| if (strchr(&in[j*2], '*'))
+ # 586|-> return -1;
+ # 587| out[i] = strtol(&in[j*2], NULL, 16);
+ # 588| mask = mask << 1;
+---
+ src/util.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/src/util.c b/src/util.c
+index 1425764..8e69d55 100644
+--- a/src/util.c
++++ b/src/util.c
+@@ -208,6 +208,8 @@ char *canonicalise(char *in, int *nomem)
+ /* older libidn2 strips underscores, so don't do IDN processing
+ if the name has an underscore (check_name() returned 2) */
+ if (rc != 2)
++#else
++ (void)rc;
+ #endif
+ #if defined(HAVE_IDN) || defined(HAVE_LIBIDN2)
+ {
+@@ -235,11 +237,14 @@ char *canonicalise(char *in, int *nomem)
+ return ret;
+ }
+ #endif
+-
++
++#if !defined(HAVE_LIBIDN2) || (defined(HAVE_LIBIDN2) && (!defined(IDN2_VERSION_NUMBER) || IDN2_VERSION_NUMBER < 0x02000003))
++ /* If recent libidn2 is used, it cannot reach this code. */
+ if ((ret = whine_malloc(strlen(in)+1)))
+ strcpy(ret, in);
+ else if (nomem)
+- *nomem = 1;
++ *nomem = 1;
++#endif
+
+ return ret;
+ }
+@@ -528,7 +533,7 @@ void prettyprint_time(char *buf, unsigned int t)
+ if ((x = (t/60)%60))
+ p += sprintf(&buf[p], "%um", x);
+ if ((x = t%60))
+- p += sprintf(&buf[p], "%us", x);
++ sprintf(&buf[p], "%us", x);
+ }
+ }
+
+@@ -574,7 +579,7 @@ int parse_hex(char *in, unsigned char *out, int maxlen,
+ int j, bytes = (1 + (r - in))/2;
+ for (j = 0; j < bytes; j++)
+ {
+- char sav = sav;
++ char sav;
+ if (j < bytes - 1)
+ {
+ sav = in[(j+1)*2];
+--
+2.31.1
+
diff --git a/0010-Fix-coverity-detected-issues-in-option.c.patch b/0010-Fix-coverity-detected-issues-in-option.c.patch
new file mode 100644
index 0000000..a63ac41
--- /dev/null
+++ b/0010-Fix-coverity-detected-issues-in-option.c.patch
@@ -0,0 +1,236 @@
+From db835f8c40e83c6392e69ffc7f2cc500f7682dd4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 19:23:20 +0200
+Subject: [PATCH 10/15] Fix coverity detected issues in option.c
+
+Error: STRING_OVERFLOW (CWE-120): [#def99]
+dnsmasq-2.86test7/src/option.c:801: fixed_size_dest: You might overrun the 100-character fixed-size string "buff" by copying "usage[i].arg" without checking the length.
+# 799| if (usage[i].arg)
+# 800| {
+# 801|-> strcpy(buff, usage[i].arg);
+# 802| for (j = 0; tab[j].handle; j++)
+# 803| if (tab[j].handle == *(usage[i].arg))
+
+Error: CLANG_WARNING: [#def100]
+dnsmasq-2.86test7/src/option.c:962:3: warning[deadcode.DeadStores]: Value stored to 'domain' is never read
+# 960| }
+# 961|
+# 962|-> domain += sprintf(domain, "in-addr.arpa");
+# 963|
+# 964| return 1;
+
+Error: CLANG_WARNING: [#def101]
+dnsmasq-2.86test7/src/option.c:981:3: warning[deadcode.DeadStores]: Value stored to 'domain' is never read
+# 979| domain += sprintf(domain, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
+# 980| }
+# 981|-> domain += sprintf(domain, "ip6.arpa");
+# 982|
+# 983| return 1;
+
+Error: RESOURCE_LEAK (CWE-772): [#def102] [important]
+dnsmasq-2.86test7/src/option.c:1809: alloc_fn: Storage is returned from allocation function "opt_malloc".
+dnsmasq-2.86test7/src/option.c:1809: var_assign: Assigning: "path" = storage returned from "opt_malloc(strlen(directory) + len + 2UL)".
+dnsmasq-2.86test7/src/option.c:1810: noescape: Resource "path" is not freed or pointed-to in "strcpy". [Note: The source code implementation of the function has been overridden by a builtin model.]
+dnsmasq-2.86test7/src/option.c:1811: noescape: Resource "path" is not freed or pointed-to in "strcat". [Note: The source code implementation of the function has been overridden by a builtin model.]
+dnsmasq-2.86test7/src/option.c:1812: noescape: Resource "path" is not freed or pointed-to in "strcat". [Note: The source code implementation of the function has been overridden by a builtin model.]
+dnsmasq-2.86test7/src/option.c:1815: noescape: Resource "path" is not freed or pointed-to in "stat".
+dnsmasq-2.86test7/src/option.c:1809: overwrite_var: Overwriting "path" in "path = opt_malloc(strlen(directory) + len + 2UL)" leaks the storage that "path" points to.
+# 1807| continue;
+# 1808|
+# 1809|-> path = opt_malloc(strlen(directory) + len + 2);
+# 1810| strcpy(path, directory);
+# 1811| strcat(path, "/");
+
+Error: RESOURCE_LEAK (CWE-772): [#def103] [important]
+dnsmasq-2.86test7/src/option.c:1809: alloc_fn: Storage is returned from allocation function "opt_malloc".
+dnsmasq-2.86test7/src/option.c:1809: var_assign: Assigning: "path" = storage returned from "opt_malloc(strlen(directory) + len + 2UL)".
+dnsmasq-2.86test7/src/option.c:1810: noescape: Resource "path" is not freed or pointed-to in "strcpy". [Note: The source code implementation of the function has been overridden by a builtin model.]
+dnsmasq-2.86test7/src/option.c:1811: noescape: Resource "path" is not freed or pointed-to in "strcat". [Note: The source code implementation of the function has been overridden by a builtin model.]
+dnsmasq-2.86test7/src/option.c:1812: noescape: Resource "path" is not freed or pointed-to in "strcat". [Note: The source code implementation of the function has been overridden by a builtin model.]
+dnsmasq-2.86test7/src/option.c:1815: noescape: Resource "path" is not freed or pointed-to in "stat".
+dnsmasq-2.86test7/src/option.c:1858: leaked_storage: Variable "path" going out of scope leaks the storage it points to.
+# 1856| free(files);
+# 1857| }
+# 1858|-> break;
+# 1859| }
+# 1860|
+
+Error: RESOURCE_LEAK (CWE-772): [#def104] [important]
+dnsmasq-2.86test7/src/option.c:1996: alloc_fn: Storage is returned from allocation function "canonicalise_opt".
+dnsmasq-2.86test7/src/option.c:1996: var_assign: Assigning: "name" = storage returned from "canonicalise_opt(arg)".
+dnsmasq-2.86test7/src/option.c:1998: leaked_storage: Variable "name" going out of scope leaks the storage it points to.
+# 1996| if (!(name = canonicalise_opt(arg)) ||
+# 1997| (comma && !(target = canonicalise_opt(comma))))
+# 1998|-> ret_err(_("bad MX name"));
+# 1999|
+# 2000| new = opt_malloc(sizeof(struct mx_srv_record));
+
+Error: RESOURCE_LEAK (CWE-772): [#def106] [important]
+dnsmasq-2.86test7/src/option.c:3477: alloc_fn: Storage is returned from allocation function "opt_malloc".
+dnsmasq-2.86test7/src/option.c:3477: var_assign: Assigning: "new" = storage returned from "opt_malloc(96UL)".
+dnsmasq-2.86test7/src/option.c:3618: leaked_storage: Variable "new" going out of scope leaks the storage it points to.
+# 3616| sprintf(errstr, _("duplicate dhcp-host IP address %s"),
+# 3617| daemon->addrbuff);
+# 3618|-> return 0;
+# 3619| }
+# 3620| }
+
+Error: RESOURCE_LEAK (CWE-772): [#def108] [important]
+dnsmasq-2.86test7/src/option.c:3781: alloc_fn: Storage is returned from allocation function "opt_malloc".
+dnsmasq-2.86test7/src/option.c:3781: var_assign: Assigning: "new" = storage returned from "opt_malloc(32UL)".
+dnsmasq-2.86test7/src/option.c:3786: leaked_storage: Variable "new" going out of scope leaks the storage it points to.
+# 3784|
+# 3785| if (!(comma = split(arg)) || (len = strlen(comma)) == 0)
+# 3786|-> ret_err(gen_err);
+# 3787|
+# 3788| new->wildcard = 0;
+
+Error: RESOURCE_LEAK (CWE-772): [#def109] [important]
+dnsmasq-2.86test7/src/option.c:3921: alloc_fn: Storage is returned from allocation function "opt_malloc".
+dnsmasq-2.86test7/src/option.c:3921: var_assign: Assigning: "new" = storage returned from "opt_malloc(56UL)".
+dnsmasq-2.86test7/src/option.c:3994: leaked_storage: Variable "new" going out of scope leaks the storage it points to.
+# 3992| }
+# 3993|
+# 3994|-> ret_err(gen_err);
+# 3995| }
+# 3996|
+
+Error: CLANG_WARNING: [#def111]
+dnsmasq-2.86test7/src/option.c:4693:25: warning[deadcode.DeadStores]: Value stored to 'tmp' during its initialization is never read
+# 4691| if (!canon)
+# 4692| {
+# 4693|-> struct name_list *tmp = new->names, *next;
+# 4694| for (tmp = new->names; tmp; tmp = next)
+# 4695|
+---
+ src/option.c | 33 +++++++++++++++++++++------------
+ 1 file changed, 21 insertions(+), 12 deletions(-)
+
+diff --git a/src/option.c b/src/option.c
+index ffce9fc..11655fd 100644
+--- a/src/option.c
++++ b/src/option.c
+@@ -798,7 +798,7 @@ static void do_usage(void)
+
+ if (usage[i].arg)
+ {
+- strcpy(buff, usage[i].arg);
++ safe_strncpy(buff, usage[i].arg, sizeof(buff));
+ for (j = 0; tab[j].handle; j++)
+ if (tab[j].handle == *(usage[i].arg))
+ sprintf(buff, "%d", tab[j].val);
+@@ -959,7 +959,7 @@ static int domain_rev4(char *domain, struct in_addr addr, int msize)
+ return 0;
+ }
+
+- domain += sprintf(domain, "in-addr.arpa");
++ sprintf(domain, "in-addr.arpa");
+
+ return 1;
+ }
+@@ -978,7 +978,7 @@ static int domain_rev6(char *domain, struct in6_addr *addr, int msize)
+ int dig = ((unsigned char *)addr)[i>>3];
+ domain += sprintf(domain, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
+ }
+- domain += sprintf(domain, "ip6.arpa");
++ sprintf(domain, "ip6.arpa");
+
+ return 1;
+ }
+@@ -1829,6 +1829,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
+ new->next = li;
+ *up = new;
+ }
++ else
++ free(path);
+
+ }
+
+@@ -1995,7 +1997,11 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
+
+ if (!(name = canonicalise_opt(arg)) ||
+ (comma && !(target = canonicalise_opt(comma))))
+- ret_err(_("bad MX name"));
++ {
++ free(name);
++ free(target);
++ ret_err(_("bad MX name"));
++ }
+
+ new = opt_malloc(sizeof(struct mx_srv_record));
+ new->next = daemon->mxnames;
+@@ -3616,6 +3622,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
+ inet_ntop(AF_INET, &in, daemon->addrbuff, ADDRSTRLEN);
+ sprintf(errstr, _("duplicate dhcp-host IP address %s"),
+ daemon->addrbuff);
++ dhcp_config_free(new);
+ return 0;
+ }
+ }
+@@ -3779,16 +3786,16 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
+
+ case LOPT_NAME_MATCH: /* --dhcp-name-match */
+ {
+- struct dhcp_match_name *new = opt_malloc(sizeof(struct dhcp_match_name));
+- struct dhcp_netid *id = opt_malloc(sizeof(struct dhcp_netid));
++ struct dhcp_match_name *new;
+ ssize_t len;
+
+ if (!(comma = split(arg)) || (len = strlen(comma)) == 0)
+ ret_err(gen_err);
+
++ new = opt_malloc(sizeof(struct dhcp_match_name));
+ new->wildcard = 0;
+- new->netid = id;
+- id->net = opt_string_alloc(set_prefix(arg));
++ new->netid = opt_malloc(sizeof(struct dhcp_netid));
++ new->netid->net = opt_string_alloc(set_prefix(arg));
+
+ if (comma[len-1] == '*')
+ {
+@@ -3992,6 +3999,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
+ }
+ }
+
++ dhcp_netid_free(new->netid);
++ free(new);
+ ret_err(gen_err);
+ }
+
+@@ -4367,7 +4376,7 @@ err:
+ case LOPT_CNAME: /* --cname */
+ {
+ struct cname *new;
+- char *alias, *target, *last, *pen;
++ char *alias, *target=NULL, *last, *pen;
+ int ttl = -1;
+
+ for (last = pen = NULL, comma = arg; comma; comma = split(comma))
+@@ -4382,13 +4391,13 @@ err:
+ if (pen != arg && atoi_check(last, &ttl))
+ last = pen;
+
+- target = canonicalise_opt(last);
+-
+ while (arg != last)
+ {
+ int arglen = strlen(arg);
+ alias = canonicalise_opt(arg);
+
++ if (!target)
++ target = canonicalise_opt(last);
+ if (!alias || !target)
+ {
+ free(target);
+@@ -4691,7 +4700,7 @@ err:
+ struct name_list *nl;
+ if (!canon)
+ {
+- struct name_list *tmp = new->names, *next;
++ struct name_list *tmp, *next;
+ for (tmp = new->names; tmp; tmp = next)
+ {
+ next = tmp->next;
+--
+2.31.1
+
diff --git a/0011-Fix-coverity-detected-issue-in-radv.c.patch b/0011-Fix-coverity-detected-issue-in-radv.c.patch
new file mode 100644
index 0000000..845de43
--- /dev/null
+++ b/0011-Fix-coverity-detected-issue-in-radv.c.patch
@@ -0,0 +1,54 @@
+From 9c088b29dcdb8a3e013120d8272a6e0314a8f3df Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 19:29:23 +0200
+Subject: [PATCH 11/15] Fix coverity detected issue in radv.c
+
+Error: NULL_RETURNS (CWE-476): [#def114]
+dnsmasq-2.86test7/src/radv.c:748: returned_null: "expand" returns "NULL" (checked 10 out of 11 times).
+dnsmasq-2.86test7/src/radv.c:748: var_assigned: Assigning: "p" = "NULL" return value from "expand".
+dnsmasq-2.86test7/src/radv.c:749: dereference: Dereferencing a pointer that might be "NULL" "p" when calling "memset". [Note: The source code implementation of the function has been overridden by a builtin model.]
+dnsmasq-2.86test7/src/outpacket.c:83: example_checked: Example 1: "expand(len)" has its value checked in "p = expand(len)".
+dnsmasq-2.86test7/src/outpacket.c:109: example_checked: Example 2: "expand(1UL)" has its value checked in "p = expand(1UL)".
+dnsmasq-2.86test7/src/radv.c:269: example_checked: Example 3: "expand(16UL)" has its value checked in "ra = expand(16UL)".
+dnsmasq-2.86test7/src/radv.c:363: example_checked: Example 4: "expand(32UL)" has its value checked in "opt = expand(32UL)".
+dnsmasq-2.86test7/src/radv.c:708: example_checked: Example 5: "expand(32UL)" has its value checked in "opt = expand(32UL)".
+ # 747| int len = (maclen + 9) >> 3;
+ # 748| unsigned char *p = expand(len << 3);
+ # 749|-> memset(p, 0, len << 3);
+ # 750| *p++ = ICMP6_OPT_SOURCE_MAC;
+ # 751| *p++ = len;
+
+Error: NULL_RETURNS (CWE-476): [#def115]
+dnsmasq-2.86test7/src/radv.c:748: returned_null: "expand" returns "NULL" (checked 10 out of 11 times).
+dnsmasq-2.86test7/src/radv.c:748: var_assigned: Assigning: "p" = "NULL" return value from "expand".
+dnsmasq-2.86test7/src/radv.c:750: dereference: Incrementing a pointer which might be null: "p".
+dnsmasq-2.86test7/src/outpacket.c:83: example_checked: Example 1: "expand(len)" has its value checked in "p = expand(len)".
+dnsmasq-2.86test7/src/outpacket.c:109: example_checked: Example 2: "expand(1UL)" has its value checked in "p = expand(1UL)".
+dnsmasq-2.86test7/src/radv.c:269: example_checked: Example 3: "expand(16UL)" has its value checked in "ra = expand(16UL)".
+dnsmasq-2.86test7/src/radv.c:363: example_checked: Example 4: "expand(32UL)" has its value checked in "opt = expand(32UL)".
+dnsmasq-2.86test7/src/radv.c:708: example_checked: Example 5: "expand(32UL)" has its value checked in "opt = expand(32UL)".
+ # 748| unsigned char *p = expand(len << 3);
+ # 749| memset(p, 0, len << 3);
+ # 750|-> *p++ = ICMP6_OPT_SOURCE_MAC;
+ # 751| *p++ = len;
+ # 752| memcpy(p, mac, maclen);
+---
+ src/radv.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/src/radv.c b/src/radv.c
+index 3255904..6d6fa32 100644
+--- a/src/radv.c
++++ b/src/radv.c
+@@ -746,6 +746,8 @@ static int add_lla(int index, unsigned int type, char *mac, size_t maclen, void
+ add 7 to round up */
+ int len = (maclen + 9) >> 3;
+ unsigned char *p = expand(len << 3);
++ if (!p)
++ return 1;
+ memset(p, 0, len << 3);
+ *p++ = ICMP6_OPT_SOURCE_MAC;
+ *p++ = len;
+--
+2.31.1
+
diff --git a/0012-Fix-coverity-detected-issues-in-cache.c.patch b/0012-Fix-coverity-detected-issues-in-cache.c.patch
new file mode 100644
index 0000000..e88c64a
--- /dev/null
+++ b/0012-Fix-coverity-detected-issues-in-cache.c.patch
@@ -0,0 +1,41 @@
+From 957b2b25238d82a6c3afced2ff0423ad171fb22e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 20:10:37 +0200
+Subject: [PATCH 12/15] Fix coverity detected issues in cache.c
+
+Error: UNINIT (CWE-457): [#def27]
+dnsmasq-2.86test7/src/cache.c:1193: var_decl: Declaring variable "lrec" without initializer.
+dnsmasq-2.86test7/src/cache.c:1315: uninit_use_in_call: Using uninitialized value "lrec.ttd" when calling "make_non_terminals".
+ # 1313| {
+ # 1314| lrec.name.namep = txt->name;
+ # 1315|-> make_non_terminals(&lrec);
+ # 1316| }
+ # 1317|
+
+Error: CLANG_WARNING: [#def29]
+dnsmasq-2.86test7/src/cache.c:1552:15: warning[core.uninitialized.Assign]: Assigned value is garbage or undefined
+ # 1550| {
+ # 1551| crecp->flags = (source->flags | F_NAMEP) & ~(F_IPV4 | F_IPV6 | F_CNAME | F_SRV | F_DNSKEY | F_DS | F_REVERSE);
+ # 1552|-> crecp->ttd = source->ttd;
+ # 1553| crecp->name.namep = name;
+ # 1554|
+---
+ src/cache.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/cache.c b/src/cache.c
+index 97c51a7..6722fa6 100644
+--- a/src/cache.c
++++ b/src/cache.c
+@@ -1188,7 +1188,7 @@ void cache_reload(void)
+ struct host_record *hr;
+ struct name_list *nl;
+ struct cname *a;
+- struct crec lrec;
++ struct crec lrec = { 0, };
+ struct mx_srv_record *mx;
+ struct txt_record *txt;
+ struct interface_name *intr;
+--
+2.31.1
+
diff --git a/0013-Fix-coverity-issues-detected-in-domain-match.c.patch b/0013-Fix-coverity-issues-detected-in-domain-match.c.patch
new file mode 100644
index 0000000..60df62b
--- /dev/null
+++ b/0013-Fix-coverity-issues-detected-in-domain-match.c.patch
@@ -0,0 +1,134 @@
+From 0dafe990a1395d597bc6022c3936769f7a0ddea7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 21:16:22 +0200
+Subject: [PATCH 13/15] Fix coverity issues detected in domain-match.c
+
+Error: CHECKED_RETURN (CWE-252): [#def28]
+dnsmasq-2.86rc3/src/domain-match.c:414: check_return: Calling "add_resource_record" without checking return value (as is done elsewhere 44 out of 46 times).
+dnsmasq-2.86rc3/src/auth.c:214: example_checked: Example 1: "add_resource_record(header, limit, &trunc, nameoffset, &ansp, dnsmasq_daemon->auth_ttl, NULL, 12, 1, "d", intr->name)" has its value checked in "add_resource_record(header, limit, &trunc, nameoffset, &ansp, dnsmasq_daemon->auth_ttl, NULL, 12, 1, "d", intr->name)".
+dnsmasq-2.86rc3/src/auth.c:239: example_checked: Example 2: "add_resource_record(header, limit, &trunc, nameoffset, &ansp, dnsmasq_daemon->auth_ttl, NULL, 12, 1, "d", name)" has its value checked in "add_resource_record(header, limit, &trunc, nameoffset, &ansp, dnsmasq_daemon->auth_ttl, NULL, 12, 1, "d", name)".
+dnsmasq-2.86rc3/src/rfc1035.c:1463: example_checked: Example 3: "add_resource_record(header, limit, &trunc, nameoffset, &ansp, crec_ttl(crecp, now), &nameoffset, 5, 1, "d", cname_target)" has its value checked in "add_resource_record(header, limit, &trunc, nameoffset, &ansp, crec_ttl(crecp, now), &nameoffset, 5, 1, "d", cname_target)".
+dnsmasq-2.86rc3/src/rfc1035.c:1500: example_checked: Example 4: "add_resource_record(header, limit, &trunc, nameoffset, &ansp, ttl, NULL, 16, t->class, "t", t->len, t->txt)" has its value checked in "add_resource_record(header, limit, &trunc, nameoffset, &ansp, ttl, NULL, 16, t->class, "t", t->len, t->txt)".
+dnsmasq-2.86rc3/src/rfc1035.c:2021: example_checked: Example 5: "add_resource_record(header, limit, NULL, rec->offset, &ansp, crec_ttl(crecp, now), NULL, type, 1, ((crecp->flags & 0x80U) ? "4" : "6"), &crecp->addr)" has its value checked in "add_resource_record(header, limit, NULL, rec->offset, &ansp, crec_ttl(crecp, now), NULL, type, 1, ((crecp->flags & 0x80U) ? "4" : "6"), &crecp->addr)".
+ # 412|
+ # 413| header->ancount = htons(ntohs(header->ancount) + 1);
+ # 414|-> add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_A, C_IN, "4", &addr);
+ # 415| log_query((flags | F_CONFIG | F_FORWARD) & ~F_IPV6, name, (union all_addr *)&addr, NULL);
+ # 416| }
+
+Error: CHECKED_RETURN (CWE-252): [#def29]
+dnsmasq-2.86rc3/src/domain-match.c:429: check_return: Calling "add_resource_record" without checking return value (as is done elsewhere 44 out of 46 times).
+dnsmasq-2.86rc3/src/auth.c:214: example_checked: Example 1: "add_resource_record(header, limit, &trunc, nameoffset, &ansp, dnsmasq_daemon->auth_ttl, NULL, 12, 1, "d", intr->name)" has its value checked in "add_resource_record(header, limit, &trunc, nameoffset, &ansp, dnsmasq_daemon->auth_ttl, NULL, 12, 1, "d", intr->name)".
+dnsmasq-2.86rc3/src/auth.c:239: example_checked: Example 2: "add_resource_record(header, limit, &trunc, nameoffset, &ansp, dnsmasq_daemon->auth_ttl, NULL, 12, 1, "d", name)" has its value checked in "add_resource_record(header, limit, &trunc, nameoffset, &ansp, dnsmasq_daemon->auth_ttl, NULL, 12, 1, "d", name)".
+dnsmasq-2.86rc3/src/rfc1035.c:1463: example_checked: Example 3: "add_resource_record(header, limit, &trunc, nameoffset, &ansp, crec_ttl(crecp, now), &nameoffset, 5, 1, "d", cname_target)" has its value checked in "add_resource_record(header, limit, &trunc, nameoffset, &ansp, crec_ttl(crecp, now), &nameoffset, 5, 1, "d", cname_target)".
+dnsmasq-2.86rc3/src/rfc1035.c:1500: example_checked: Example 4: "add_resource_record(header, limit, &trunc, nameoffset, &ansp, ttl, NULL, 16, t->class, "t", t->len, t->txt)" has its value checked in "add_resource_record(header, limit, &trunc, nameoffset, &ansp, ttl, NULL, 16, t->class, "t", t->len, t->txt)".
+dnsmasq-2.86rc3/src/rfc1035.c:2021: example_checked: Example 5: "add_resource_record(header, limit, NULL, rec->offset, &ansp, crec_ttl(crecp, now), NULL, type, 1, ((crecp->flags & 0x80U) ? "4" : "6"), &crecp->addr)" has its value checked in "add_resource_record(header, limit, NULL, rec->offset, &ansp, crec_ttl(crecp, now), NULL, type, 1, ((crecp->flags & 0x80U) ? "4" : "6"), &crecp->addr)".
+ # 427|
+ # 428| header->ancount = htons(ntohs(header->ancount) + 1);
+ # 429|-> add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_AAAA, C_IN, "6", &addr);
+ # 430| log_query((flags | F_CONFIG | F_FORWARD) & ~F_IPV4, name, (union all_addr *)&addr, NULL);
+ # 431| }
+
+Error: NULL_RETURNS (CWE-476): [#def30]
+dnsmasq-2.86rc3/src/domain-match.c:611: returned_null: "whine_malloc" returns "NULL" (checked 72 out of 76 times).
+dnsmasq-2.86rc3/src/domain-match.c:611: var_assigned: Assigning: "alloc_domain" = "NULL" return value from "whine_malloc".
+dnsmasq-2.86rc3/src/domain-match.c:620: dereference: Dereferencing a pointer that might be "NULL" "alloc_domain" when calling "hostname_isequal".
+dnsmasq-2.86rc3/src/arp.c:88: example_checked: Example 1: "whine_malloc(48UL)" has its value checked in "arp = whine_malloc(48UL)".
+dnsmasq-2.86rc3/src/blockdata.c:24: example_assign: Example 2: Assigning: "new" = return value from "whine_malloc(n * 48UL)".
+dnsmasq-2.86rc3/src/blockdata.c:26: example_checked: Example 2 (cont.): "new" has its value checked in "new".
+dnsmasq-2.86rc3/src/cache.c:1545: example_assign: Example 3: Assigning: "crecp" = return value from "whine_malloc(70UL)".
+dnsmasq-2.86rc3/src/cache.c:1547: example_checked: Example 3 (cont.): "crecp" has its value checked in "crecp".
+dnsmasq-2.86rc3/src/forward.c:1791: example_assign: Example 4: Assigning: "packet" = return value from "whine_malloc(66573UL)".
+dnsmasq-2.86rc3/src/forward.c:1795: example_checked: Example 4 (cont.): "packet" has its value checked in "packet".
+dnsmasq-2.86rc3/src/inotify.c:186: example_checked: Example 5: "whine_malloc(lendir + lenfile + 2UL)" has its value checked in "path = whine_malloc(lendir + lenfile + 2UL)".
+ # 618| if (flags & SERV_IS_LOCAL)
+ # 619| for (serv = daemon->servers; serv; serv = serv->next)
+ # 620|-> if ((serv->flags & SERV_MARK) &&
+ # 621| hostname_isequal(alloc_domain, serv->domain))
+ # 622| break;
+
+Error: RESOURCE_LEAK (CWE-772): [#def31] [important]
+dnsmasq-2.86rc3/src/domain-match.c:611: alloc_fn: Storage is returned from allocation function "whine_malloc".
+dnsmasq-2.86rc3/src/domain-match.c:611: var_assign: Assigning: "alloc_domain" = storage returned from "whine_malloc(1UL)".
+dnsmasq-2.86rc3/src/domain-match.c:620: noescape: Resource "alloc_domain" is not freed or pointed-to in "hostname_isequal".
+dnsmasq-2.86rc3/src/domain-match.c:646: leaked_storage: Variable "alloc_domain" going out of scope leaks the storage it points to.
+ # 644|
+ # 645| if (!(serv = whine_malloc(size)))
+ # 646|-> return 0;
+ # 647|
+ # 648| if (flags & SERV_IS_LOCAL)
+
+Error: NULL_RETURNS (CWE-476): [#def32]
+dnsmasq-2.86rc3/src/domain-match.c:611: returned_null: "whine_malloc" returns "NULL" (checked 72 out of 76 times).
+dnsmasq-2.86rc3/src/domain-match.c:611: var_assigned: Assigning: "alloc_domain" = "NULL" return value from "whine_malloc".
+dnsmasq-2.86rc3/src/domain-match.c:674: dereference: Dereferencing a pointer that might be "NULL" "alloc_domain" when calling "strlen".
+dnsmasq-2.86rc3/src/arp.c:88: example_checked: Example 1: "whine_malloc(48UL)" has its value checked in "arp = whine_malloc(48UL)".
+dnsmasq-2.86rc3/src/blockdata.c:24: example_assign: Example 2: Assigning: "new" = return value from "whine_malloc(n * 48UL)".
+dnsmasq-2.86rc3/src/blockdata.c:26: example_checked: Example 2 (cont.): "new" has its value checked in "new".
+dnsmasq-2.86rc3/src/cache.c:1545: example_assign: Example 3: Assigning: "crecp" = return value from "whine_malloc(70UL)".
+dnsmasq-2.86rc3/src/cache.c:1547: example_checked: Example 3 (cont.): "crecp" has its value checked in "crecp".
+dnsmasq-2.86rc3/src/forward.c:1791: example_assign: Example 4: Assigning: "packet" = return value from "whine_malloc(66573UL)".
+dnsmasq-2.86rc3/src/forward.c:1795: example_checked: Example 4 (cont.): "packet" has its value checked in "packet".
+dnsmasq-2.86rc3/src/inotify.c:186: example_checked: Example 5: "whine_malloc(lendir + lenfile + 2UL)" has its value checked in "path = whine_malloc(lendir + lenfile + 2UL)".
+ # 672| serv->flags = flags;
+ # 673| serv->domain = alloc_domain;
+ # 674|-> serv->domain_len = strlen(alloc_domain);
+ # 675|
+ # 676| if (flags & SERV_4ADDR)
+---
+ src/domain-match.c | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/src/domain-match.c b/src/domain-match.c
+index f8e4796..7124c18 100644
+--- a/src/domain-match.c
++++ b/src/domain-match.c
+@@ -411,7 +411,8 @@ size_t make_local_answer(int flags, int gotname, size_t size, struct dns_header
+ addr.addr4 = srv->addr;
+
+ header->ancount = htons(ntohs(header->ancount) + 1);
+- add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_A, C_IN, "4", &addr);
++ if (!add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_A, C_IN, "4", &addr))
++ return 0;
+ log_query((flags | F_CONFIG | F_FORWARD) & ~F_IPV6, name, (union all_addr *)&addr, NULL);
+ }
+
+@@ -426,7 +427,8 @@ size_t make_local_answer(int flags, int gotname, size_t size, struct dns_header
+ addr.addr6 = srv->addr;
+
+ header->ancount = htons(ntohs(header->ancount) + 1);
+- add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_AAAA, C_IN, "6", &addr);
++ if (!add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_AAAA, C_IN, "6", &addr))
++ return 0;
+ log_query((flags | F_CONFIG | F_FORWARD) & ~F_IPV4, name, (union all_addr *)&addr, NULL);
+ }
+
+@@ -609,9 +611,11 @@ int add_update_server(int flags,
+
+ if (*domain == 0)
+ alloc_domain = whine_malloc(1);
+- else if (!(alloc_domain = canonicalise((char *)domain, NULL)))
++ else
++ alloc_domain = canonicalise((char *)domain, NULL);
++ 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. */
+@@ -643,7 +647,10 @@ int add_update_server(int flags,
+ size = sizeof(struct server);
+
+ if (!(serv = whine_malloc(size)))
+- return 0;
++ {
++ free(alloc_domain);
++ return 0;
++ }
+
+ if (flags & SERV_IS_LOCAL)
+ {
+--
+2.31.1
+
diff --git a/0014-Fix-coverity-detected-issues-in-dnsmasq.c.patch b/0014-Fix-coverity-detected-issues-in-dnsmasq.c.patch
new file mode 100644
index 0000000..6069244
--- /dev/null
+++ b/0014-Fix-coverity-detected-issues-in-dnsmasq.c.patch
@@ -0,0 +1,133 @@
+From f476acbe3c2830e6ff0c50cc36d364a3f3f4fadb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 22:45:29 +0200
+Subject: [PATCH 14/15] Fix coverity detected issues in dnsmasq.c
+
+Error: DEADCODE (CWE-561): [#def12]
+dnsmasq-2.86rc3/src/dnsmasq.c:37: assignment: Assigning: "bind_fallback" = "0".
+dnsmasq-2.86rc3/src/dnsmasq.c:927: const: At condition "bind_fallback", the value of "bind_fallback" must be equal to 0.
+dnsmasq-2.86rc3/src/dnsmasq.c:927: dead_error_condition: The condition "bind_fallback" cannot be true.
+dnsmasq-2.86rc3/src/dnsmasq.c:928: dead_error_line: Execution cannot reach this statement: "my_syslog(4, "setting --bin...".
+dnsmasq-2.86rc3/src/dnsmasq.c:928: effectively_constant: Local variable "bind_fallback" is assigned only once, to a constant value, making it effectively constant throughout its scope. If this is not the intent, examine the logic to see if there is a missing assignment that would make "bind_fallback" not remain constant.
+ # 926|
+ # 927| if (bind_fallback)
+ # 928|-> my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
+ # 929|
+ # 930| if (option_bool(OPT_NOWILD))
+
+Error: REVERSE_NEGATIVE (CWE-191): [#def13]
+dnsmasq-2.86rc3/src/dnsmasq.c:383: negative_sink_in_call: Passing "dnsmasq_daemon->pxefd" to a parameter that cannot be negative.
+dnsmasq-2.86rc3/src/dnsmasq.c:1086: check_after_sink: You might be using variable "dnsmasq_daemon->pxefd" before verifying that it is >= 0.
+ # 1084| {
+ # 1085| poll_listen(daemon->dhcpfd, POLLIN);
+ # 1086|-> if (daemon->pxefd != -1)
+ # 1087| poll_listen(daemon->pxefd, POLLIN);
+ # 1088| }
+
+Error: CHECKED_RETURN (CWE-252): [#def18]
+dnsmasq-2.86rc3/src/dnsmasq.c:1582: check_return: Calling "fcntl(dnsmasq_daemon->helperfd, 4, i & 0xfffffffffffff7ff)" without checking return value. This library function may fail and return an error code.
+ # 1580| /* block in writes until all done */
+ # 1581| if ((i = fcntl(daemon->helperfd, F_GETFL)) != -1)
+ # 1582|-> fcntl(daemon->helperfd, F_SETFL, i & ~O_NONBLOCK);
+ # 1583| do {
+ # 1584| helper_write();
+
+Error: CHECKED_RETURN (CWE-252): [#def22]
+dnsmasq-2.86rc3/src/dnsmasq.c:1991: check_return: Calling "fcntl(confd, 4, flags & 0xfffffffffffff7ff)" without checking return value. This library function may fail and return an error code.
+ # 1989| Reset that here. */
+ # 1990| if ((flags = fcntl(confd, F_GETFL, 0)) != -1)
+ # 1991|-> fcntl(confd, F_SETFL, flags & ~O_NONBLOCK);
+ # 1992|
+ # 1993| buff = tcp_request(confd, now, &tcp_addr, netmask, auth_dns);
+
+Error: CHECKED_RETURN (CWE-252): [#def26]
+dnsmasq-2.86rc3/src/dnssec.c:727: check_return: Calling "extract_name" without checking return value (as is done elsewhere 9 out of 10 times).
+dnsmasq-2.86rc3/src/dnssec.c:459: example_checked: Example 1: "extract_name(header, plen, &p, keyname, 1, 0)" has its value checked in "extract_name(header, plen, &p, keyname, 1, 0)".
+dnsmasq-2.86rc3/src/dnssec.c:269: example_checked: Example 2: "extract_name(header, plen, &state->ip, state->buff, 1, 0)" has its value checked in "extract_name(header, plen, &state->ip, state->buff, 1, 0)".
+dnsmasq-2.86rc3/src/dnssec.c:569: example_checked: Example 3: "extract_name(header, plen, &p, keyname, 1, 0)" has its value checked in "extract_name(header, plen, &p, keyname, 1, 0)".
+dnsmasq-2.86rc3/src/rfc1035.c:648: example_checked: Example 4: "extract_name(header, qlen, &p1, name, 1, 0)" has its value checked in "extract_name(header, qlen, &p1, name, 1, 0)".
+dnsmasq-2.86rc3/src/rfc1035.c:787: example_checked: Example 5: "extract_name(header, qlen, &p1, name, 1, 0)" has its value checked in "extract_name(header, qlen, &p1, name, 1, 0)".
+ # 725| /* namebuff used for workspace above, restore to leave unchanged on exit */
+ # 726| p = (unsigned char*)(rrset[0]);
+ # 727|-> extract_name(header, plen, &p, name, 1, 0);
+ # 728|
+ # 729| if (key)
+
+Error: CHECKED_RETURN (CWE-252): [#def27]
+dnsmasq-2.86rc3/src/dnssec.c:1020: check_return: Calling "extract_name" without checking return value (as is done elsewhere 7 out of 8 times).
+dnsmasq-2.86rc3/src/auth.c:140: example_checked: Example 1: "extract_name(header, qlen, &p, name, 1, 4)" has its value checked in "extract_name(header, qlen, &p, name, 1, 4)".
+dnsmasq-2.86rc3/src/dnssec.c:771: example_checked: Example 2: "extract_name(header, plen, &p, name, 1, 4)" has its value checked in "extract_name(header, plen, &p, name, 1, 4)".
+dnsmasq-2.86rc3/src/hash-questions.c:57: example_checked: Example 3: "extract_name(header, plen, &p, name, 1, 4)" has its value checked in "extract_name(header, plen, &p, name, 1, 4)".
+dnsmasq-2.86rc3/src/rfc1035.c:1028: example_checked: Example 4: "extract_name(header, qlen, &p, name, 1, 4)" has its value checked in "extract_name(header, qlen, &p, name, 1, 4)".
+dnsmasq-2.86rc3/src/rfc1035.c:1438: example_checked: Example 5: "extract_name(header, qlen, &p, name, 1, 4)" has its value checked in "extract_name(header, qlen, &p, name, 1, 4)".
+ # 1018|
+ # 1019| p = (unsigned char *)(header+1);
+ # 1020|-> extract_name(header, plen, &p, name, 1, 4);
+ # 1021| p += 4; /* qtype, qclass */
+ # 1022|
+---
+ src/dnsmasq.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/src/dnsmasq.c b/src/dnsmasq.c
+index 602daed..3e1bfe8 100644
+--- a/src/dnsmasq.c
++++ b/src/dnsmasq.c
+@@ -34,7 +34,6 @@ static void poll_resolv(int force, int do_reload, time_t now);
+
+ int main (int argc, char **argv)
+ {
+- int bind_fallback = 0;
+ time_t now;
+ struct sigaction sigact;
+ struct iname *if_tmp;
+@@ -59,6 +58,8 @@ int main (int argc, char **argv)
+ int did_bind = 0;
+ struct server *serv;
+ char *netlink_warn;
++#else
++ int bind_fallback = 0;
+ #endif
+ #if defined(HAVE_DHCP) || defined(HAVE_DHCP6)
+ struct dhcp_context *context;
+@@ -377,7 +378,7 @@ int main (int argc, char **argv)
+ bindtodevice(bound_device, daemon->dhcpfd);
+ did_bind = 1;
+ }
+- if (daemon->enable_pxe && bound_device)
++ if (daemon->enable_pxe && bound_device && daemon->pxefd != -1)
+ {
+ bindtodevice(bound_device, daemon->pxefd);
+ did_bind = 1;
+@@ -920,8 +921,10 @@ int main (int argc, char **argv)
+ my_syslog(LOG_WARNING, _("warning: failed to change owner of %s: %s"),
+ daemon->log_file, strerror(log_err));
+
++#ifndef HAVE_LINUX_NETWORK
+ if (bind_fallback)
+ my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
++#endif
+
+ if (option_bool(OPT_NOWILD))
+ warn_bound_listeners();
+@@ -1575,7 +1578,7 @@ static void async_event(int pipe, time_t now)
+ {
+ /* block in writes until all done */
+ if ((i = fcntl(daemon->helperfd, F_GETFL)) != -1)
+- fcntl(daemon->helperfd, F_SETFL, i & ~O_NONBLOCK);
++ while(retry_send(fcntl(daemon->helperfd, F_SETFL, i & ~O_NONBLOCK)));
+ do {
+ helper_write();
+ } while (!helper_buf_empty() || do_script_run(now));
+@@ -1984,7 +1987,7 @@ static void check_dns_listeners(time_t now)
+ attribute from the listening socket.
+ Reset that here. */
+ if ((flags = fcntl(confd, F_GETFL, 0)) != -1)
+- fcntl(confd, F_SETFL, flags & ~O_NONBLOCK);
++ while(retry_send(fcntl(confd, F_SETFL, flags & ~O_NONBLOCK)));
+
+ buff = tcp_request(confd, now, &tcp_addr, netmask, auth_dns);
+
+--
+2.31.1
+
diff --git a/0015-Fix-coverity-issues-in-dnssec.c.patch b/0015-Fix-coverity-issues-in-dnssec.c.patch
new file mode 100644
index 0000000..67b1d6d
--- /dev/null
+++ b/0015-Fix-coverity-issues-in-dnssec.c.patch
@@ -0,0 +1,62 @@
+From 82c23fb1f0d9e46c6ce4bc4a57f0d377cc6089b7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 22:51:36 +0200
+Subject: [PATCH 15/15] Fix coverity issues in dnssec.c
+
+Error: CHECKED_RETURN (CWE-252): [#def26]
+dnsmasq-2.86rc3/src/dnssec.c:727: check_return: Calling "extract_name" without checking return value (as is done elsewhere 9 out of 10 times).
+dnsmasq-2.86rc3/src/dnssec.c:459: example_checked: Example 1: "extract_name(header, plen, &p, keyname, 1, 0)" has its value checked in "extract_name(header, plen, &p, keyname, 1, 0)".
+dnsmasq-2.86rc3/src/dnssec.c:269: example_checked: Example 2: "extract_name(header, plen, &state->ip, state->buff, 1, 0)" has its value checked in "extract_name(header, plen, &state->ip, state->buff, 1, 0)".
+dnsmasq-2.86rc3/src/dnssec.c:569: example_checked: Example 3: "extract_name(header, plen, &p, keyname, 1, 0)" has its value checked in "extract_name(header, plen, &p, keyname, 1, 0)".
+dnsmasq-2.86rc3/src/rfc1035.c:648: example_checked: Example 4: "extract_name(header, qlen, &p1, name, 1, 0)" has its value checked in "extract_name(header, qlen, &p1, name, 1, 0)".
+dnsmasq-2.86rc3/src/rfc1035.c:787: example_checked: Example 5: "extract_name(header, qlen, &p1, name, 1, 0)" has its value checked in "extract_name(header, qlen, &p1, name, 1, 0)".
+ # 725| /* namebuff used for workspace above, restore to leave unchanged on exit */
+ # 726| p = (unsigned char*)(rrset[0]);
+ # 727|-> extract_name(header, plen, &p, name, 1, 0);
+ # 728|
+ # 729| if (key)
+
+Error: CHECKED_RETURN (CWE-252): [#def27]
+dnsmasq-2.86rc3/src/dnssec.c:1020: check_return: Calling "extract_name" without checking return value (as is done elsewhere 7 out of 8 times).
+dnsmasq-2.86rc3/src/auth.c:140: example_checked: Example 1: "extract_name(header, qlen, &p, name, 1, 4)" has its value checked in "extract_name(header, qlen, &p, name, 1, 4)".
+dnsmasq-2.86rc3/src/dnssec.c:771: example_checked: Example 2: "extract_name(header, plen, &p, name, 1, 4)" has its value checked in "extract_name(header, plen, &p, name, 1, 4)".
+dnsmasq-2.86rc3/src/hash-questions.c:57: example_checked: Example 3: "extract_name(header, plen, &p, name, 1, 4)" has its value checked in "extract_name(header, plen, &p, name, 1, 4)".
+dnsmasq-2.86rc3/src/rfc1035.c:1028: example_checked: Example 4: "extract_name(header, qlen, &p, name, 1, 4)" has its value checked in "extract_name(header, qlen, &p, name, 1, 4)".
+dnsmasq-2.86rc3/src/rfc1035.c:1438: example_checked: Example 5: "extract_name(header, qlen, &p, name, 1, 4)" has its value checked in "extract_name(header, qlen, &p, name, 1, 4)".
+ # 1018|
+ # 1019| p = (unsigned char *)(header+1);
+ # 1020|-> extract_name(header, plen, &p, name, 1, 4);
+ # 1021| p += 4; /* qtype, qclass */
+ # 1022|
+---
+ src/dnssec.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/src/dnssec.c b/src/dnssec.c
+index 94ebb6f..8800a5b 100644
+--- a/src/dnssec.c
++++ b/src/dnssec.c
+@@ -724,7 +724,8 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
+
+ /* namebuff used for workspace above, restore to leave unchanged on exit */
+ p = (unsigned char*)(rrset[0]);
+- extract_name(header, plen, &p, name, 1, 0);
++ if (!extract_name(header, plen, &p, name, 1, 0))
++ return STAT_BOGUS;
+
+ if (key)
+ {
+@@ -1017,7 +1018,9 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
+ }
+
+ p = (unsigned char *)(header+1);
+- extract_name(header, plen, &p, name, 1, 4);
++ if (!extract_name(header, plen, &p, name, 1, 4))
++ return STAT_BOGUS;
++
+ p += 4; /* qtype, qclass */
+
+ /* If the key needed to validate the DS is on the same domain as the DS, we'll
+--
+2.31.1
+
diff --git a/dnsmasq.spec b/dnsmasq.spec
index 7e74130..3af1202 100644
--- a/dnsmasq.spec
+++ b/dnsmasq.spec
@@ -41,8 +41,24 @@ 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=1978718
-Patch4: dnsmasq-2.85-lease-hostname.patch
+
+Patch10: 0001-Retry-on-interrupted-error-in-tftp.patch
+Patch11: 0002-Add-safety-checks-to-places-pointed-by-Coverity.patch
+Patch12: 0003-Small-safeguard-to-unexpected-data.patch
+Patch13: 0004-Fix-bunch-of-warnings-in-auth.c.patch
+Patch14: 0005-Fix-few-coverity-warnings-in-lease-tools.patch
+Patch15: 0006-Fix-coverity-formats-issues-in-blockdata.patch
+Patch16: 0007-Retry-dhcp6-ping-on-interrupts.patch
+Patch17: 0008-Fix-coverity-warnings-on-dbus.patch
+Patch18: 0009-Address-coverity-issues-detected-in-util.c.patch
+Patch19: 0010-Fix-coverity-detected-issues-in-option.c.patch
+Patch20: 0011-Fix-coverity-detected-issue-in-radv.c.patch
+Patch21: 0012-Fix-coverity-detected-issues-in-cache.c.patch
+Patch22: 0013-Fix-coverity-issues-detected-in-domain-match.c.patch
+Patch23: 0014-Fix-coverity-detected-issues-in-dnsmasq.c.patch
+Patch24: 0015-Fix-coverity-issues-in-dnssec.c.patch
+
+
Requires: nettle
https://src.fedoraproject.org/rpms/dnsmasq/c/06b5c95b058e4985a844a72bfc98...
2 years, 9 months
pemensik pushed to dnsmasq (f35). "Add coverity patches (..more)"
by notifications@fedoraproject.org
Notification time stamped 2021-09-09 08:21:10 UTC
From 06b5c95b058e4985a844a72bfc98ab0dd157a364 Mon Sep 17 00:00:00 2001
From: Petr Menšík <pemensik(a)redhat.com>
Date: Sep 09 2021 07:55:19 +0000
Subject: Add coverity patches
Various coverity fixes, not yet sent to upstream.
---
diff --git a/0001-Retry-on-interrupted-error-in-tftp.patch b/0001-Retry-on-interrupted-error-in-tftp.patch
new file mode 100644
index 0000000..f486f2d
--- /dev/null
+++ b/0001-Retry-on-interrupted-error-in-tftp.patch
@@ -0,0 +1,35 @@
+From f5f56c001dddd486859dc6301e6cbe00ba604fe8 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Wed, 18 Aug 2021 10:09:35 +0200
+Subject: [PATCH 01/15] Retry on interrupted error in tftp
+
+Interrupt might arrive when sending error reply. Retry if possible.
+
+Wrong Check of Return Value
+
+10. dnsmasq-2.85/src/tftp.c:603: check_return: Calling "sendto(transfer->sockfd, dnsmasq_daemon->packet, len, 0, __CONST_SOCKADDR_ARG({.__sockaddr__ = &peer.sa}), sa_len(&peer))" without checking return value. This library function may fail and return an error code.
+ # 601| prettyprint_addr(&peer, daemon->addrbuff);
+ # 602| len = tftp_err(ERR_TID, daemon->packet, _("ignoring packet from %s (TID mismatch)"), daemon->addrbuff);
+ # 603|-> sendto(transfer->sockfd, daemon->packet, len, 0, &peer.sa, sa_len(&peer));
+ # 604| }
+ # 605| }
+---
+ src/tftp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/tftp.c b/src/tftp.c
+index 37bdff2..3d87523 100644
+--- a/src/tftp.c
++++ b/src/tftp.c
+@@ -600,7 +600,7 @@ void check_tftp_listeners(time_t now)
+ /* Wrong source address. See rfc1350 para 4. */
+ prettyprint_addr(&peer, daemon->addrbuff);
+ len = tftp_err(ERR_TID, daemon->packet, _("ignoring packet from %s (TID mismatch)"), daemon->addrbuff);
+- sendto(transfer->sockfd, daemon->packet, len, 0, &peer.sa, sa_len(&peer));
++ while(retry_send(sendto(transfer->sockfd, daemon->packet, len, 0, &peer.sa, sa_len(&peer))));
+ }
+ }
+ }
+--
+2.31.1
+
diff --git a/0002-Add-safety-checks-to-places-pointed-by-Coverity.patch b/0002-Add-safety-checks-to-places-pointed-by-Coverity.patch
new file mode 100644
index 0000000..8fc70a5
--- /dev/null
+++ b/0002-Add-safety-checks-to-places-pointed-by-Coverity.patch
@@ -0,0 +1,77 @@
+From 061013293ceddce509ae06a31a045e803103f1ce Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Wed, 18 Aug 2021 14:59:23 +0200
+Subject: [PATCH 02/15] Add safety checks to places pointed by Coverity
+
+GCC Analyzer (experimental)
+
+1. dnsmasq-2.85/src/forward.c:0: scope_hint: In function 'allocate_rfd.part.0'
+2. dnsmasq-2.85/src/forward.c:2321:18: warning[-Wanalyzer-null-dereference]: dereference of NULL 'rfd'
+ # 2319| *fdlp = rfl;
+ # 2320|
+ # 2321|-> return rfl->rfd->fd;
+ # 2322| }
+ # 2323|
+
+1. dnsmasq-2.85/src/cache.c:0: scope_hint: In function 'log_query'
+2. dnsmasq-2.85/src/cache.c:1969:20: warning[-Wanalyzer-null-dereference]: dereference of NULL 'name'
+ # 1967| source = "cached";
+ # 1968|
+ # 1969|-> if (strlen(name) == 0)
+ # 1970| name = ".";
+ # 1971|
+
+1. dnsmasq-2.85/src/cache.c:0: scope_hint: In function 'cache_scan_free'
+2. dnsmasq-2.85/src/cache.c:436:20: warning[-Wanalyzer-null-argument]: use of NULL 'addr' where non-null expected
+40. /usr/include/sys/un.h:37: included_from: Included from here.
+41. dnsmasq-2.85/src/dnsmasq.h:101: included_from: Included from here.
+42. dnsmasq-2.85/src/cache.c:17: included_from: Included from here.
+43. /usr/include/string.h:64:12: note: argument 2 of 'memcmp' must be non-null
+ # 434| (flags & crecp->flags & F_REVERSE) &&
+ # 435| (flags & crecp->flags & (F_IPV4 | F_IPV6)) &&
+ # 436|-> memcmp(&crecp->addr, addr, addrlen) == 0)
+ # 437| {
+ # 438| *up = crecp->hash_next;
+---
+ src/cache.c | 4 ++--
+ src/forward.c | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/src/cache.c b/src/cache.c
+index 8add610..97c51a7 100644
+--- a/src/cache.c
++++ b/src/cache.c
+@@ -433,7 +433,7 @@ static struct crec *cache_scan_free(char *name, union all_addr *addr, unsigned s
+ else if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) &&
+ (flags & crecp->flags & F_REVERSE) &&
+ (flags & crecp->flags & (F_IPV4 | F_IPV6)) &&
+- memcmp(&crecp->addr, addr, addrlen) == 0)
++ addr && memcmp(&crecp->addr, addr, addrlen) == 0)
+ {
+ *up = crecp->hash_next;
+ cache_unlink(crecp);
+@@ -2013,7 +2013,7 @@ void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg)
+ else
+ source = "cached";
+
+- if (strlen(name) == 0)
++ if (name && !name[0])
+ name = ".";
+
+ if (option_bool(OPT_EXTRALOG))
+diff --git a/src/forward.c b/src/forward.c
+index 3d638e4..f07c908 100644
+--- a/src/forward.c
++++ b/src/forward.c
+@@ -2276,7 +2276,7 @@ int allocate_rfd(struct randfd_list **fdlp, struct server *serv)
+ }
+ }
+
+- if (j == daemon->numrrand)
++ if (!rfd) /* should be when j == daemon->numrrand */
+ {
+ struct randfd_list *rfl_poll;
+
+--
+2.31.1
+
diff --git a/0003-Small-safeguard-to-unexpected-data.patch b/0003-Small-safeguard-to-unexpected-data.patch
new file mode 100644
index 0000000..c496640
--- /dev/null
+++ b/0003-Small-safeguard-to-unexpected-data.patch
@@ -0,0 +1,28 @@
+From 920cd815bafea084f68cc4309399aea77bd7f66b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 14:11:42 +0200
+Subject: [PATCH 03/15] Small safeguard to unexpected data
+
+Make sure negative index is not used for comparison. It seems code in
+option parsing does not allow it to be empty, but insist on it also in
+this place.
+---
+ src/dhcp-common.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/dhcp-common.c b/src/dhcp-common.c
+index 73568a9..85b269a 100644
+--- a/src/dhcp-common.c
++++ b/src/dhcp-common.c
+@@ -88,7 +88,7 @@ int match_netid_wild(struct dhcp_netid *check, struct dhcp_netid *pool)
+ for (; check; check = check->next)
+ {
+ const int check_len = strlen(check->net);
+- const int is_wc = (check->net[check_len - 1] == '*');
++ const int is_wc = (check_len > 0 && check->net[check_len - 1] == '*');
+
+ /* '#' for not is for backwards compat. */
+ if (check->net[0] != '!' && check->net[0] != '#')
+--
+2.31.1
+
diff --git a/0004-Fix-bunch-of-warnings-in-auth.c.patch b/0004-Fix-bunch-of-warnings-in-auth.c.patch
new file mode 100644
index 0000000..976255f
--- /dev/null
+++ b/0004-Fix-bunch-of-warnings-in-auth.c.patch
@@ -0,0 +1,153 @@
+From e61af561900b4d2dd976a575b2efd388be092742 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 16:00:35 +0200
+Subject: [PATCH 04/15] Fix bunch of warnings in auth.c
+
+Error: CLANG_WARNING: [#def7]
+dnsmasq-2.86test7/src/auth.c:420:5: warning[deadcode.DeadStores]: Value stored to 'found' is never read
+ # 418| if (!found && is_name_synthetic(flag, name, &addr) )
+ # 419| {
+ # 420|-> found = 1;
+ # 421| nxdomain = 0;
+ # 422|
+
+Error: CLANG_WARNING: [#def8]
+dnsmasq-2.86test7/src/auth.c:436:8: warning[deadcode.DeadStores]: Value stored to 'found' is never read
+ # 434| {
+ # 435| auth = soa = 1; /* inhibits auth section */
+ # 436|-> found = 1;
+ # 437| log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<SOA>");
+ # 438| }
+
+Error: CLANG_WARNING: [#def9]
+dnsmasq-2.86test7/src/auth.c:472:8: warning[deadcode.DeadStores]: Value stored to 'found' is never read
+ # 470| ns = 1; /* ensure we include NS records! */
+ # 471| axfr = 1;
+ # 472|-> found = 1;
+ # 473| axfroffset = nameoffset;
+ # 474| log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<AXFR>");
+
+Error: CLANG_WARNING: [#def10]
+dnsmasq-2.86test7/src/auth.c:480:8: warning[deadcode.DeadStores]: Value stored to 'found' is never read
+ # 478| auth = 1;
+ # 479| ns = 1; /* inhibits auth section */
+ # 480|-> found = 1;
+ # 481| log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<NS>");
+ # 482| }
+
+Error: CLANG_WARNING: [#def11]
+dnsmasq-2.86test7/src/auth.c:501:4: warning[deadcode.DeadStores]: Value stored to 'found' is never read
+ # 499| log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid));
+ # 500| *cut = 0; /* remove domain part */
+ # 501|-> found = 1;
+ # 502| if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+ # 503| daemon->auth_ttl, NULL, qtype, C_IN,
+
+Error: CLANG_WARNING: [#def12]
+dnsmasq-2.86test7/src/auth.c:522:8: warning[deadcode.DeadStores]: Value stored to 'found' is never read
+ # 520| {
+ # 521| log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid));
+ # 522|-> found = 1;
+ # 523| if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+ # 524| daemon->auth_ttl, NULL, qtype, C_IN,
+
+Error: CLANG_WARNING: [#def13]
+dnsmasq-2.86test7/src/auth.c:617:8: warning[deadcode.DeadStores]: Value stored to 'p' is never read
+ # 615| p += sprintf(p, "%u.", a & 0xff);
+ # 616| a = a >> 8;
+ # 617|-> p += sprintf(p, "%u.in-addr.arpa", a & 0xff);
+ # 618|
+ # 619| }
+
+Error: CPPCHECK_WARNING (CWE-758): [#def14]
+dnsmasq-2.86test7/src/auth.c:627: warning[objectIndex]: The address of local variable 'addr6' might be accessed at non-zero index.
+ # 625| for (i = subnet->prefixlen-1; i >= 0; i -= 4)
+ # 626| {
+ # 627|-> int dig = ((unsigned char *)&subnet->addr.addr6)[i>>3];
+ # 628| p += sprintf(p, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
+ # 629| }
+
+Error: CLANG_WARNING: [#def15]
+dnsmasq-2.86test7/src/auth.c:630:8: warning[deadcode.DeadStores]: Value stored to 'p' is never read
+ # 628| p += sprintf(p, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
+ # 629| }
+ # 630|-> p += sprintf(p, "ip6.arpa");
+ # 631|
+ # 632| }
+---
+ src/auth.c | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+diff --git a/src/auth.c b/src/auth.c
+index 172a4b2..4f03c39 100644
+--- a/src/auth.c
++++ b/src/auth.c
+@@ -417,7 +417,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+
+ if (!found && is_name_synthetic(flag, name, &addr) )
+ {
+- found = 1;
+ nxdomain = 0;
+
+ log_query(F_FORWARD | F_CONFIG | flag, name, &addr, NULL);
+@@ -433,7 +432,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ if (qtype == T_SOA)
+ {
+ auth = soa = 1; /* inhibits auth section */
+- found = 1;
+ log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<SOA>");
+ }
+ else if (qtype == T_AXFR)
+@@ -469,7 +467,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ soa = 1; /* inhibits auth section */
+ ns = 1; /* ensure we include NS records! */
+ axfr = 1;
+- found = 1;
+ axfroffset = nameoffset;
+ log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<AXFR>");
+ }
+@@ -477,7 +474,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ {
+ auth = 1;
+ ns = 1; /* inhibits auth section */
+- found = 1;
+ log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<NS>");
+ }
+ }
+@@ -498,7 +494,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ *cut = '.'; /* restore domain part */
+ log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid));
+ *cut = 0; /* remove domain part */
+- found = 1;
+ if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+ daemon->auth_ttl, NULL, qtype, C_IN,
+ qtype == T_A ? "4" : "6", &crecp->addr))
+@@ -519,7 +514,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ if ((crecp->flags & flag) && (local_query || filter_zone(zone, flag, &(crecp->addr))))
+ {
+ log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid));
+- found = 1;
+ if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+ daemon->auth_ttl, NULL, qtype, C_IN,
+ qtype == T_A ? "4" : "6", &crecp->addr))
+@@ -614,7 +608,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ if (subnet->prefixlen >= 16 )
+ p += sprintf(p, "%u.", a & 0xff);
+ a = a >> 8;
+- p += sprintf(p, "%u.in-addr.arpa", a & 0xff);
++ sprintf(p, "%u.in-addr.arpa", a & 0xff);
+
+ }
+ else
+@@ -627,7 +621,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ int dig = ((unsigned char *)&subnet->addr.addr6)[i>>3];
+ p += sprintf(p, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
+ }
+- p += sprintf(p, "ip6.arpa");
++ sprintf(p, "ip6.arpa");
+
+ }
+ }
+--
+2.31.1
+
diff --git a/0005-Fix-few-coverity-warnings-in-lease-tools.patch b/0005-Fix-few-coverity-warnings-in-lease-tools.patch
new file mode 100644
index 0000000..ab24440
--- /dev/null
+++ b/0005-Fix-few-coverity-warnings-in-lease-tools.patch
@@ -0,0 +1,148 @@
+From be7f213066282baeed46cc34223601c462db9cbf Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 16:32:05 +0200
+Subject: [PATCH 05/15] Fix few coverity warnings in lease-tools
+
+Error: UNINIT (CWE-457): [#def2]
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release.c:265: var_decl: Declaring variable "ifr" without initializer.
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release.c:285: uninit_use_in_call: Using uninitialized value "ifr". Field "ifr.ifr_ifru" is uninitialized when calling "setsockopt".
+ # 283| strncpy(ifr.ifr_name, argv[1], sizeof(ifr.ifr_name)-1);
+ # 284| ifr.ifr_name[sizeof(ifr.ifr_name)-1] = '\0';
+ # 285|-> if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) == -1)
+ # 286| {
+ # 287| perror("cannot setup interface");
+
+Error: CHECKED_RETURN (CWE-252): [#def3]
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:346: check_return: Calling "inet_pton" without checking return value (as is done elsewhere 61 out of 72 times).
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:188: example_assign: Example 1: Assigning: "s" = return value from "inet_pton(10, ip, &result.ip)".
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:189: example_checked: Example 1 (cont.): "s" has its value checked in "s <= 0".
+dnsmasq-2.86test7/src/cache.c:1108: example_checked: Example 2: "inet_pton(10, token, &addr)" has its value checked in "inet_pton(10, token, &addr) > 0".
+dnsmasq-2.86test7/src/dbus.c:525: example_checked: Example 3: "inet_pton(2, ipaddr, &addr.addr4)" has its value checked in "inet_pton(2, ipaddr, &addr.addr4)".
+dnsmasq-2.86test7/src/domain.c:138: example_checked: Example 4: "inet_pton(prot, tail, addr)" has its value checked in "inet_pton(prot, tail, addr)".
+dnsmasq-2.86test7/src/lease.c:81: example_checked: Example 5: "inet_pton(10, dnsmasq_daemon->namebuff, &addr.addr6)" has its value checked in "inet_pton(10, dnsmasq_daemon->namebuff, &addr.addr6)".
+ # 344| client_addr.sin6_flowinfo = 0;
+ # 345| client_addr.sin6_scope_id =0;
+ # 346|-> inet_pton(AF_INET6, "::", &client_addr.sin6_addr);
+ # 347| bind(sock, (struct sockaddr*)&client_addr, sizeof(struct sockaddr_in6));
+ # 348| inet_pton(AF_INET6, DHCP6_MULTICAST_ADDRESS, &server_addr.sin6_addr);
+
+Error: CHECKED_RETURN (CWE-252): [#def4]
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:347: check_return: Calling "bind(sock, (struct sockaddr *)&client_addr, 28U)" without checking return value. This library function may fail and return an error code.
+ # 345| client_addr.sin6_scope_id =0;
+ # 346| inet_pton(AF_INET6, "::", &client_addr.sin6_addr);
+ # 347|-> bind(sock, (struct sockaddr*)&client_addr, sizeof(struct sockaddr_in6));
+ # 348| inet_pton(AF_INET6, DHCP6_MULTICAST_ADDRESS, &server_addr.sin6_addr);
+ # 349| server_addr.sin6_port = htons(DHCP6_SERVER_PORT);
+
+Error: CHECKED_RETURN (CWE-252): [#def5]
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:348: check_return: Calling "inet_pton" without checking return value (as is done elsewhere 61 out of 72 times).
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:188: example_assign: Example 1: Assigning: "s" = return value from "inet_pton(10, ip, &result.ip)".
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:189: example_checked: Example 1 (cont.): "s" has its value checked in "s <= 0".
+dnsmasq-2.86test7/src/cache.c:1108: example_checked: Example 2: "inet_pton(10, token, &addr)" has its value checked in "inet_pton(10, token, &addr) > 0".
+dnsmasq-2.86test7/src/dbus.c:525: example_checked: Example 3: "inet_pton(2, ipaddr, &addr.addr4)" has its value checked in "inet_pton(2, ipaddr, &addr.addr4)".
+dnsmasq-2.86test7/src/domain.c:138: example_checked: Example 4: "inet_pton(prot, tail, addr)" has its value checked in "inet_pton(prot, tail, addr)".
+dnsmasq-2.86test7/src/lease.c:81: example_checked: Example 5: "inet_pton(10, dnsmasq_daemon->namebuff, &addr.addr6)" has its value checked in "inet_pton(10, dnsmasq_daemon->namebuff, &addr.addr6)".
+ # 346| inet_pton(AF_INET6, "::", &client_addr.sin6_addr);
+ # 347| bind(sock, (struct sockaddr*)&client_addr, sizeof(struct sockaddr_in6));
+ # 348|-> inet_pton(AF_INET6, DHCP6_MULTICAST_ADDRESS, &server_addr.sin6_addr);
+ # 349| server_addr.sin6_port = htons(DHCP6_SERVER_PORT);
+ # 350| int16_t recv_size = 0;
+
+Error: NEGATIVE_RETURNS (CWE-394): [#def6]
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:360: var_tested_neg: Variable "recv_size" tests negative.
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:373: negative_returns: "recv_size" is passed to a parameter that cannot be negative.
+ # 371| }
+ # 372|
+ # 373|-> int16_t result = parse_packet(response, recv_size);
+ # 374| if (result == NOT_REPLY_CODE)
+ # 375| {
+---
+ contrib/lease-tools/dhcp_release.c | 1 +
+ contrib/lease-tools/dhcp_release6.c | 37 ++++++++++++++++++-----------
+ 2 files changed, 24 insertions(+), 14 deletions(-)
+
+diff --git a/contrib/lease-tools/dhcp_release.c b/contrib/lease-tools/dhcp_release.c
+index c1c835b..84f5610 100644
+--- a/contrib/lease-tools/dhcp_release.c
++++ b/contrib/lease-tools/dhcp_release.c
+@@ -280,6 +280,7 @@ int main(int argc, char **argv)
+
+ /* This voodoo fakes up a packet coming from the correct interface, which really matters for
+ a DHCP server */
++ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, argv[1], sizeof(ifr.ifr_name)-1);
+ ifr.ifr_name[sizeof(ifr.ifr_name)-1] = '\0';
+ if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) == -1)
+diff --git a/contrib/lease-tools/dhcp_release6.c b/contrib/lease-tools/dhcp_release6.c
+index d680222..9b3438f 100644
+--- a/contrib/lease-tools/dhcp_release6.c
++++ b/contrib/lease-tools/dhcp_release6.c
+@@ -318,6 +318,12 @@ void usage(const char* arg, FILE* stream)
+ fprintf (stream, "Usage: %s %s\n", arg, usage_string);
+ }
+
++static void fail_fatal(const char *errstr, int exitcode)
++{
++ perror(errstr);
++ exit(exitcode);
++}
++
+ int send_release_packet(const char* iface, struct dhcp6_packet* packet)
+ {
+ struct sockaddr_in6 server_addr, client_addr;
+@@ -343,18 +349,19 @@ int send_release_packet(const char* iface, struct dhcp6_packet* packet)
+ client_addr.sin6_port = htons(DHCP6_CLIENT_PORT);
+ client_addr.sin6_flowinfo = 0;
+ client_addr.sin6_scope_id =0;
+- inet_pton(AF_INET6, "::", &client_addr.sin6_addr);
+- bind(sock, (struct sockaddr*)&client_addr, sizeof(struct sockaddr_in6));
+- inet_pton(AF_INET6, DHCP6_MULTICAST_ADDRESS, &server_addr.sin6_addr);
++ if (inet_pton(AF_INET6, "::", &client_addr.sin6_addr) <= 0)
++ fail_fatal("inet_pton", 5);
++ if (bind(sock, (struct sockaddr*)&client_addr, sizeof(struct sockaddr_in6)) != 0)
++ perror("bind"); /* continue on bind error */
++ if (inet_pton(AF_INET6, DHCP6_MULTICAST_ADDRESS, &server_addr.sin6_addr) <= 0)
++ fail_fatal("inet_pton", 5);
+ server_addr.sin6_port = htons(DHCP6_SERVER_PORT);
+- int16_t recv_size = 0;
++ ssize_t recv_size = 0;
++ int result;
+ for (i = 0; i < 5; i++)
+ {
+ if (sendto(sock, packet->buf, packet->len, 0, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
+- {
+- perror("sendto failed");
+- exit(4);
+- }
++ fail_fatal("sendto failed", 4);
+
+ recv_size = recvfrom(sock, response, sizeof(response), MSG_DONTWAIT, NULL, 0);
+ if (recv_size == -1)
+@@ -367,16 +374,18 @@ int send_release_packet(const char* iface, struct dhcp6_packet* packet)
+ else
+ {
+ perror("recvfrom");
++ result = UNSPEC_FAIL;
+ }
+ }
+-
+- int16_t result = parse_packet(response, recv_size);
+- if (result == NOT_REPLY_CODE)
++ else
+ {
+- sleep(1);
+- continue;
++ result = parse_packet(response, recv_size);
++ if (result == NOT_REPLY_CODE)
++ {
++ sleep(1);
++ continue;
++ }
+ }
+-
+ close(sock);
+ return result;
+ }
+--
+2.31.1
+
diff --git a/0006-Fix-coverity-formats-issues-in-blockdata.patch b/0006-Fix-coverity-formats-issues-in-blockdata.patch
new file mode 100644
index 0000000..beb0898
--- /dev/null
+++ b/0006-Fix-coverity-formats-issues-in-blockdata.patch
@@ -0,0 +1,48 @@
+From 3a077065ce846e301b532127ebecdd2771ad75ed Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 16:41:00 +0200
+Subject: [PATCH 06/15] Fix coverity formats issues in blockdata
+
+Error: PRINTF_ARGS (CWE-686): [#def16]
+dnsmasq-2.86test7/src/blockdata.c:56: invalid_type: Argument "blockdata_count * 48UL" to format specifier "%u" was expected to have type "unsigned int" but has type "unsigned long".
+ # 54| {
+ # 55| my_syslog(LOG_INFO, _("pool memory in use %u, max %u, allocated %u"),
+ # 56|-> blockdata_count * sizeof(struct blockdata),
+ # 57| blockdata_hwm * sizeof(struct blockdata),
+ # 58| blockdata_alloced * sizeof(struct blockdata));
+
+Error: PRINTF_ARGS (CWE-686): [#def17]
+dnsmasq-2.86test7/src/blockdata.c:57: invalid_type: Argument "blockdata_hwm * 48UL" to format specifier "%u" was expected to have type "unsigned int" but has type "unsigned long".
+ # 55| my_syslog(LOG_INFO, _("pool memory in use %u, max %u, allocated %u"),
+ # 56| blockdata_count * sizeof(struct blockdata),
+ # 57|-> blockdata_hwm * sizeof(struct blockdata),
+ # 58| blockdata_alloced * sizeof(struct blockdata));
+ # 59| }
+
+Error: PRINTF_ARGS (CWE-686): [#def18]
+dnsmasq-2.86test7/src/blockdata.c:58: invalid_type: Argument "blockdata_alloced * 48UL" to format specifier "%u" was expected to have type "unsigned int" but has type "unsigned long".
+ # 56| blockdata_count * sizeof(struct blockdata),
+ # 57| blockdata_hwm * sizeof(struct blockdata),
+ # 58|-> blockdata_alloced * sizeof(struct blockdata));
+ # 59| }
+ # 60|
+---
+ src/blockdata.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/blockdata.c b/src/blockdata.c
+index f7740b5..0986285 100644
+--- a/src/blockdata.c
++++ b/src/blockdata.c
+@@ -52,7 +52,7 @@ void blockdata_init(void)
+
+ void blockdata_report(void)
+ {
+- my_syslog(LOG_INFO, _("pool memory in use %u, max %u, allocated %u"),
++ my_syslog(LOG_INFO, _("pool memory in use %zu, max %zu, allocated %zu"),
+ blockdata_count * sizeof(struct blockdata),
+ blockdata_hwm * sizeof(struct blockdata),
+ blockdata_alloced * sizeof(struct blockdata));
+--
+2.31.1
+
diff --git a/0007-Retry-dhcp6-ping-on-interrupts.patch b/0007-Retry-dhcp6-ping-on-interrupts.patch
new file mode 100644
index 0000000..1beb806
--- /dev/null
+++ b/0007-Retry-dhcp6-ping-on-interrupts.patch
@@ -0,0 +1,32 @@
+From 467b621fb7da6e1318ac7204325b0adb01b3ff19 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 16:48:50 +0200
+Subject: [PATCH 07/15] Retry dhcp6 ping on interrupts
+
+Error: CHECKED_RETURN (CWE-252): [#def35]
+dnsmasq-2.86test7/src/dhcp6.c:295: check_return: Calling "sendto(dnsmasq_daemon->icmp6fd, &neigh, 24UL, 0, __CONST_SOCKADDR_ARG({.__sockaddr__ = &addr.sa}), 28U)" without checking return value. This library function may fail and return an error code.
+ # 293| break;
+ # 294|
+ # 295|-> sendto(daemon->icmp6fd, &neigh, sizeof(neigh), 0, &addr.sa, sizeof(addr));
+ # 296|
+ # 297| ts.tv_sec = 0;
+---
+ src/dhcp6.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/dhcp6.c b/src/dhcp6.c
+index 2be877f..ae1f5c1 100644
+--- a/src/dhcp6.c
++++ b/src/dhcp6.c
+@@ -292,7 +292,7 @@ void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac, unsi
+ if ((maclen = find_mac(&addr, mac, 0, now)) != 0)
+ break;
+
+- sendto(daemon->icmp6fd, &neigh, sizeof(neigh), 0, &addr.sa, sizeof(addr));
++ while(retry_send(sendto(daemon->icmp6fd, &neigh, sizeof(neigh), 0, &addr.sa, sizeof(addr))));
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = 100000000; /* 100ms */
+--
+2.31.1
+
diff --git a/0008-Fix-coverity-warnings-on-dbus.patch b/0008-Fix-coverity-warnings-on-dbus.patch
new file mode 100644
index 0000000..fd02da5
--- /dev/null
+++ b/0008-Fix-coverity-warnings-on-dbus.patch
@@ -0,0 +1,131 @@
+From bbfdf6a435cbd5f71ae76f962ce86786346589aa Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 17:19:05 +0200
+Subject: [PATCH 08/15] Fix coverity warnings on dbus
+
+Error: CLANG_WARNING: [#def30]
+dnsmasq-2.86test7/src/dbus.c:117:3: warning[deadcode.DeadStores]: Value stored to 'w' is never read
+ # 115| daemon->watches = w;
+ # 116|
+ # 117|-> w = data; /* no warning */
+ # 118| return TRUE;
+ # 119| }
+
+Error: CLANG_WARNING: [#def31]
+dnsmasq-2.86test7/src/dbus.c:137:3: warning[deadcode.DeadStores]: Value stored to 'w' is never read
+ # 135| }
+ # 136|
+ # 137|-> w = data; /* no warning */
+ # 138| }
+ # 139|
+
+Error: CHECKED_RETURN (CWE-252): [#def32]
+dnsmasq-2.86test7/src/dbus.c:146: check_return: Calling "dbus_message_iter_init" without checking return value (as is done elsewhere 4 out of 5 times).
+dnsmasq-2.86test7/src/dbus.c:460: example_checked: Example 1: "dbus_message_iter_init(message, &iter)" has its value checked in "dbus_message_iter_init(message, &iter)".
+dnsmasq-2.86test7/src/dbus.c:573: example_checked: Example 2: "dbus_message_iter_init(message, &iter)" has its value checked in "dbus_message_iter_init(message, &iter)".
+dnsmasq-2.86test7/src/dbus.c:257: example_checked: Example 3: "dbus_message_iter_init(message, &iter)" has its value checked in "dbus_message_iter_init(message, &iter)".
+dnsmasq-2.86test7/src/dbus.c:427: example_checked: Example 4: "dbus_message_iter_init(message, &iter)" has its value checked in "dbus_message_iter_init(message, &iter)".
+ # 144| char *domain;
+ # 145|
+ # 146|-> dbus_message_iter_init(message, &iter);
+ # 147|
+ # 148| mark_servers(SERV_FROM_DBUS);
+
+Error: NEGATIVE_RETURNS (CWE-394): [#def33]
+dnsmasq-2.86test7/src/dbus.c:547: negative_return_fn: Function "parse_hex((char *)hwaddr, dhcp_chaddr, 16, NULL, &hw_type)" returns a negative number.
+dnsmasq-2.86test7/src/dbus.c:547: assign: Assigning: "hw_len" = "parse_hex((char *)hwaddr, dhcp_chaddr, 16, NULL, &hw_type)".
+dnsmasq-2.86test7/src/dbus.c:551: negative_returns: "hw_len" is passed to a parameter that cannot be negative.
+ # 549| hw_type = ARPHRD_ETHER;
+ # 550|
+ # 551|-> lease_set_hwaddr(lease, dhcp_chaddr, clid, hw_len, hw_type,
+ # 552| clid_len, now, 0);
+ # 553| lease_set_expires(lease, expires, now);
+
+Error: CLANG_WARNING: [#def34]
+dnsmasq-2.86test7/src/dbus.c:722:3: warning[deadcode.DeadStores]: Value stored to 'method' is never read
+ # 720| clear_cache_and_reload(dnsmasq_time());
+ # 721|
+ # 722|-> method = user_data; /* no warning */
+ # 723|
+ # 724| /* If no reply or no error, return nothing */
+---
+ src/dbus.c | 21 +++++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/src/dbus.c b/src/dbus.c
+index cbdce9c..d746b9a 100644
+--- a/src/dbus.c
++++ b/src/dbus.c
+@@ -114,7 +114,7 @@ static dbus_bool_t add_watch(DBusWatch *watch, void *data)
+ w->next = daemon->watches;
+ daemon->watches = w;
+
+- w = data; /* no warning */
++ (void)data; /* no warning */
+ return TRUE;
+ }
+
+@@ -134,16 +134,20 @@ static void remove_watch(DBusWatch *watch, void *data)
+ up = &(w->next);
+ }
+
+- w = data; /* no warning */
++ (void)data; /* no warning */
+ }
+
+-static void dbus_read_servers(DBusMessage *message)
++static DBusMessage* dbus_read_servers(DBusMessage *message)
+ {
+ DBusMessageIter iter;
+ union mysockaddr addr, source_addr;
+ char *domain;
+
+- dbus_message_iter_init(message, &iter);
++ if (!dbus_message_iter_init(message, &iter))
++ {
++ return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
++ "Failed to initialize dbus message iter");
++ }
+
+ mark_servers(SERV_FROM_DBUS);
+
+@@ -222,6 +226,7 @@ static void dbus_read_servers(DBusMessage *message)
+
+ /* unlink and free anything still marked. */
+ cleanup_servers();
++ return NULL;
+ }
+
+ #ifdef HAVE_LOOP
+@@ -545,6 +550,10 @@ static DBusMessage *dbus_add_lease(DBusMessage* message)
+ "Invalid IP address '%s'", ipaddr);
+
+ hw_len = parse_hex((char*)hwaddr, dhcp_chaddr, DHCP_CHADDR_MAX, NULL, &hw_type);
++ if (hw_len < 0)
++ return dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
++ "Invalid HW address '%s'", hwaddr);
++
+ if (hw_type == 0 && hw_len != 0)
+ hw_type = ARPHRD_ETHER;
+
+@@ -668,7 +677,7 @@ DBusHandlerResult message_handler(DBusConnection *connection,
+ #endif
+ else if (strcmp(method, "SetServers") == 0)
+ {
+- dbus_read_servers(message);
++ reply = dbus_read_servers(message);
+ new_servers = 1;
+ }
+ else if (strcmp(method, "SetServersEx") == 0)
+@@ -719,7 +728,7 @@ DBusHandlerResult message_handler(DBusConnection *connection,
+ if (clear_cache)
+ clear_cache_and_reload(dnsmasq_time());
+
+- method = user_data; /* no warning */
++ (void)user_data; /* no warning */
+
+ /* If no reply or no error, return nothing */
+ if (!reply)
+--
+2.31.1
+
diff --git a/0009-Address-coverity-issues-detected-in-util.c.patch b/0009-Address-coverity-issues-detected-in-util.c.patch
new file mode 100644
index 0000000..cc075c7
--- /dev/null
+++ b/0009-Address-coverity-issues-detected-in-util.c.patch
@@ -0,0 +1,110 @@
+From 7b975696a7bda5b86fcf168644f177544adb6fe9 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 17:38:26 +0200
+Subject: [PATCH 09/15] Address coverity issues detected in util.c
+
+Error: CLANG_WARNING: [#def163]
+dnsmasq-2.86test7/src/util.c:204:9: warning[deadcode.DeadStores]: Although the value stored to 'rc' is used in the enclosing expression, the value is never actually read from 'rc'
+ # 202| *nomem = 0;
+ # 203|
+ # 204|-> if (!(rc = check_name(in)))
+ # 205| return NULL;
+ # 206|
+
+Error: UNREACHABLE (CWE-561): [#def164]
+dnsmasq-2.86test7/src/util.c:239: unreachable: This code cannot be reached: "if (ret = whine_malloc(strl...".
+ # 237| #endif
+ # 238|
+ # 239|-> if ((ret = whine_malloc(strlen(in)+1)))
+ # 240| strcpy(ret, in);
+ # 241| else if (nomem)
+
+Error: CLANG_WARNING: [#def165]
+dnsmasq-2.86test7/src/util.c:531:2: warning[deadcode.DeadStores]: Value stored to 'p' is never read
+ # 529| p += sprintf(&buf[p], "%um", x);
+ # 530| if ((x = t%60))
+ # 531|-> p += sprintf(&buf[p], "%us", x);
+ # 532| }
+ # 533| }
+
+Error: CPPCHECK_WARNING (CWE-456): [#def166]
+dnsmasq-2.86test7/src/util.c:577: error[uninitvar]: Uninitialized variable: sav
+ # 575| for (j = 0; j < bytes; j++)
+ # 576| {
+ # 577|-> char sav = sav;
+ # 578| if (j < bytes - 1)
+ # 579| {
+
+Error: CLANG_WARNING: [#def167]
+dnsmasq-2.86test7/src/util.c:577:9: warning[core.uninitialized.Assign]: Assigned value is garbage or undefined
+ # 575| for (j = 0; j < bytes; j++)
+ # 576| {
+ # 577|-> char sav = sav;
+ # 578| if (j < bytes - 1)
+ # 579| {
+
+Error: MISSING_RESTORE (CWE-573): [#def168]
+dnsmasq-2.86test7/src/util.c:580: save: Saving non-local "in[(j + 1) * 2]" in local "sav".
+dnsmasq-2.86test7/src/util.c:581: modify: Modifying non-local "in[(j + 1) * 2]".
+dnsmasq-2.86test7/src/util.c:586: end_of_scope: Value of non-local "in[(j + 1) * 2]" that was saved in "sav" is not restored as it was along other paths.
+dnsmasq-2.86test7/src/util.c:592: restore_example: The original value of non-local "in[(j + 1) * 2]" was restored here.
+ # 584| is illegal. */
+ # 585| if (strchr(&in[j*2], '*'))
+ # 586|-> return -1;
+ # 587| out[i] = strtol(&in[j*2], NULL, 16);
+ # 588| mask = mask << 1;
+---
+ src/util.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/src/util.c b/src/util.c
+index 1425764..8e69d55 100644
+--- a/src/util.c
++++ b/src/util.c
+@@ -208,6 +208,8 @@ char *canonicalise(char *in, int *nomem)
+ /* older libidn2 strips underscores, so don't do IDN processing
+ if the name has an underscore (check_name() returned 2) */
+ if (rc != 2)
++#else
++ (void)rc;
+ #endif
+ #if defined(HAVE_IDN) || defined(HAVE_LIBIDN2)
+ {
+@@ -235,11 +237,14 @@ char *canonicalise(char *in, int *nomem)
+ return ret;
+ }
+ #endif
+-
++
++#if !defined(HAVE_LIBIDN2) || (defined(HAVE_LIBIDN2) && (!defined(IDN2_VERSION_NUMBER) || IDN2_VERSION_NUMBER < 0x02000003))
++ /* If recent libidn2 is used, it cannot reach this code. */
+ if ((ret = whine_malloc(strlen(in)+1)))
+ strcpy(ret, in);
+ else if (nomem)
+- *nomem = 1;
++ *nomem = 1;
++#endif
+
+ return ret;
+ }
+@@ -528,7 +533,7 @@ void prettyprint_time(char *buf, unsigned int t)
+ if ((x = (t/60)%60))
+ p += sprintf(&buf[p], "%um", x);
+ if ((x = t%60))
+- p += sprintf(&buf[p], "%us", x);
++ sprintf(&buf[p], "%us", x);
+ }
+ }
+
+@@ -574,7 +579,7 @@ int parse_hex(char *in, unsigned char *out, int maxlen,
+ int j, bytes = (1 + (r - in))/2;
+ for (j = 0; j < bytes; j++)
+ {
+- char sav = sav;
++ char sav;
+ if (j < bytes - 1)
+ {
+ sav = in[(j+1)*2];
+--
+2.31.1
+
diff --git a/0010-Fix-coverity-detected-issues-in-option.c.patch b/0010-Fix-coverity-detected-issues-in-option.c.patch
new file mode 100644
index 0000000..a63ac41
--- /dev/null
+++ b/0010-Fix-coverity-detected-issues-in-option.c.patch
@@ -0,0 +1,236 @@
+From db835f8c40e83c6392e69ffc7f2cc500f7682dd4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 19:23:20 +0200
+Subject: [PATCH 10/15] Fix coverity detected issues in option.c
+
+Error: STRING_OVERFLOW (CWE-120): [#def99]
+dnsmasq-2.86test7/src/option.c:801: fixed_size_dest: You might overrun the 100-character fixed-size string "buff" by copying "usage[i].arg" without checking the length.
+# 799| if (usage[i].arg)
+# 800| {
+# 801|-> strcpy(buff, usage[i].arg);
+# 802| for (j = 0; tab[j].handle; j++)
+# 803| if (tab[j].handle == *(usage[i].arg))
+
+Error: CLANG_WARNING: [#def100]
+dnsmasq-2.86test7/src/option.c:962:3: warning[deadcode.DeadStores]: Value stored to 'domain' is never read
+# 960| }
+# 961|
+# 962|-> domain += sprintf(domain, "in-addr.arpa");
+# 963|
+# 964| return 1;
+
+Error: CLANG_WARNING: [#def101]
+dnsmasq-2.86test7/src/option.c:981:3: warning[deadcode.DeadStores]: Value stored to 'domain' is never read
+# 979| domain += sprintf(domain, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
+# 980| }
+# 981|-> domain += sprintf(domain, "ip6.arpa");
+# 982|
+# 983| return 1;
+
+Error: RESOURCE_LEAK (CWE-772): [#def102] [important]
+dnsmasq-2.86test7/src/option.c:1809: alloc_fn: Storage is returned from allocation function "opt_malloc".
+dnsmasq-2.86test7/src/option.c:1809: var_assign: Assigning: "path" = storage returned from "opt_malloc(strlen(directory) + len + 2UL)".
+dnsmasq-2.86test7/src/option.c:1810: noescape: Resource "path" is not freed or pointed-to in "strcpy". [Note: The source code implementation of the function has been overridden by a builtin model.]
+dnsmasq-2.86test7/src/option.c:1811: noescape: Resource "path" is not freed or pointed-to in "strcat". [Note: The source code implementation of the function has been overridden by a builtin model.]
+dnsmasq-2.86test7/src/option.c:1812: noescape: Resource "path" is not freed or pointed-to in "strcat". [Note: The source code implementation of the function has been overridden by a builtin model.]
+dnsmasq-2.86test7/src/option.c:1815: noescape: Resource "path" is not freed or pointed-to in "stat".
+dnsmasq-2.86test7/src/option.c:1809: overwrite_var: Overwriting "path" in "path = opt_malloc(strlen(directory) + len + 2UL)" leaks the storage that "path" points to.
+# 1807| continue;
+# 1808|
+# 1809|-> path = opt_malloc(strlen(directory) + len + 2);
+# 1810| strcpy(path, directory);
+# 1811| strcat(path, "/");
+
+Error: RESOURCE_LEAK (CWE-772): [#def103] [important]
+dnsmasq-2.86test7/src/option.c:1809: alloc_fn: Storage is returned from allocation function "opt_malloc".
+dnsmasq-2.86test7/src/option.c:1809: var_assign: Assigning: "path" = storage returned from "opt_malloc(strlen(directory) + len + 2UL)".
+dnsmasq-2.86test7/src/option.c:1810: noescape: Resource "path" is not freed or pointed-to in "strcpy". [Note: The source code implementation of the function has been overridden by a builtin model.]
+dnsmasq-2.86test7/src/option.c:1811: noescape: Resource "path" is not freed or pointed-to in "strcat". [Note: The source code implementation of the function has been overridden by a builtin model.]
+dnsmasq-2.86test7/src/option.c:1812: noescape: Resource "path" is not freed or pointed-to in "strcat". [Note: The source code implementation of the function has been overridden by a builtin model.]
+dnsmasq-2.86test7/src/option.c:1815: noescape: Resource "path" is not freed or pointed-to in "stat".
+dnsmasq-2.86test7/src/option.c:1858: leaked_storage: Variable "path" going out of scope leaks the storage it points to.
+# 1856| free(files);
+# 1857| }
+# 1858|-> break;
+# 1859| }
+# 1860|
+
+Error: RESOURCE_LEAK (CWE-772): [#def104] [important]
+dnsmasq-2.86test7/src/option.c:1996: alloc_fn: Storage is returned from allocation function "canonicalise_opt".
+dnsmasq-2.86test7/src/option.c:1996: var_assign: Assigning: "name" = storage returned from "canonicalise_opt(arg)".
+dnsmasq-2.86test7/src/option.c:1998: leaked_storage: Variable "name" going out of scope leaks the storage it points to.
+# 1996| if (!(name = canonicalise_opt(arg)) ||
+# 1997| (comma && !(target = canonicalise_opt(comma))))
+# 1998|-> ret_err(_("bad MX name"));
+# 1999|
+# 2000| new = opt_malloc(sizeof(struct mx_srv_record));
+
+Error: RESOURCE_LEAK (CWE-772): [#def106] [important]
+dnsmasq-2.86test7/src/option.c:3477: alloc_fn: Storage is returned from allocation function "opt_malloc".
+dnsmasq-2.86test7/src/option.c:3477: var_assign: Assigning: "new" = storage returned from "opt_malloc(96UL)".
+dnsmasq-2.86test7/src/option.c:3618: leaked_storage: Variable "new" going out of scope leaks the storage it points to.
+# 3616| sprintf(errstr, _("duplicate dhcp-host IP address %s"),
+# 3617| daemon->addrbuff);
+# 3618|-> return 0;
+# 3619| }
+# 3620| }
+
+Error: RESOURCE_LEAK (CWE-772): [#def108] [important]
+dnsmasq-2.86test7/src/option.c:3781: alloc_fn: Storage is returned from allocation function "opt_malloc".
+dnsmasq-2.86test7/src/option.c:3781: var_assign: Assigning: "new" = storage returned from "opt_malloc(32UL)".
+dnsmasq-2.86test7/src/option.c:3786: leaked_storage: Variable "new" going out of scope leaks the storage it points to.
+# 3784|
+# 3785| if (!(comma = split(arg)) || (len = strlen(comma)) == 0)
+# 3786|-> ret_err(gen_err);
+# 3787|
+# 3788| new->wildcard = 0;
+
+Error: RESOURCE_LEAK (CWE-772): [#def109] [important]
+dnsmasq-2.86test7/src/option.c:3921: alloc_fn: Storage is returned from allocation function "opt_malloc".
+dnsmasq-2.86test7/src/option.c:3921: var_assign: Assigning: "new" = storage returned from "opt_malloc(56UL)".
+dnsmasq-2.86test7/src/option.c:3994: leaked_storage: Variable "new" going out of scope leaks the storage it points to.
+# 3992| }
+# 3993|
+# 3994|-> ret_err(gen_err);
+# 3995| }
+# 3996|
+
+Error: CLANG_WARNING: [#def111]
+dnsmasq-2.86test7/src/option.c:4693:25: warning[deadcode.DeadStores]: Value stored to 'tmp' during its initialization is never read
+# 4691| if (!canon)
+# 4692| {
+# 4693|-> struct name_list *tmp = new->names, *next;
+# 4694| for (tmp = new->names; tmp; tmp = next)
+# 4695|
+---
+ src/option.c | 33 +++++++++++++++++++++------------
+ 1 file changed, 21 insertions(+), 12 deletions(-)
+
+diff --git a/src/option.c b/src/option.c
+index ffce9fc..11655fd 100644
+--- a/src/option.c
++++ b/src/option.c
+@@ -798,7 +798,7 @@ static void do_usage(void)
+
+ if (usage[i].arg)
+ {
+- strcpy(buff, usage[i].arg);
++ safe_strncpy(buff, usage[i].arg, sizeof(buff));
+ for (j = 0; tab[j].handle; j++)
+ if (tab[j].handle == *(usage[i].arg))
+ sprintf(buff, "%d", tab[j].val);
+@@ -959,7 +959,7 @@ static int domain_rev4(char *domain, struct in_addr addr, int msize)
+ return 0;
+ }
+
+- domain += sprintf(domain, "in-addr.arpa");
++ sprintf(domain, "in-addr.arpa");
+
+ return 1;
+ }
+@@ -978,7 +978,7 @@ static int domain_rev6(char *domain, struct in6_addr *addr, int msize)
+ int dig = ((unsigned char *)addr)[i>>3];
+ domain += sprintf(domain, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
+ }
+- domain += sprintf(domain, "ip6.arpa");
++ sprintf(domain, "ip6.arpa");
+
+ return 1;
+ }
+@@ -1829,6 +1829,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
+ new->next = li;
+ *up = new;
+ }
++ else
++ free(path);
+
+ }
+
+@@ -1995,7 +1997,11 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
+
+ if (!(name = canonicalise_opt(arg)) ||
+ (comma && !(target = canonicalise_opt(comma))))
+- ret_err(_("bad MX name"));
++ {
++ free(name);
++ free(target);
++ ret_err(_("bad MX name"));
++ }
+
+ new = opt_malloc(sizeof(struct mx_srv_record));
+ new->next = daemon->mxnames;
+@@ -3616,6 +3622,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
+ inet_ntop(AF_INET, &in, daemon->addrbuff, ADDRSTRLEN);
+ sprintf(errstr, _("duplicate dhcp-host IP address %s"),
+ daemon->addrbuff);
++ dhcp_config_free(new);
+ return 0;
+ }
+ }
+@@ -3779,16 +3786,16 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
+
+ case LOPT_NAME_MATCH: /* --dhcp-name-match */
+ {
+- struct dhcp_match_name *new = opt_malloc(sizeof(struct dhcp_match_name));
+- struct dhcp_netid *id = opt_malloc(sizeof(struct dhcp_netid));
++ struct dhcp_match_name *new;
+ ssize_t len;
+
+ if (!(comma = split(arg)) || (len = strlen(comma)) == 0)
+ ret_err(gen_err);
+
++ new = opt_malloc(sizeof(struct dhcp_match_name));
+ new->wildcard = 0;
+- new->netid = id;
+- id->net = opt_string_alloc(set_prefix(arg));
++ new->netid = opt_malloc(sizeof(struct dhcp_netid));
++ new->netid->net = opt_string_alloc(set_prefix(arg));
+
+ if (comma[len-1] == '*')
+ {
+@@ -3992,6 +3999,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
+ }
+ }
+
++ dhcp_netid_free(new->netid);
++ free(new);
+ ret_err(gen_err);
+ }
+
+@@ -4367,7 +4376,7 @@ err:
+ case LOPT_CNAME: /* --cname */
+ {
+ struct cname *new;
+- char *alias, *target, *last, *pen;
++ char *alias, *target=NULL, *last, *pen;
+ int ttl = -1;
+
+ for (last = pen = NULL, comma = arg; comma; comma = split(comma))
+@@ -4382,13 +4391,13 @@ err:
+ if (pen != arg && atoi_check(last, &ttl))
+ last = pen;
+
+- target = canonicalise_opt(last);
+-
+ while (arg != last)
+ {
+ int arglen = strlen(arg);
+ alias = canonicalise_opt(arg);
+
++ if (!target)
++ target = canonicalise_opt(last);
+ if (!alias || !target)
+ {
+ free(target);
+@@ -4691,7 +4700,7 @@ err:
+ struct name_list *nl;
+ if (!canon)
+ {
+- struct name_list *tmp = new->names, *next;
++ struct name_list *tmp, *next;
+ for (tmp = new->names; tmp; tmp = next)
+ {
+ next = tmp->next;
+--
+2.31.1
+
diff --git a/0011-Fix-coverity-detected-issue-in-radv.c.patch b/0011-Fix-coverity-detected-issue-in-radv.c.patch
new file mode 100644
index 0000000..845de43
--- /dev/null
+++ b/0011-Fix-coverity-detected-issue-in-radv.c.patch
@@ -0,0 +1,54 @@
+From 9c088b29dcdb8a3e013120d8272a6e0314a8f3df Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 19:29:23 +0200
+Subject: [PATCH 11/15] Fix coverity detected issue in radv.c
+
+Error: NULL_RETURNS (CWE-476): [#def114]
+dnsmasq-2.86test7/src/radv.c:748: returned_null: "expand" returns "NULL" (checked 10 out of 11 times).
+dnsmasq-2.86test7/src/radv.c:748: var_assigned: Assigning: "p" = "NULL" return value from "expand".
+dnsmasq-2.86test7/src/radv.c:749: dereference: Dereferencing a pointer that might be "NULL" "p" when calling "memset". [Note: The source code implementation of the function has been overridden by a builtin model.]
+dnsmasq-2.86test7/src/outpacket.c:83: example_checked: Example 1: "expand(len)" has its value checked in "p = expand(len)".
+dnsmasq-2.86test7/src/outpacket.c:109: example_checked: Example 2: "expand(1UL)" has its value checked in "p = expand(1UL)".
+dnsmasq-2.86test7/src/radv.c:269: example_checked: Example 3: "expand(16UL)" has its value checked in "ra = expand(16UL)".
+dnsmasq-2.86test7/src/radv.c:363: example_checked: Example 4: "expand(32UL)" has its value checked in "opt = expand(32UL)".
+dnsmasq-2.86test7/src/radv.c:708: example_checked: Example 5: "expand(32UL)" has its value checked in "opt = expand(32UL)".
+ # 747| int len = (maclen + 9) >> 3;
+ # 748| unsigned char *p = expand(len << 3);
+ # 749|-> memset(p, 0, len << 3);
+ # 750| *p++ = ICMP6_OPT_SOURCE_MAC;
+ # 751| *p++ = len;
+
+Error: NULL_RETURNS (CWE-476): [#def115]
+dnsmasq-2.86test7/src/radv.c:748: returned_null: "expand" returns "NULL" (checked 10 out of 11 times).
+dnsmasq-2.86test7/src/radv.c:748: var_assigned: Assigning: "p" = "NULL" return value from "expand".
+dnsmasq-2.86test7/src/radv.c:750: dereference: Incrementing a pointer which might be null: "p".
+dnsmasq-2.86test7/src/outpacket.c:83: example_checked: Example 1: "expand(len)" has its value checked in "p = expand(len)".
+dnsmasq-2.86test7/src/outpacket.c:109: example_checked: Example 2: "expand(1UL)" has its value checked in "p = expand(1UL)".
+dnsmasq-2.86test7/src/radv.c:269: example_checked: Example 3: "expand(16UL)" has its value checked in "ra = expand(16UL)".
+dnsmasq-2.86test7/src/radv.c:363: example_checked: Example 4: "expand(32UL)" has its value checked in "opt = expand(32UL)".
+dnsmasq-2.86test7/src/radv.c:708: example_checked: Example 5: "expand(32UL)" has its value checked in "opt = expand(32UL)".
+ # 748| unsigned char *p = expand(len << 3);
+ # 749| memset(p, 0, len << 3);
+ # 750|-> *p++ = ICMP6_OPT_SOURCE_MAC;
+ # 751| *p++ = len;
+ # 752| memcpy(p, mac, maclen);
+---
+ src/radv.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/src/radv.c b/src/radv.c
+index 3255904..6d6fa32 100644
+--- a/src/radv.c
++++ b/src/radv.c
+@@ -746,6 +746,8 @@ static int add_lla(int index, unsigned int type, char *mac, size_t maclen, void
+ add 7 to round up */
+ int len = (maclen + 9) >> 3;
+ unsigned char *p = expand(len << 3);
++ if (!p)
++ return 1;
+ memset(p, 0, len << 3);
+ *p++ = ICMP6_OPT_SOURCE_MAC;
+ *p++ = len;
+--
+2.31.1
+
diff --git a/0012-Fix-coverity-detected-issues-in-cache.c.patch b/0012-Fix-coverity-detected-issues-in-cache.c.patch
new file mode 100644
index 0000000..e88c64a
--- /dev/null
+++ b/0012-Fix-coverity-detected-issues-in-cache.c.patch
@@ -0,0 +1,41 @@
+From 957b2b25238d82a6c3afced2ff0423ad171fb22e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 20:10:37 +0200
+Subject: [PATCH 12/15] Fix coverity detected issues in cache.c
+
+Error: UNINIT (CWE-457): [#def27]
+dnsmasq-2.86test7/src/cache.c:1193: var_decl: Declaring variable "lrec" without initializer.
+dnsmasq-2.86test7/src/cache.c:1315: uninit_use_in_call: Using uninitialized value "lrec.ttd" when calling "make_non_terminals".
+ # 1313| {
+ # 1314| lrec.name.namep = txt->name;
+ # 1315|-> make_non_terminals(&lrec);
+ # 1316| }
+ # 1317|
+
+Error: CLANG_WARNING: [#def29]
+dnsmasq-2.86test7/src/cache.c:1552:15: warning[core.uninitialized.Assign]: Assigned value is garbage or undefined
+ # 1550| {
+ # 1551| crecp->flags = (source->flags | F_NAMEP) & ~(F_IPV4 | F_IPV6 | F_CNAME | F_SRV | F_DNSKEY | F_DS | F_REVERSE);
+ # 1552|-> crecp->ttd = source->ttd;
+ # 1553| crecp->name.namep = name;
+ # 1554|
+---
+ src/cache.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/cache.c b/src/cache.c
+index 97c51a7..6722fa6 100644
+--- a/src/cache.c
++++ b/src/cache.c
+@@ -1188,7 +1188,7 @@ void cache_reload(void)
+ struct host_record *hr;
+ struct name_list *nl;
+ struct cname *a;
+- struct crec lrec;
++ struct crec lrec = { 0, };
+ struct mx_srv_record *mx;
+ struct txt_record *txt;
+ struct interface_name *intr;
+--
+2.31.1
+
diff --git a/0013-Fix-coverity-issues-detected-in-domain-match.c.patch b/0013-Fix-coverity-issues-detected-in-domain-match.c.patch
new file mode 100644
index 0000000..60df62b
--- /dev/null
+++ b/0013-Fix-coverity-issues-detected-in-domain-match.c.patch
@@ -0,0 +1,134 @@
+From 0dafe990a1395d597bc6022c3936769f7a0ddea7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 21:16:22 +0200
+Subject: [PATCH 13/15] Fix coverity issues detected in domain-match.c
+
+Error: CHECKED_RETURN (CWE-252): [#def28]
+dnsmasq-2.86rc3/src/domain-match.c:414: check_return: Calling "add_resource_record" without checking return value (as is done elsewhere 44 out of 46 times).
+dnsmasq-2.86rc3/src/auth.c:214: example_checked: Example 1: "add_resource_record(header, limit, &trunc, nameoffset, &ansp, dnsmasq_daemon->auth_ttl, NULL, 12, 1, "d", intr->name)" has its value checked in "add_resource_record(header, limit, &trunc, nameoffset, &ansp, dnsmasq_daemon->auth_ttl, NULL, 12, 1, "d", intr->name)".
+dnsmasq-2.86rc3/src/auth.c:239: example_checked: Example 2: "add_resource_record(header, limit, &trunc, nameoffset, &ansp, dnsmasq_daemon->auth_ttl, NULL, 12, 1, "d", name)" has its value checked in "add_resource_record(header, limit, &trunc, nameoffset, &ansp, dnsmasq_daemon->auth_ttl, NULL, 12, 1, "d", name)".
+dnsmasq-2.86rc3/src/rfc1035.c:1463: example_checked: Example 3: "add_resource_record(header, limit, &trunc, nameoffset, &ansp, crec_ttl(crecp, now), &nameoffset, 5, 1, "d", cname_target)" has its value checked in "add_resource_record(header, limit, &trunc, nameoffset, &ansp, crec_ttl(crecp, now), &nameoffset, 5, 1, "d", cname_target)".
+dnsmasq-2.86rc3/src/rfc1035.c:1500: example_checked: Example 4: "add_resource_record(header, limit, &trunc, nameoffset, &ansp, ttl, NULL, 16, t->class, "t", t->len, t->txt)" has its value checked in "add_resource_record(header, limit, &trunc, nameoffset, &ansp, ttl, NULL, 16, t->class, "t", t->len, t->txt)".
+dnsmasq-2.86rc3/src/rfc1035.c:2021: example_checked: Example 5: "add_resource_record(header, limit, NULL, rec->offset, &ansp, crec_ttl(crecp, now), NULL, type, 1, ((crecp->flags & 0x80U) ? "4" : "6"), &crecp->addr)" has its value checked in "add_resource_record(header, limit, NULL, rec->offset, &ansp, crec_ttl(crecp, now), NULL, type, 1, ((crecp->flags & 0x80U) ? "4" : "6"), &crecp->addr)".
+ # 412|
+ # 413| header->ancount = htons(ntohs(header->ancount) + 1);
+ # 414|-> add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_A, C_IN, "4", &addr);
+ # 415| log_query((flags | F_CONFIG | F_FORWARD) & ~F_IPV6, name, (union all_addr *)&addr, NULL);
+ # 416| }
+
+Error: CHECKED_RETURN (CWE-252): [#def29]
+dnsmasq-2.86rc3/src/domain-match.c:429: check_return: Calling "add_resource_record" without checking return value (as is done elsewhere 44 out of 46 times).
+dnsmasq-2.86rc3/src/auth.c:214: example_checked: Example 1: "add_resource_record(header, limit, &trunc, nameoffset, &ansp, dnsmasq_daemon->auth_ttl, NULL, 12, 1, "d", intr->name)" has its value checked in "add_resource_record(header, limit, &trunc, nameoffset, &ansp, dnsmasq_daemon->auth_ttl, NULL, 12, 1, "d", intr->name)".
+dnsmasq-2.86rc3/src/auth.c:239: example_checked: Example 2: "add_resource_record(header, limit, &trunc, nameoffset, &ansp, dnsmasq_daemon->auth_ttl, NULL, 12, 1, "d", name)" has its value checked in "add_resource_record(header, limit, &trunc, nameoffset, &ansp, dnsmasq_daemon->auth_ttl, NULL, 12, 1, "d", name)".
+dnsmasq-2.86rc3/src/rfc1035.c:1463: example_checked: Example 3: "add_resource_record(header, limit, &trunc, nameoffset, &ansp, crec_ttl(crecp, now), &nameoffset, 5, 1, "d", cname_target)" has its value checked in "add_resource_record(header, limit, &trunc, nameoffset, &ansp, crec_ttl(crecp, now), &nameoffset, 5, 1, "d", cname_target)".
+dnsmasq-2.86rc3/src/rfc1035.c:1500: example_checked: Example 4: "add_resource_record(header, limit, &trunc, nameoffset, &ansp, ttl, NULL, 16, t->class, "t", t->len, t->txt)" has its value checked in "add_resource_record(header, limit, &trunc, nameoffset, &ansp, ttl, NULL, 16, t->class, "t", t->len, t->txt)".
+dnsmasq-2.86rc3/src/rfc1035.c:2021: example_checked: Example 5: "add_resource_record(header, limit, NULL, rec->offset, &ansp, crec_ttl(crecp, now), NULL, type, 1, ((crecp->flags & 0x80U) ? "4" : "6"), &crecp->addr)" has its value checked in "add_resource_record(header, limit, NULL, rec->offset, &ansp, crec_ttl(crecp, now), NULL, type, 1, ((crecp->flags & 0x80U) ? "4" : "6"), &crecp->addr)".
+ # 427|
+ # 428| header->ancount = htons(ntohs(header->ancount) + 1);
+ # 429|-> add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_AAAA, C_IN, "6", &addr);
+ # 430| log_query((flags | F_CONFIG | F_FORWARD) & ~F_IPV4, name, (union all_addr *)&addr, NULL);
+ # 431| }
+
+Error: NULL_RETURNS (CWE-476): [#def30]
+dnsmasq-2.86rc3/src/domain-match.c:611: returned_null: "whine_malloc" returns "NULL" (checked 72 out of 76 times).
+dnsmasq-2.86rc3/src/domain-match.c:611: var_assigned: Assigning: "alloc_domain" = "NULL" return value from "whine_malloc".
+dnsmasq-2.86rc3/src/domain-match.c:620: dereference: Dereferencing a pointer that might be "NULL" "alloc_domain" when calling "hostname_isequal".
+dnsmasq-2.86rc3/src/arp.c:88: example_checked: Example 1: "whine_malloc(48UL)" has its value checked in "arp = whine_malloc(48UL)".
+dnsmasq-2.86rc3/src/blockdata.c:24: example_assign: Example 2: Assigning: "new" = return value from "whine_malloc(n * 48UL)".
+dnsmasq-2.86rc3/src/blockdata.c:26: example_checked: Example 2 (cont.): "new" has its value checked in "new".
+dnsmasq-2.86rc3/src/cache.c:1545: example_assign: Example 3: Assigning: "crecp" = return value from "whine_malloc(70UL)".
+dnsmasq-2.86rc3/src/cache.c:1547: example_checked: Example 3 (cont.): "crecp" has its value checked in "crecp".
+dnsmasq-2.86rc3/src/forward.c:1791: example_assign: Example 4: Assigning: "packet" = return value from "whine_malloc(66573UL)".
+dnsmasq-2.86rc3/src/forward.c:1795: example_checked: Example 4 (cont.): "packet" has its value checked in "packet".
+dnsmasq-2.86rc3/src/inotify.c:186: example_checked: Example 5: "whine_malloc(lendir + lenfile + 2UL)" has its value checked in "path = whine_malloc(lendir + lenfile + 2UL)".
+ # 618| if (flags & SERV_IS_LOCAL)
+ # 619| for (serv = daemon->servers; serv; serv = serv->next)
+ # 620|-> if ((serv->flags & SERV_MARK) &&
+ # 621| hostname_isequal(alloc_domain, serv->domain))
+ # 622| break;
+
+Error: RESOURCE_LEAK (CWE-772): [#def31] [important]
+dnsmasq-2.86rc3/src/domain-match.c:611: alloc_fn: Storage is returned from allocation function "whine_malloc".
+dnsmasq-2.86rc3/src/domain-match.c:611: var_assign: Assigning: "alloc_domain" = storage returned from "whine_malloc(1UL)".
+dnsmasq-2.86rc3/src/domain-match.c:620: noescape: Resource "alloc_domain" is not freed or pointed-to in "hostname_isequal".
+dnsmasq-2.86rc3/src/domain-match.c:646: leaked_storage: Variable "alloc_domain" going out of scope leaks the storage it points to.
+ # 644|
+ # 645| if (!(serv = whine_malloc(size)))
+ # 646|-> return 0;
+ # 647|
+ # 648| if (flags & SERV_IS_LOCAL)
+
+Error: NULL_RETURNS (CWE-476): [#def32]
+dnsmasq-2.86rc3/src/domain-match.c:611: returned_null: "whine_malloc" returns "NULL" (checked 72 out of 76 times).
+dnsmasq-2.86rc3/src/domain-match.c:611: var_assigned: Assigning: "alloc_domain" = "NULL" return value from "whine_malloc".
+dnsmasq-2.86rc3/src/domain-match.c:674: dereference: Dereferencing a pointer that might be "NULL" "alloc_domain" when calling "strlen".
+dnsmasq-2.86rc3/src/arp.c:88: example_checked: Example 1: "whine_malloc(48UL)" has its value checked in "arp = whine_malloc(48UL)".
+dnsmasq-2.86rc3/src/blockdata.c:24: example_assign: Example 2: Assigning: "new" = return value from "whine_malloc(n * 48UL)".
+dnsmasq-2.86rc3/src/blockdata.c:26: example_checked: Example 2 (cont.): "new" has its value checked in "new".
+dnsmasq-2.86rc3/src/cache.c:1545: example_assign: Example 3: Assigning: "crecp" = return value from "whine_malloc(70UL)".
+dnsmasq-2.86rc3/src/cache.c:1547: example_checked: Example 3 (cont.): "crecp" has its value checked in "crecp".
+dnsmasq-2.86rc3/src/forward.c:1791: example_assign: Example 4: Assigning: "packet" = return value from "whine_malloc(66573UL)".
+dnsmasq-2.86rc3/src/forward.c:1795: example_checked: Example 4 (cont.): "packet" has its value checked in "packet".
+dnsmasq-2.86rc3/src/inotify.c:186: example_checked: Example 5: "whine_malloc(lendir + lenfile + 2UL)" has its value checked in "path = whine_malloc(lendir + lenfile + 2UL)".
+ # 672| serv->flags = flags;
+ # 673| serv->domain = alloc_domain;
+ # 674|-> serv->domain_len = strlen(alloc_domain);
+ # 675|
+ # 676| if (flags & SERV_4ADDR)
+---
+ src/domain-match.c | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/src/domain-match.c b/src/domain-match.c
+index f8e4796..7124c18 100644
+--- a/src/domain-match.c
++++ b/src/domain-match.c
+@@ -411,7 +411,8 @@ size_t make_local_answer(int flags, int gotname, size_t size, struct dns_header
+ addr.addr4 = srv->addr;
+
+ header->ancount = htons(ntohs(header->ancount) + 1);
+- add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_A, C_IN, "4", &addr);
++ if (!add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_A, C_IN, "4", &addr))
++ return 0;
+ log_query((flags | F_CONFIG | F_FORWARD) & ~F_IPV6, name, (union all_addr *)&addr, NULL);
+ }
+
+@@ -426,7 +427,8 @@ size_t make_local_answer(int flags, int gotname, size_t size, struct dns_header
+ addr.addr6 = srv->addr;
+
+ header->ancount = htons(ntohs(header->ancount) + 1);
+- add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_AAAA, C_IN, "6", &addr);
++ if (!add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_AAAA, C_IN, "6", &addr))
++ return 0;
+ log_query((flags | F_CONFIG | F_FORWARD) & ~F_IPV4, name, (union all_addr *)&addr, NULL);
+ }
+
+@@ -609,9 +611,11 @@ int add_update_server(int flags,
+
+ if (*domain == 0)
+ alloc_domain = whine_malloc(1);
+- else if (!(alloc_domain = canonicalise((char *)domain, NULL)))
++ else
++ alloc_domain = canonicalise((char *)domain, NULL);
++ 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. */
+@@ -643,7 +647,10 @@ int add_update_server(int flags,
+ size = sizeof(struct server);
+
+ if (!(serv = whine_malloc(size)))
+- return 0;
++ {
++ free(alloc_domain);
++ return 0;
++ }
+
+ if (flags & SERV_IS_LOCAL)
+ {
+--
+2.31.1
+
diff --git a/0014-Fix-coverity-detected-issues-in-dnsmasq.c.patch b/0014-Fix-coverity-detected-issues-in-dnsmasq.c.patch
new file mode 100644
index 0000000..6069244
--- /dev/null
+++ b/0014-Fix-coverity-detected-issues-in-dnsmasq.c.patch
@@ -0,0 +1,133 @@
+From f476acbe3c2830e6ff0c50cc36d364a3f3f4fadb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 22:45:29 +0200
+Subject: [PATCH 14/15] Fix coverity detected issues in dnsmasq.c
+
+Error: DEADCODE (CWE-561): [#def12]
+dnsmasq-2.86rc3/src/dnsmasq.c:37: assignment: Assigning: "bind_fallback" = "0".
+dnsmasq-2.86rc3/src/dnsmasq.c:927: const: At condition "bind_fallback", the value of "bind_fallback" must be equal to 0.
+dnsmasq-2.86rc3/src/dnsmasq.c:927: dead_error_condition: The condition "bind_fallback" cannot be true.
+dnsmasq-2.86rc3/src/dnsmasq.c:928: dead_error_line: Execution cannot reach this statement: "my_syslog(4, "setting --bin...".
+dnsmasq-2.86rc3/src/dnsmasq.c:928: effectively_constant: Local variable "bind_fallback" is assigned only once, to a constant value, making it effectively constant throughout its scope. If this is not the intent, examine the logic to see if there is a missing assignment that would make "bind_fallback" not remain constant.
+ # 926|
+ # 927| if (bind_fallback)
+ # 928|-> my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
+ # 929|
+ # 930| if (option_bool(OPT_NOWILD))
+
+Error: REVERSE_NEGATIVE (CWE-191): [#def13]
+dnsmasq-2.86rc3/src/dnsmasq.c:383: negative_sink_in_call: Passing "dnsmasq_daemon->pxefd" to a parameter that cannot be negative.
+dnsmasq-2.86rc3/src/dnsmasq.c:1086: check_after_sink: You might be using variable "dnsmasq_daemon->pxefd" before verifying that it is >= 0.
+ # 1084| {
+ # 1085| poll_listen(daemon->dhcpfd, POLLIN);
+ # 1086|-> if (daemon->pxefd != -1)
+ # 1087| poll_listen(daemon->pxefd, POLLIN);
+ # 1088| }
+
+Error: CHECKED_RETURN (CWE-252): [#def18]
+dnsmasq-2.86rc3/src/dnsmasq.c:1582: check_return: Calling "fcntl(dnsmasq_daemon->helperfd, 4, i & 0xfffffffffffff7ff)" without checking return value. This library function may fail and return an error code.
+ # 1580| /* block in writes until all done */
+ # 1581| if ((i = fcntl(daemon->helperfd, F_GETFL)) != -1)
+ # 1582|-> fcntl(daemon->helperfd, F_SETFL, i & ~O_NONBLOCK);
+ # 1583| do {
+ # 1584| helper_write();
+
+Error: CHECKED_RETURN (CWE-252): [#def22]
+dnsmasq-2.86rc3/src/dnsmasq.c:1991: check_return: Calling "fcntl(confd, 4, flags & 0xfffffffffffff7ff)" without checking return value. This library function may fail and return an error code.
+ # 1989| Reset that here. */
+ # 1990| if ((flags = fcntl(confd, F_GETFL, 0)) != -1)
+ # 1991|-> fcntl(confd, F_SETFL, flags & ~O_NONBLOCK);
+ # 1992|
+ # 1993| buff = tcp_request(confd, now, &tcp_addr, netmask, auth_dns);
+
+Error: CHECKED_RETURN (CWE-252): [#def26]
+dnsmasq-2.86rc3/src/dnssec.c:727: check_return: Calling "extract_name" without checking return value (as is done elsewhere 9 out of 10 times).
+dnsmasq-2.86rc3/src/dnssec.c:459: example_checked: Example 1: "extract_name(header, plen, &p, keyname, 1, 0)" has its value checked in "extract_name(header, plen, &p, keyname, 1, 0)".
+dnsmasq-2.86rc3/src/dnssec.c:269: example_checked: Example 2: "extract_name(header, plen, &state->ip, state->buff, 1, 0)" has its value checked in "extract_name(header, plen, &state->ip, state->buff, 1, 0)".
+dnsmasq-2.86rc3/src/dnssec.c:569: example_checked: Example 3: "extract_name(header, plen, &p, keyname, 1, 0)" has its value checked in "extract_name(header, plen, &p, keyname, 1, 0)".
+dnsmasq-2.86rc3/src/rfc1035.c:648: example_checked: Example 4: "extract_name(header, qlen, &p1, name, 1, 0)" has its value checked in "extract_name(header, qlen, &p1, name, 1, 0)".
+dnsmasq-2.86rc3/src/rfc1035.c:787: example_checked: Example 5: "extract_name(header, qlen, &p1, name, 1, 0)" has its value checked in "extract_name(header, qlen, &p1, name, 1, 0)".
+ # 725| /* namebuff used for workspace above, restore to leave unchanged on exit */
+ # 726| p = (unsigned char*)(rrset[0]);
+ # 727|-> extract_name(header, plen, &p, name, 1, 0);
+ # 728|
+ # 729| if (key)
+
+Error: CHECKED_RETURN (CWE-252): [#def27]
+dnsmasq-2.86rc3/src/dnssec.c:1020: check_return: Calling "extract_name" without checking return value (as is done elsewhere 7 out of 8 times).
+dnsmasq-2.86rc3/src/auth.c:140: example_checked: Example 1: "extract_name(header, qlen, &p, name, 1, 4)" has its value checked in "extract_name(header, qlen, &p, name, 1, 4)".
+dnsmasq-2.86rc3/src/dnssec.c:771: example_checked: Example 2: "extract_name(header, plen, &p, name, 1, 4)" has its value checked in "extract_name(header, plen, &p, name, 1, 4)".
+dnsmasq-2.86rc3/src/hash-questions.c:57: example_checked: Example 3: "extract_name(header, plen, &p, name, 1, 4)" has its value checked in "extract_name(header, plen, &p, name, 1, 4)".
+dnsmasq-2.86rc3/src/rfc1035.c:1028: example_checked: Example 4: "extract_name(header, qlen, &p, name, 1, 4)" has its value checked in "extract_name(header, qlen, &p, name, 1, 4)".
+dnsmasq-2.86rc3/src/rfc1035.c:1438: example_checked: Example 5: "extract_name(header, qlen, &p, name, 1, 4)" has its value checked in "extract_name(header, qlen, &p, name, 1, 4)".
+ # 1018|
+ # 1019| p = (unsigned char *)(header+1);
+ # 1020|-> extract_name(header, plen, &p, name, 1, 4);
+ # 1021| p += 4; /* qtype, qclass */
+ # 1022|
+---
+ src/dnsmasq.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/src/dnsmasq.c b/src/dnsmasq.c
+index 602daed..3e1bfe8 100644
+--- a/src/dnsmasq.c
++++ b/src/dnsmasq.c
+@@ -34,7 +34,6 @@ static void poll_resolv(int force, int do_reload, time_t now);
+
+ int main (int argc, char **argv)
+ {
+- int bind_fallback = 0;
+ time_t now;
+ struct sigaction sigact;
+ struct iname *if_tmp;
+@@ -59,6 +58,8 @@ int main (int argc, char **argv)
+ int did_bind = 0;
+ struct server *serv;
+ char *netlink_warn;
++#else
++ int bind_fallback = 0;
+ #endif
+ #if defined(HAVE_DHCP) || defined(HAVE_DHCP6)
+ struct dhcp_context *context;
+@@ -377,7 +378,7 @@ int main (int argc, char **argv)
+ bindtodevice(bound_device, daemon->dhcpfd);
+ did_bind = 1;
+ }
+- if (daemon->enable_pxe && bound_device)
++ if (daemon->enable_pxe && bound_device && daemon->pxefd != -1)
+ {
+ bindtodevice(bound_device, daemon->pxefd);
+ did_bind = 1;
+@@ -920,8 +921,10 @@ int main (int argc, char **argv)
+ my_syslog(LOG_WARNING, _("warning: failed to change owner of %s: %s"),
+ daemon->log_file, strerror(log_err));
+
++#ifndef HAVE_LINUX_NETWORK
+ if (bind_fallback)
+ my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
++#endif
+
+ if (option_bool(OPT_NOWILD))
+ warn_bound_listeners();
+@@ -1575,7 +1578,7 @@ static void async_event(int pipe, time_t now)
+ {
+ /* block in writes until all done */
+ if ((i = fcntl(daemon->helperfd, F_GETFL)) != -1)
+- fcntl(daemon->helperfd, F_SETFL, i & ~O_NONBLOCK);
++ while(retry_send(fcntl(daemon->helperfd, F_SETFL, i & ~O_NONBLOCK)));
+ do {
+ helper_write();
+ } while (!helper_buf_empty() || do_script_run(now));
+@@ -1984,7 +1987,7 @@ static void check_dns_listeners(time_t now)
+ attribute from the listening socket.
+ Reset that here. */
+ if ((flags = fcntl(confd, F_GETFL, 0)) != -1)
+- fcntl(confd, F_SETFL, flags & ~O_NONBLOCK);
++ while(retry_send(fcntl(confd, F_SETFL, flags & ~O_NONBLOCK)));
+
+ buff = tcp_request(confd, now, &tcp_addr, netmask, auth_dns);
+
+--
+2.31.1
+
diff --git a/0015-Fix-coverity-issues-in-dnssec.c.patch b/0015-Fix-coverity-issues-in-dnssec.c.patch
new file mode 100644
index 0000000..67b1d6d
--- /dev/null
+++ b/0015-Fix-coverity-issues-in-dnssec.c.patch
@@ -0,0 +1,62 @@
+From 82c23fb1f0d9e46c6ce4bc4a57f0d377cc6089b7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 22:51:36 +0200
+Subject: [PATCH 15/15] Fix coverity issues in dnssec.c
+
+Error: CHECKED_RETURN (CWE-252): [#def26]
+dnsmasq-2.86rc3/src/dnssec.c:727: check_return: Calling "extract_name" without checking return value (as is done elsewhere 9 out of 10 times).
+dnsmasq-2.86rc3/src/dnssec.c:459: example_checked: Example 1: "extract_name(header, plen, &p, keyname, 1, 0)" has its value checked in "extract_name(header, plen, &p, keyname, 1, 0)".
+dnsmasq-2.86rc3/src/dnssec.c:269: example_checked: Example 2: "extract_name(header, plen, &state->ip, state->buff, 1, 0)" has its value checked in "extract_name(header, plen, &state->ip, state->buff, 1, 0)".
+dnsmasq-2.86rc3/src/dnssec.c:569: example_checked: Example 3: "extract_name(header, plen, &p, keyname, 1, 0)" has its value checked in "extract_name(header, plen, &p, keyname, 1, 0)".
+dnsmasq-2.86rc3/src/rfc1035.c:648: example_checked: Example 4: "extract_name(header, qlen, &p1, name, 1, 0)" has its value checked in "extract_name(header, qlen, &p1, name, 1, 0)".
+dnsmasq-2.86rc3/src/rfc1035.c:787: example_checked: Example 5: "extract_name(header, qlen, &p1, name, 1, 0)" has its value checked in "extract_name(header, qlen, &p1, name, 1, 0)".
+ # 725| /* namebuff used for workspace above, restore to leave unchanged on exit */
+ # 726| p = (unsigned char*)(rrset[0]);
+ # 727|-> extract_name(header, plen, &p, name, 1, 0);
+ # 728|
+ # 729| if (key)
+
+Error: CHECKED_RETURN (CWE-252): [#def27]
+dnsmasq-2.86rc3/src/dnssec.c:1020: check_return: Calling "extract_name" without checking return value (as is done elsewhere 7 out of 8 times).
+dnsmasq-2.86rc3/src/auth.c:140: example_checked: Example 1: "extract_name(header, qlen, &p, name, 1, 4)" has its value checked in "extract_name(header, qlen, &p, name, 1, 4)".
+dnsmasq-2.86rc3/src/dnssec.c:771: example_checked: Example 2: "extract_name(header, plen, &p, name, 1, 4)" has its value checked in "extract_name(header, plen, &p, name, 1, 4)".
+dnsmasq-2.86rc3/src/hash-questions.c:57: example_checked: Example 3: "extract_name(header, plen, &p, name, 1, 4)" has its value checked in "extract_name(header, plen, &p, name, 1, 4)".
+dnsmasq-2.86rc3/src/rfc1035.c:1028: example_checked: Example 4: "extract_name(header, qlen, &p, name, 1, 4)" has its value checked in "extract_name(header, qlen, &p, name, 1, 4)".
+dnsmasq-2.86rc3/src/rfc1035.c:1438: example_checked: Example 5: "extract_name(header, qlen, &p, name, 1, 4)" has its value checked in "extract_name(header, qlen, &p, name, 1, 4)".
+ # 1018|
+ # 1019| p = (unsigned char *)(header+1);
+ # 1020|-> extract_name(header, plen, &p, name, 1, 4);
+ # 1021| p += 4; /* qtype, qclass */
+ # 1022|
+---
+ src/dnssec.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/src/dnssec.c b/src/dnssec.c
+index 94ebb6f..8800a5b 100644
+--- a/src/dnssec.c
++++ b/src/dnssec.c
+@@ -724,7 +724,8 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
+
+ /* namebuff used for workspace above, restore to leave unchanged on exit */
+ p = (unsigned char*)(rrset[0]);
+- extract_name(header, plen, &p, name, 1, 0);
++ if (!extract_name(header, plen, &p, name, 1, 0))
++ return STAT_BOGUS;
+
+ if (key)
+ {
+@@ -1017,7 +1018,9 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
+ }
+
+ p = (unsigned char *)(header+1);
+- extract_name(header, plen, &p, name, 1, 4);
++ if (!extract_name(header, plen, &p, name, 1, 4))
++ return STAT_BOGUS;
++
+ p += 4; /* qtype, qclass */
+
+ /* If the key needed to validate the DS is on the same domain as the DS, we'll
+--
+2.31.1
+
diff --git a/dnsmasq.spec b/dnsmasq.spec
index 7e74130..3af1202 100644
--- a/dnsmasq.spec
+++ b/dnsmasq.spec
@@ -41,8 +41,24 @@ 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=1978718
-Patch4: dnsmasq-2.85-lease-hostname.patch
+
+Patch10: 0001-Retry-on-interrupted-error-in-tftp.patch
+Patch11: 0002-Add-safety-checks-to-places-pointed-by-Coverity.patch
+Patch12: 0003-Small-safeguard-to-unexpected-data.patch
+Patch13: 0004-Fix-bunch-of-warnings-in-auth.c.patch
+Patch14: 0005-Fix-few-coverity-warnings-in-lease-tools.patch
+Patch15: 0006-Fix-coverity-formats-issues-in-blockdata.patch
+Patch16: 0007-Retry-dhcp6-ping-on-interrupts.patch
+Patch17: 0008-Fix-coverity-warnings-on-dbus.patch
+Patch18: 0009-Address-coverity-issues-detected-in-util.c.patch
+Patch19: 0010-Fix-coverity-detected-issues-in-option.c.patch
+Patch20: 0011-Fix-coverity-detected-issue-in-radv.c.patch
+Patch21: 0012-Fix-coverity-detected-issues-in-cache.c.patch
+Patch22: 0013-Fix-coverity-issues-detected-in-domain-match.c.patch
+Patch23: 0014-Fix-coverity-detected-issues-in-dnsmasq.c.patch
+Patch24: 0015-Fix-coverity-issues-in-dnssec.c.patch
+
+
Requires: nettle
https://src.fedoraproject.org/rpms/dnsmasq/c/06b5c95b058e4985a844a72bfc98...
2 years, 9 months
pemensik pushed to dnsmasq (f34). "Add coverity patches (..more)"
by notifications@fedoraproject.org
Notification time stamped 2021-09-09 08:26:39 UTC
From 682b4a82c275ad242fb38bfd2358dc4a55f85bbb Mon Sep 17 00:00:00 2001
From: Petr Menšík <pemensik(a)redhat.com>
Date: Sep 09 2021 08:24:31 +0000
Subject: Add coverity patches
Various coverity fixes, not yet sent to upstream.
---
diff --git a/0001-Retry-on-interrupted-error-in-tftp.patch b/0001-Retry-on-interrupted-error-in-tftp.patch
new file mode 100644
index 0000000..f486f2d
--- /dev/null
+++ b/0001-Retry-on-interrupted-error-in-tftp.patch
@@ -0,0 +1,35 @@
+From f5f56c001dddd486859dc6301e6cbe00ba604fe8 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Wed, 18 Aug 2021 10:09:35 +0200
+Subject: [PATCH 01/15] Retry on interrupted error in tftp
+
+Interrupt might arrive when sending error reply. Retry if possible.
+
+Wrong Check of Return Value
+
+10. dnsmasq-2.85/src/tftp.c:603: check_return: Calling "sendto(transfer->sockfd, dnsmasq_daemon->packet, len, 0, __CONST_SOCKADDR_ARG({.__sockaddr__ = &peer.sa}), sa_len(&peer))" without checking return value. This library function may fail and return an error code.
+ # 601| prettyprint_addr(&peer, daemon->addrbuff);
+ # 602| len = tftp_err(ERR_TID, daemon->packet, _("ignoring packet from %s (TID mismatch)"), daemon->addrbuff);
+ # 603|-> sendto(transfer->sockfd, daemon->packet, len, 0, &peer.sa, sa_len(&peer));
+ # 604| }
+ # 605| }
+---
+ src/tftp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/tftp.c b/src/tftp.c
+index 37bdff2..3d87523 100644
+--- a/src/tftp.c
++++ b/src/tftp.c
+@@ -600,7 +600,7 @@ void check_tftp_listeners(time_t now)
+ /* Wrong source address. See rfc1350 para 4. */
+ prettyprint_addr(&peer, daemon->addrbuff);
+ len = tftp_err(ERR_TID, daemon->packet, _("ignoring packet from %s (TID mismatch)"), daemon->addrbuff);
+- sendto(transfer->sockfd, daemon->packet, len, 0, &peer.sa, sa_len(&peer));
++ while(retry_send(sendto(transfer->sockfd, daemon->packet, len, 0, &peer.sa, sa_len(&peer))));
+ }
+ }
+ }
+--
+2.31.1
+
diff --git a/0002-Add-safety-checks-to-places-pointed-by-Coverity.patch b/0002-Add-safety-checks-to-places-pointed-by-Coverity.patch
new file mode 100644
index 0000000..8fc70a5
--- /dev/null
+++ b/0002-Add-safety-checks-to-places-pointed-by-Coverity.patch
@@ -0,0 +1,77 @@
+From 061013293ceddce509ae06a31a045e803103f1ce Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Wed, 18 Aug 2021 14:59:23 +0200
+Subject: [PATCH 02/15] Add safety checks to places pointed by Coverity
+
+GCC Analyzer (experimental)
+
+1. dnsmasq-2.85/src/forward.c:0: scope_hint: In function 'allocate_rfd.part.0'
+2. dnsmasq-2.85/src/forward.c:2321:18: warning[-Wanalyzer-null-dereference]: dereference of NULL 'rfd'
+ # 2319| *fdlp = rfl;
+ # 2320|
+ # 2321|-> return rfl->rfd->fd;
+ # 2322| }
+ # 2323|
+
+1. dnsmasq-2.85/src/cache.c:0: scope_hint: In function 'log_query'
+2. dnsmasq-2.85/src/cache.c:1969:20: warning[-Wanalyzer-null-dereference]: dereference of NULL 'name'
+ # 1967| source = "cached";
+ # 1968|
+ # 1969|-> if (strlen(name) == 0)
+ # 1970| name = ".";
+ # 1971|
+
+1. dnsmasq-2.85/src/cache.c:0: scope_hint: In function 'cache_scan_free'
+2. dnsmasq-2.85/src/cache.c:436:20: warning[-Wanalyzer-null-argument]: use of NULL 'addr' where non-null expected
+40. /usr/include/sys/un.h:37: included_from: Included from here.
+41. dnsmasq-2.85/src/dnsmasq.h:101: included_from: Included from here.
+42. dnsmasq-2.85/src/cache.c:17: included_from: Included from here.
+43. /usr/include/string.h:64:12: note: argument 2 of 'memcmp' must be non-null
+ # 434| (flags & crecp->flags & F_REVERSE) &&
+ # 435| (flags & crecp->flags & (F_IPV4 | F_IPV6)) &&
+ # 436|-> memcmp(&crecp->addr, addr, addrlen) == 0)
+ # 437| {
+ # 438| *up = crecp->hash_next;
+---
+ src/cache.c | 4 ++--
+ src/forward.c | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/src/cache.c b/src/cache.c
+index 8add610..97c51a7 100644
+--- a/src/cache.c
++++ b/src/cache.c
+@@ -433,7 +433,7 @@ static struct crec *cache_scan_free(char *name, union all_addr *addr, unsigned s
+ else if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) &&
+ (flags & crecp->flags & F_REVERSE) &&
+ (flags & crecp->flags & (F_IPV4 | F_IPV6)) &&
+- memcmp(&crecp->addr, addr, addrlen) == 0)
++ addr && memcmp(&crecp->addr, addr, addrlen) == 0)
+ {
+ *up = crecp->hash_next;
+ cache_unlink(crecp);
+@@ -2013,7 +2013,7 @@ void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg)
+ else
+ source = "cached";
+
+- if (strlen(name) == 0)
++ if (name && !name[0])
+ name = ".";
+
+ if (option_bool(OPT_EXTRALOG))
+diff --git a/src/forward.c b/src/forward.c
+index 3d638e4..f07c908 100644
+--- a/src/forward.c
++++ b/src/forward.c
+@@ -2276,7 +2276,7 @@ int allocate_rfd(struct randfd_list **fdlp, struct server *serv)
+ }
+ }
+
+- if (j == daemon->numrrand)
++ if (!rfd) /* should be when j == daemon->numrrand */
+ {
+ struct randfd_list *rfl_poll;
+
+--
+2.31.1
+
diff --git a/0003-Small-safeguard-to-unexpected-data.patch b/0003-Small-safeguard-to-unexpected-data.patch
new file mode 100644
index 0000000..c496640
--- /dev/null
+++ b/0003-Small-safeguard-to-unexpected-data.patch
@@ -0,0 +1,28 @@
+From 920cd815bafea084f68cc4309399aea77bd7f66b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 14:11:42 +0200
+Subject: [PATCH 03/15] Small safeguard to unexpected data
+
+Make sure negative index is not used for comparison. It seems code in
+option parsing does not allow it to be empty, but insist on it also in
+this place.
+---
+ src/dhcp-common.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/dhcp-common.c b/src/dhcp-common.c
+index 73568a9..85b269a 100644
+--- a/src/dhcp-common.c
++++ b/src/dhcp-common.c
+@@ -88,7 +88,7 @@ int match_netid_wild(struct dhcp_netid *check, struct dhcp_netid *pool)
+ for (; check; check = check->next)
+ {
+ const int check_len = strlen(check->net);
+- const int is_wc = (check->net[check_len - 1] == '*');
++ const int is_wc = (check_len > 0 && check->net[check_len - 1] == '*');
+
+ /* '#' for not is for backwards compat. */
+ if (check->net[0] != '!' && check->net[0] != '#')
+--
+2.31.1
+
diff --git a/0004-Fix-bunch-of-warnings-in-auth.c.patch b/0004-Fix-bunch-of-warnings-in-auth.c.patch
new file mode 100644
index 0000000..976255f
--- /dev/null
+++ b/0004-Fix-bunch-of-warnings-in-auth.c.patch
@@ -0,0 +1,153 @@
+From e61af561900b4d2dd976a575b2efd388be092742 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 16:00:35 +0200
+Subject: [PATCH 04/15] Fix bunch of warnings in auth.c
+
+Error: CLANG_WARNING: [#def7]
+dnsmasq-2.86test7/src/auth.c:420:5: warning[deadcode.DeadStores]: Value stored to 'found' is never read
+ # 418| if (!found && is_name_synthetic(flag, name, &addr) )
+ # 419| {
+ # 420|-> found = 1;
+ # 421| nxdomain = 0;
+ # 422|
+
+Error: CLANG_WARNING: [#def8]
+dnsmasq-2.86test7/src/auth.c:436:8: warning[deadcode.DeadStores]: Value stored to 'found' is never read
+ # 434| {
+ # 435| auth = soa = 1; /* inhibits auth section */
+ # 436|-> found = 1;
+ # 437| log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<SOA>");
+ # 438| }
+
+Error: CLANG_WARNING: [#def9]
+dnsmasq-2.86test7/src/auth.c:472:8: warning[deadcode.DeadStores]: Value stored to 'found' is never read
+ # 470| ns = 1; /* ensure we include NS records! */
+ # 471| axfr = 1;
+ # 472|-> found = 1;
+ # 473| axfroffset = nameoffset;
+ # 474| log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<AXFR>");
+
+Error: CLANG_WARNING: [#def10]
+dnsmasq-2.86test7/src/auth.c:480:8: warning[deadcode.DeadStores]: Value stored to 'found' is never read
+ # 478| auth = 1;
+ # 479| ns = 1; /* inhibits auth section */
+ # 480|-> found = 1;
+ # 481| log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<NS>");
+ # 482| }
+
+Error: CLANG_WARNING: [#def11]
+dnsmasq-2.86test7/src/auth.c:501:4: warning[deadcode.DeadStores]: Value stored to 'found' is never read
+ # 499| log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid));
+ # 500| *cut = 0; /* remove domain part */
+ # 501|-> found = 1;
+ # 502| if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+ # 503| daemon->auth_ttl, NULL, qtype, C_IN,
+
+Error: CLANG_WARNING: [#def12]
+dnsmasq-2.86test7/src/auth.c:522:8: warning[deadcode.DeadStores]: Value stored to 'found' is never read
+ # 520| {
+ # 521| log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid));
+ # 522|-> found = 1;
+ # 523| if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+ # 524| daemon->auth_ttl, NULL, qtype, C_IN,
+
+Error: CLANG_WARNING: [#def13]
+dnsmasq-2.86test7/src/auth.c:617:8: warning[deadcode.DeadStores]: Value stored to 'p' is never read
+ # 615| p += sprintf(p, "%u.", a & 0xff);
+ # 616| a = a >> 8;
+ # 617|-> p += sprintf(p, "%u.in-addr.arpa", a & 0xff);
+ # 618|
+ # 619| }
+
+Error: CPPCHECK_WARNING (CWE-758): [#def14]
+dnsmasq-2.86test7/src/auth.c:627: warning[objectIndex]: The address of local variable 'addr6' might be accessed at non-zero index.
+ # 625| for (i = subnet->prefixlen-1; i >= 0; i -= 4)
+ # 626| {
+ # 627|-> int dig = ((unsigned char *)&subnet->addr.addr6)[i>>3];
+ # 628| p += sprintf(p, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
+ # 629| }
+
+Error: CLANG_WARNING: [#def15]
+dnsmasq-2.86test7/src/auth.c:630:8: warning[deadcode.DeadStores]: Value stored to 'p' is never read
+ # 628| p += sprintf(p, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
+ # 629| }
+ # 630|-> p += sprintf(p, "ip6.arpa");
+ # 631|
+ # 632| }
+---
+ src/auth.c | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+diff --git a/src/auth.c b/src/auth.c
+index 172a4b2..4f03c39 100644
+--- a/src/auth.c
++++ b/src/auth.c
+@@ -417,7 +417,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+
+ if (!found && is_name_synthetic(flag, name, &addr) )
+ {
+- found = 1;
+ nxdomain = 0;
+
+ log_query(F_FORWARD | F_CONFIG | flag, name, &addr, NULL);
+@@ -433,7 +432,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ if (qtype == T_SOA)
+ {
+ auth = soa = 1; /* inhibits auth section */
+- found = 1;
+ log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<SOA>");
+ }
+ else if (qtype == T_AXFR)
+@@ -469,7 +467,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ soa = 1; /* inhibits auth section */
+ ns = 1; /* ensure we include NS records! */
+ axfr = 1;
+- found = 1;
+ axfroffset = nameoffset;
+ log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<AXFR>");
+ }
+@@ -477,7 +474,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ {
+ auth = 1;
+ ns = 1; /* inhibits auth section */
+- found = 1;
+ log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<NS>");
+ }
+ }
+@@ -498,7 +494,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ *cut = '.'; /* restore domain part */
+ log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid));
+ *cut = 0; /* remove domain part */
+- found = 1;
+ if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+ daemon->auth_ttl, NULL, qtype, C_IN,
+ qtype == T_A ? "4" : "6", &crecp->addr))
+@@ -519,7 +514,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ if ((crecp->flags & flag) && (local_query || filter_zone(zone, flag, &(crecp->addr))))
+ {
+ log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid));
+- found = 1;
+ if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+ daemon->auth_ttl, NULL, qtype, C_IN,
+ qtype == T_A ? "4" : "6", &crecp->addr))
+@@ -614,7 +608,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ if (subnet->prefixlen >= 16 )
+ p += sprintf(p, "%u.", a & 0xff);
+ a = a >> 8;
+- p += sprintf(p, "%u.in-addr.arpa", a & 0xff);
++ sprintf(p, "%u.in-addr.arpa", a & 0xff);
+
+ }
+ else
+@@ -627,7 +621,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ int dig = ((unsigned char *)&subnet->addr.addr6)[i>>3];
+ p += sprintf(p, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
+ }
+- p += sprintf(p, "ip6.arpa");
++ sprintf(p, "ip6.arpa");
+
+ }
+ }
+--
+2.31.1
+
diff --git a/0005-Fix-few-coverity-warnings-in-lease-tools.patch b/0005-Fix-few-coverity-warnings-in-lease-tools.patch
new file mode 100644
index 0000000..ab24440
--- /dev/null
+++ b/0005-Fix-few-coverity-warnings-in-lease-tools.patch
@@ -0,0 +1,148 @@
+From be7f213066282baeed46cc34223601c462db9cbf Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 16:32:05 +0200
+Subject: [PATCH 05/15] Fix few coverity warnings in lease-tools
+
+Error: UNINIT (CWE-457): [#def2]
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release.c:265: var_decl: Declaring variable "ifr" without initializer.
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release.c:285: uninit_use_in_call: Using uninitialized value "ifr". Field "ifr.ifr_ifru" is uninitialized when calling "setsockopt".
+ # 283| strncpy(ifr.ifr_name, argv[1], sizeof(ifr.ifr_name)-1);
+ # 284| ifr.ifr_name[sizeof(ifr.ifr_name)-1] = '\0';
+ # 285|-> if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) == -1)
+ # 286| {
+ # 287| perror("cannot setup interface");
+
+Error: CHECKED_RETURN (CWE-252): [#def3]
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:346: check_return: Calling "inet_pton" without checking return value (as is done elsewhere 61 out of 72 times).
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:188: example_assign: Example 1: Assigning: "s" = return value from "inet_pton(10, ip, &result.ip)".
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:189: example_checked: Example 1 (cont.): "s" has its value checked in "s <= 0".
+dnsmasq-2.86test7/src/cache.c:1108: example_checked: Example 2: "inet_pton(10, token, &addr)" has its value checked in "inet_pton(10, token, &addr) > 0".
+dnsmasq-2.86test7/src/dbus.c:525: example_checked: Example 3: "inet_pton(2, ipaddr, &addr.addr4)" has its value checked in "inet_pton(2, ipaddr, &addr.addr4)".
+dnsmasq-2.86test7/src/domain.c:138: example_checked: Example 4: "inet_pton(prot, tail, addr)" has its value checked in "inet_pton(prot, tail, addr)".
+dnsmasq-2.86test7/src/lease.c:81: example_checked: Example 5: "inet_pton(10, dnsmasq_daemon->namebuff, &addr.addr6)" has its value checked in "inet_pton(10, dnsmasq_daemon->namebuff, &addr.addr6)".
+ # 344| client_addr.sin6_flowinfo = 0;
+ # 345| client_addr.sin6_scope_id =0;
+ # 346|-> inet_pton(AF_INET6, "::", &client_addr.sin6_addr);
+ # 347| bind(sock, (struct sockaddr*)&client_addr, sizeof(struct sockaddr_in6));
+ # 348| inet_pton(AF_INET6, DHCP6_MULTICAST_ADDRESS, &server_addr.sin6_addr);
+
+Error: CHECKED_RETURN (CWE-252): [#def4]
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:347: check_return: Calling "bind(sock, (struct sockaddr *)&client_addr, 28U)" without checking return value. This library function may fail and return an error code.
+ # 345| client_addr.sin6_scope_id =0;
+ # 346| inet_pton(AF_INET6, "::", &client_addr.sin6_addr);
+ # 347|-> bind(sock, (struct sockaddr*)&client_addr, sizeof(struct sockaddr_in6));
+ # 348| inet_pton(AF_INET6, DHCP6_MULTICAST_ADDRESS, &server_addr.sin6_addr);
+ # 349| server_addr.sin6_port = htons(DHCP6_SERVER_PORT);
+
+Error: CHECKED_RETURN (CWE-252): [#def5]
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:348: check_return: Calling "inet_pton" without checking return value (as is done elsewhere 61 out of 72 times).
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:188: example_assign: Example 1: Assigning: "s" = return value from "inet_pton(10, ip, &result.ip)".
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:189: example_checked: Example 1 (cont.): "s" has its value checked in "s <= 0".
+dnsmasq-2.86test7/src/cache.c:1108: example_checked: Example 2: "inet_pton(10, token, &addr)" has its value checked in "inet_pton(10, token, &addr) > 0".
+dnsmasq-2.86test7/src/dbus.c:525: example_checked: Example 3: "inet_pton(2, ipaddr, &addr.addr4)" has its value checked in "inet_pton(2, ipaddr, &addr.addr4)".
+dnsmasq-2.86test7/src/domain.c:138: example_checked: Example 4: "inet_pton(prot, tail, addr)" has its value checked in "inet_pton(prot, tail, addr)".
+dnsmasq-2.86test7/src/lease.c:81: example_checked: Example 5: "inet_pton(10, dnsmasq_daemon->namebuff, &addr.addr6)" has its value checked in "inet_pton(10, dnsmasq_daemon->namebuff, &addr.addr6)".
+ # 346| inet_pton(AF_INET6, "::", &client_addr.sin6_addr);
+ # 347| bind(sock, (struct sockaddr*)&client_addr, sizeof(struct sockaddr_in6));
+ # 348|-> inet_pton(AF_INET6, DHCP6_MULTICAST_ADDRESS, &server_addr.sin6_addr);
+ # 349| server_addr.sin6_port = htons(DHCP6_SERVER_PORT);
+ # 350| int16_t recv_size = 0;
+
+Error: NEGATIVE_RETURNS (CWE-394): [#def6]
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:360: var_tested_neg: Variable "recv_size" tests negative.
+dnsmasq-2.86test7/contrib/lease-tools/dhcp_release6.c:373: negative_returns: "recv_size" is passed to a parameter that cannot be negative.
+ # 371| }
+ # 372|
+ # 373|-> int16_t result = parse_packet(response, recv_size);
+ # 374| if (result == NOT_REPLY_CODE)
+ # 375| {
+---
+ contrib/lease-tools/dhcp_release.c | 1 +
+ contrib/lease-tools/dhcp_release6.c | 37 ++++++++++++++++++-----------
+ 2 files changed, 24 insertions(+), 14 deletions(-)
+
+diff --git a/contrib/lease-tools/dhcp_release.c b/contrib/lease-tools/dhcp_release.c
+index c1c835b..84f5610 100644
+--- a/contrib/lease-tools/dhcp_release.c
++++ b/contrib/lease-tools/dhcp_release.c
+@@ -280,6 +280,7 @@ int main(int argc, char **argv)
+
+ /* This voodoo fakes up a packet coming from the correct interface, which really matters for
+ a DHCP server */
++ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, argv[1], sizeof(ifr.ifr_name)-1);
+ ifr.ifr_name[sizeof(ifr.ifr_name)-1] = '\0';
+ if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) == -1)
+diff --git a/contrib/lease-tools/dhcp_release6.c b/contrib/lease-tools/dhcp_release6.c
+index d680222..9b3438f 100644
+--- a/contrib/lease-tools/dhcp_release6.c
++++ b/contrib/lease-tools/dhcp_release6.c
+@@ -318,6 +318,12 @@ void usage(const char* arg, FILE* stream)
+ fprintf (stream, "Usage: %s %s\n", arg, usage_string);
+ }
+
++static void fail_fatal(const char *errstr, int exitcode)
++{
++ perror(errstr);
++ exit(exitcode);
++}
++
+ int send_release_packet(const char* iface, struct dhcp6_packet* packet)
+ {
+ struct sockaddr_in6 server_addr, client_addr;
+@@ -343,18 +349,19 @@ int send_release_packet(const char* iface, struct dhcp6_packet* packet)
+ client_addr.sin6_port = htons(DHCP6_CLIENT_PORT);
+ client_addr.sin6_flowinfo = 0;
+ client_addr.sin6_scope_id =0;
+- inet_pton(AF_INET6, "::", &client_addr.sin6_addr);
+- bind(sock, (struct sockaddr*)&client_addr, sizeof(struct sockaddr_in6));
+- inet_pton(AF_INET6, DHCP6_MULTICAST_ADDRESS, &server_addr.sin6_addr);
++ if (inet_pton(AF_INET6, "::", &client_addr.sin6_addr) <= 0)
++ fail_fatal("inet_pton", 5);
++ if (bind(sock, (struct sockaddr*)&client_addr, sizeof(struct sockaddr_in6)) != 0)
++ perror("bind"); /* continue on bind error */
++ if (inet_pton(AF_INET6, DHCP6_MULTICAST_ADDRESS, &server_addr.sin6_addr) <= 0)
++ fail_fatal("inet_pton", 5);
+ server_addr.sin6_port = htons(DHCP6_SERVER_PORT);
+- int16_t recv_size = 0;
++ ssize_t recv_size = 0;
++ int result;
+ for (i = 0; i < 5; i++)
+ {
+ if (sendto(sock, packet->buf, packet->len, 0, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
+- {
+- perror("sendto failed");
+- exit(4);
+- }
++ fail_fatal("sendto failed", 4);
+
+ recv_size = recvfrom(sock, response, sizeof(response), MSG_DONTWAIT, NULL, 0);
+ if (recv_size == -1)
+@@ -367,16 +374,18 @@ int send_release_packet(const char* iface, struct dhcp6_packet* packet)
+ else
+ {
+ perror("recvfrom");
++ result = UNSPEC_FAIL;
+ }
+ }
+-
+- int16_t result = parse_packet(response, recv_size);
+- if (result == NOT_REPLY_CODE)
++ else
+ {
+- sleep(1);
+- continue;
++ result = parse_packet(response, recv_size);
++ if (result == NOT_REPLY_CODE)
++ {
++ sleep(1);
++ continue;
++ }
+ }
+-
+ close(sock);
+ return result;
+ }
+--
+2.31.1
+
diff --git a/0006-Fix-coverity-formats-issues-in-blockdata.patch b/0006-Fix-coverity-formats-issues-in-blockdata.patch
new file mode 100644
index 0000000..beb0898
--- /dev/null
+++ b/0006-Fix-coverity-formats-issues-in-blockdata.patch
@@ -0,0 +1,48 @@
+From 3a077065ce846e301b532127ebecdd2771ad75ed Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 16:41:00 +0200
+Subject: [PATCH 06/15] Fix coverity formats issues in blockdata
+
+Error: PRINTF_ARGS (CWE-686): [#def16]
+dnsmasq-2.86test7/src/blockdata.c:56: invalid_type: Argument "blockdata_count * 48UL" to format specifier "%u" was expected to have type "unsigned int" but has type "unsigned long".
+ # 54| {
+ # 55| my_syslog(LOG_INFO, _("pool memory in use %u, max %u, allocated %u"),
+ # 56|-> blockdata_count * sizeof(struct blockdata),
+ # 57| blockdata_hwm * sizeof(struct blockdata),
+ # 58| blockdata_alloced * sizeof(struct blockdata));
+
+Error: PRINTF_ARGS (CWE-686): [#def17]
+dnsmasq-2.86test7/src/blockdata.c:57: invalid_type: Argument "blockdata_hwm * 48UL" to format specifier "%u" was expected to have type "unsigned int" but has type "unsigned long".
+ # 55| my_syslog(LOG_INFO, _("pool memory in use %u, max %u, allocated %u"),
+ # 56| blockdata_count * sizeof(struct blockdata),
+ # 57|-> blockdata_hwm * sizeof(struct blockdata),
+ # 58| blockdata_alloced * sizeof(struct blockdata));
+ # 59| }
+
+Error: PRINTF_ARGS (CWE-686): [#def18]
+dnsmasq-2.86test7/src/blockdata.c:58: invalid_type: Argument "blockdata_alloced * 48UL" to format specifier "%u" was expected to have type "unsigned int" but has type "unsigned long".
+ # 56| blockdata_count * sizeof(struct blockdata),
+ # 57| blockdata_hwm * sizeof(struct blockdata),
+ # 58|-> blockdata_alloced * sizeof(struct blockdata));
+ # 59| }
+ # 60|
+---
+ src/blockdata.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/blockdata.c b/src/blockdata.c
+index f7740b5..0986285 100644
+--- a/src/blockdata.c
++++ b/src/blockdata.c
+@@ -52,7 +52,7 @@ void blockdata_init(void)
+
+ void blockdata_report(void)
+ {
+- my_syslog(LOG_INFO, _("pool memory in use %u, max %u, allocated %u"),
++ my_syslog(LOG_INFO, _("pool memory in use %zu, max %zu, allocated %zu"),
+ blockdata_count * sizeof(struct blockdata),
+ blockdata_hwm * sizeof(struct blockdata),
+ blockdata_alloced * sizeof(struct blockdata));
+--
+2.31.1
+
diff --git a/0007-Retry-dhcp6-ping-on-interrupts.patch b/0007-Retry-dhcp6-ping-on-interrupts.patch
new file mode 100644
index 0000000..1beb806
--- /dev/null
+++ b/0007-Retry-dhcp6-ping-on-interrupts.patch
@@ -0,0 +1,32 @@
+From 467b621fb7da6e1318ac7204325b0adb01b3ff19 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 16:48:50 +0200
+Subject: [PATCH 07/15] Retry dhcp6 ping on interrupts
+
+Error: CHECKED_RETURN (CWE-252): [#def35]
+dnsmasq-2.86test7/src/dhcp6.c:295: check_return: Calling "sendto(dnsmasq_daemon->icmp6fd, &neigh, 24UL, 0, __CONST_SOCKADDR_ARG({.__sockaddr__ = &addr.sa}), 28U)" without checking return value. This library function may fail and return an error code.
+ # 293| break;
+ # 294|
+ # 295|-> sendto(daemon->icmp6fd, &neigh, sizeof(neigh), 0, &addr.sa, sizeof(addr));
+ # 296|
+ # 297| ts.tv_sec = 0;
+---
+ src/dhcp6.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/dhcp6.c b/src/dhcp6.c
+index 2be877f..ae1f5c1 100644
+--- a/src/dhcp6.c
++++ b/src/dhcp6.c
+@@ -292,7 +292,7 @@ void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac, unsi
+ if ((maclen = find_mac(&addr, mac, 0, now)) != 0)
+ break;
+
+- sendto(daemon->icmp6fd, &neigh, sizeof(neigh), 0, &addr.sa, sizeof(addr));
++ while(retry_send(sendto(daemon->icmp6fd, &neigh, sizeof(neigh), 0, &addr.sa, sizeof(addr))));
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = 100000000; /* 100ms */
+--
+2.31.1
+
diff --git a/0008-Fix-coverity-warnings-on-dbus.patch b/0008-Fix-coverity-warnings-on-dbus.patch
new file mode 100644
index 0000000..fd02da5
--- /dev/null
+++ b/0008-Fix-coverity-warnings-on-dbus.patch
@@ -0,0 +1,131 @@
+From bbfdf6a435cbd5f71ae76f962ce86786346589aa Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 17:19:05 +0200
+Subject: [PATCH 08/15] Fix coverity warnings on dbus
+
+Error: CLANG_WARNING: [#def30]
+dnsmasq-2.86test7/src/dbus.c:117:3: warning[deadcode.DeadStores]: Value stored to 'w' is never read
+ # 115| daemon->watches = w;
+ # 116|
+ # 117|-> w = data; /* no warning */
+ # 118| return TRUE;
+ # 119| }
+
+Error: CLANG_WARNING: [#def31]
+dnsmasq-2.86test7/src/dbus.c:137:3: warning[deadcode.DeadStores]: Value stored to 'w' is never read
+ # 135| }
+ # 136|
+ # 137|-> w = data; /* no warning */
+ # 138| }
+ # 139|
+
+Error: CHECKED_RETURN (CWE-252): [#def32]
+dnsmasq-2.86test7/src/dbus.c:146: check_return: Calling "dbus_message_iter_init" without checking return value (as is done elsewhere 4 out of 5 times).
+dnsmasq-2.86test7/src/dbus.c:460: example_checked: Example 1: "dbus_message_iter_init(message, &iter)" has its value checked in "dbus_message_iter_init(message, &iter)".
+dnsmasq-2.86test7/src/dbus.c:573: example_checked: Example 2: "dbus_message_iter_init(message, &iter)" has its value checked in "dbus_message_iter_init(message, &iter)".
+dnsmasq-2.86test7/src/dbus.c:257: example_checked: Example 3: "dbus_message_iter_init(message, &iter)" has its value checked in "dbus_message_iter_init(message, &iter)".
+dnsmasq-2.86test7/src/dbus.c:427: example_checked: Example 4: "dbus_message_iter_init(message, &iter)" has its value checked in "dbus_message_iter_init(message, &iter)".
+ # 144| char *domain;
+ # 145|
+ # 146|-> dbus_message_iter_init(message, &iter);
+ # 147|
+ # 148| mark_servers(SERV_FROM_DBUS);
+
+Error: NEGATIVE_RETURNS (CWE-394): [#def33]
+dnsmasq-2.86test7/src/dbus.c:547: negative_return_fn: Function "parse_hex((char *)hwaddr, dhcp_chaddr, 16, NULL, &hw_type)" returns a negative number.
+dnsmasq-2.86test7/src/dbus.c:547: assign: Assigning: "hw_len" = "parse_hex((char *)hwaddr, dhcp_chaddr, 16, NULL, &hw_type)".
+dnsmasq-2.86test7/src/dbus.c:551: negative_returns: "hw_len" is passed to a parameter that cannot be negative.
+ # 549| hw_type = ARPHRD_ETHER;
+ # 550|
+ # 551|-> lease_set_hwaddr(lease, dhcp_chaddr, clid, hw_len, hw_type,
+ # 552| clid_len, now, 0);
+ # 553| lease_set_expires(lease, expires, now);
+
+Error: CLANG_WARNING: [#def34]
+dnsmasq-2.86test7/src/dbus.c:722:3: warning[deadcode.DeadStores]: Value stored to 'method' is never read
+ # 720| clear_cache_and_reload(dnsmasq_time());
+ # 721|
+ # 722|-> method = user_data; /* no warning */
+ # 723|
+ # 724| /* If no reply or no error, return nothing */
+---
+ src/dbus.c | 21 +++++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/src/dbus.c b/src/dbus.c
+index cbdce9c..d746b9a 100644
+--- a/src/dbus.c
++++ b/src/dbus.c
+@@ -114,7 +114,7 @@ static dbus_bool_t add_watch(DBusWatch *watch, void *data)
+ w->next = daemon->watches;
+ daemon->watches = w;
+
+- w = data; /* no warning */
++ (void)data; /* no warning */
+ return TRUE;
+ }
+
+@@ -134,16 +134,20 @@ static void remove_watch(DBusWatch *watch, void *data)
+ up = &(w->next);
+ }
+
+- w = data; /* no warning */
++ (void)data; /* no warning */
+ }
+
+-static void dbus_read_servers(DBusMessage *message)
++static DBusMessage* dbus_read_servers(DBusMessage *message)
+ {
+ DBusMessageIter iter;
+ union mysockaddr addr, source_addr;
+ char *domain;
+
+- dbus_message_iter_init(message, &iter);
++ if (!dbus_message_iter_init(message, &iter))
++ {
++ return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
++ "Failed to initialize dbus message iter");
++ }
+
+ mark_servers(SERV_FROM_DBUS);
+
+@@ -222,6 +226,7 @@ static void dbus_read_servers(DBusMessage *message)
+
+ /* unlink and free anything still marked. */
+ cleanup_servers();
++ return NULL;
+ }
+
+ #ifdef HAVE_LOOP
+@@ -545,6 +550,10 @@ static DBusMessage *dbus_add_lease(DBusMessage* message)
+ "Invalid IP address '%s'", ipaddr);
+
+ hw_len = parse_hex((char*)hwaddr, dhcp_chaddr, DHCP_CHADDR_MAX, NULL, &hw_type);
++ if (hw_len < 0)
++ return dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
++ "Invalid HW address '%s'", hwaddr);
++
+ if (hw_type == 0 && hw_len != 0)
+ hw_type = ARPHRD_ETHER;
+
+@@ -668,7 +677,7 @@ DBusHandlerResult message_handler(DBusConnection *connection,
+ #endif
+ else if (strcmp(method, "SetServers") == 0)
+ {
+- dbus_read_servers(message);
++ reply = dbus_read_servers(message);
+ new_servers = 1;
+ }
+ else if (strcmp(method, "SetServersEx") == 0)
+@@ -719,7 +728,7 @@ DBusHandlerResult message_handler(DBusConnection *connection,
+ if (clear_cache)
+ clear_cache_and_reload(dnsmasq_time());
+
+- method = user_data; /* no warning */
++ (void)user_data; /* no warning */
+
+ /* If no reply or no error, return nothing */
+ if (!reply)
+--
+2.31.1
+
diff --git a/0009-Address-coverity-issues-detected-in-util.c.patch b/0009-Address-coverity-issues-detected-in-util.c.patch
new file mode 100644
index 0000000..cc075c7
--- /dev/null
+++ b/0009-Address-coverity-issues-detected-in-util.c.patch
@@ -0,0 +1,110 @@
+From 7b975696a7bda5b86fcf168644f177544adb6fe9 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 17:38:26 +0200
+Subject: [PATCH 09/15] Address coverity issues detected in util.c
+
+Error: CLANG_WARNING: [#def163]
+dnsmasq-2.86test7/src/util.c:204:9: warning[deadcode.DeadStores]: Although the value stored to 'rc' is used in the enclosing expression, the value is never actually read from 'rc'
+ # 202| *nomem = 0;
+ # 203|
+ # 204|-> if (!(rc = check_name(in)))
+ # 205| return NULL;
+ # 206|
+
+Error: UNREACHABLE (CWE-561): [#def164]
+dnsmasq-2.86test7/src/util.c:239: unreachable: This code cannot be reached: "if (ret = whine_malloc(strl...".
+ # 237| #endif
+ # 238|
+ # 239|-> if ((ret = whine_malloc(strlen(in)+1)))
+ # 240| strcpy(ret, in);
+ # 241| else if (nomem)
+
+Error: CLANG_WARNING: [#def165]
+dnsmasq-2.86test7/src/util.c:531:2: warning[deadcode.DeadStores]: Value stored to 'p' is never read
+ # 529| p += sprintf(&buf[p], "%um", x);
+ # 530| if ((x = t%60))
+ # 531|-> p += sprintf(&buf[p], "%us", x);
+ # 532| }
+ # 533| }
+
+Error: CPPCHECK_WARNING (CWE-456): [#def166]
+dnsmasq-2.86test7/src/util.c:577: error[uninitvar]: Uninitialized variable: sav
+ # 575| for (j = 0; j < bytes; j++)
+ # 576| {
+ # 577|-> char sav = sav;
+ # 578| if (j < bytes - 1)
+ # 579| {
+
+Error: CLANG_WARNING: [#def167]
+dnsmasq-2.86test7/src/util.c:577:9: warning[core.uninitialized.Assign]: Assigned value is garbage or undefined
+ # 575| for (j = 0; j < bytes; j++)
+ # 576| {
+ # 577|-> char sav = sav;
+ # 578| if (j < bytes - 1)
+ # 579| {
+
+Error: MISSING_RESTORE (CWE-573): [#def168]
+dnsmasq-2.86test7/src/util.c:580: save: Saving non-local "in[(j + 1) * 2]" in local "sav".
+dnsmasq-2.86test7/src/util.c:581: modify: Modifying non-local "in[(j + 1) * 2]".
+dnsmasq-2.86test7/src/util.c:586: end_of_scope: Value of non-local "in[(j + 1) * 2]" that was saved in "sav" is not restored as it was along other paths.
+dnsmasq-2.86test7/src/util.c:592: restore_example: The original value of non-local "in[(j + 1) * 2]" was restored here.
+ # 584| is illegal. */
+ # 585| if (strchr(&in[j*2], '*'))
+ # 586|-> return -1;
+ # 587| out[i] = strtol(&in[j*2], NULL, 16);
+ # 588| mask = mask << 1;
+---
+ src/util.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/src/util.c b/src/util.c
+index 1425764..8e69d55 100644
+--- a/src/util.c
++++ b/src/util.c
+@@ -208,6 +208,8 @@ char *canonicalise(char *in, int *nomem)
+ /* older libidn2 strips underscores, so don't do IDN processing
+ if the name has an underscore (check_name() returned 2) */
+ if (rc != 2)
++#else
++ (void)rc;
+ #endif
+ #if defined(HAVE_IDN) || defined(HAVE_LIBIDN2)
+ {
+@@ -235,11 +237,14 @@ char *canonicalise(char *in, int *nomem)
+ return ret;
+ }
+ #endif
+-
++
++#if !defined(HAVE_LIBIDN2) || (defined(HAVE_LIBIDN2) && (!defined(IDN2_VERSION_NUMBER) || IDN2_VERSION_NUMBER < 0x02000003))
++ /* If recent libidn2 is used, it cannot reach this code. */
+ if ((ret = whine_malloc(strlen(in)+1)))
+ strcpy(ret, in);
+ else if (nomem)
+- *nomem = 1;
++ *nomem = 1;
++#endif
+
+ return ret;
+ }
+@@ -528,7 +533,7 @@ void prettyprint_time(char *buf, unsigned int t)
+ if ((x = (t/60)%60))
+ p += sprintf(&buf[p], "%um", x);
+ if ((x = t%60))
+- p += sprintf(&buf[p], "%us", x);
++ sprintf(&buf[p], "%us", x);
+ }
+ }
+
+@@ -574,7 +579,7 @@ int parse_hex(char *in, unsigned char *out, int maxlen,
+ int j, bytes = (1 + (r - in))/2;
+ for (j = 0; j < bytes; j++)
+ {
+- char sav = sav;
++ char sav;
+ if (j < bytes - 1)
+ {
+ sav = in[(j+1)*2];
+--
+2.31.1
+
diff --git a/0010-Fix-coverity-detected-issues-in-option.c.patch b/0010-Fix-coverity-detected-issues-in-option.c.patch
new file mode 100644
index 0000000..a63ac41
--- /dev/null
+++ b/0010-Fix-coverity-detected-issues-in-option.c.patch
@@ -0,0 +1,236 @@
+From db835f8c40e83c6392e69ffc7f2cc500f7682dd4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 19:23:20 +0200
+Subject: [PATCH 10/15] Fix coverity detected issues in option.c
+
+Error: STRING_OVERFLOW (CWE-120): [#def99]
+dnsmasq-2.86test7/src/option.c:801: fixed_size_dest: You might overrun the 100-character fixed-size string "buff" by copying "usage[i].arg" without checking the length.
+# 799| if (usage[i].arg)
+# 800| {
+# 801|-> strcpy(buff, usage[i].arg);
+# 802| for (j = 0; tab[j].handle; j++)
+# 803| if (tab[j].handle == *(usage[i].arg))
+
+Error: CLANG_WARNING: [#def100]
+dnsmasq-2.86test7/src/option.c:962:3: warning[deadcode.DeadStores]: Value stored to 'domain' is never read
+# 960| }
+# 961|
+# 962|-> domain += sprintf(domain, "in-addr.arpa");
+# 963|
+# 964| return 1;
+
+Error: CLANG_WARNING: [#def101]
+dnsmasq-2.86test7/src/option.c:981:3: warning[deadcode.DeadStores]: Value stored to 'domain' is never read
+# 979| domain += sprintf(domain, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
+# 980| }
+# 981|-> domain += sprintf(domain, "ip6.arpa");
+# 982|
+# 983| return 1;
+
+Error: RESOURCE_LEAK (CWE-772): [#def102] [important]
+dnsmasq-2.86test7/src/option.c:1809: alloc_fn: Storage is returned from allocation function "opt_malloc".
+dnsmasq-2.86test7/src/option.c:1809: var_assign: Assigning: "path" = storage returned from "opt_malloc(strlen(directory) + len + 2UL)".
+dnsmasq-2.86test7/src/option.c:1810: noescape: Resource "path" is not freed or pointed-to in "strcpy". [Note: The source code implementation of the function has been overridden by a builtin model.]
+dnsmasq-2.86test7/src/option.c:1811: noescape: Resource "path" is not freed or pointed-to in "strcat". [Note: The source code implementation of the function has been overridden by a builtin model.]
+dnsmasq-2.86test7/src/option.c:1812: noescape: Resource "path" is not freed or pointed-to in "strcat". [Note: The source code implementation of the function has been overridden by a builtin model.]
+dnsmasq-2.86test7/src/option.c:1815: noescape: Resource "path" is not freed or pointed-to in "stat".
+dnsmasq-2.86test7/src/option.c:1809: overwrite_var: Overwriting "path" in "path = opt_malloc(strlen(directory) + len + 2UL)" leaks the storage that "path" points to.
+# 1807| continue;
+# 1808|
+# 1809|-> path = opt_malloc(strlen(directory) + len + 2);
+# 1810| strcpy(path, directory);
+# 1811| strcat(path, "/");
+
+Error: RESOURCE_LEAK (CWE-772): [#def103] [important]
+dnsmasq-2.86test7/src/option.c:1809: alloc_fn: Storage is returned from allocation function "opt_malloc".
+dnsmasq-2.86test7/src/option.c:1809: var_assign: Assigning: "path" = storage returned from "opt_malloc(strlen(directory) + len + 2UL)".
+dnsmasq-2.86test7/src/option.c:1810: noescape: Resource "path" is not freed or pointed-to in "strcpy". [Note: The source code implementation of the function has been overridden by a builtin model.]
+dnsmasq-2.86test7/src/option.c:1811: noescape: Resource "path" is not freed or pointed-to in "strcat". [Note: The source code implementation of the function has been overridden by a builtin model.]
+dnsmasq-2.86test7/src/option.c:1812: noescape: Resource "path" is not freed or pointed-to in "strcat". [Note: The source code implementation of the function has been overridden by a builtin model.]
+dnsmasq-2.86test7/src/option.c:1815: noescape: Resource "path" is not freed or pointed-to in "stat".
+dnsmasq-2.86test7/src/option.c:1858: leaked_storage: Variable "path" going out of scope leaks the storage it points to.
+# 1856| free(files);
+# 1857| }
+# 1858|-> break;
+# 1859| }
+# 1860|
+
+Error: RESOURCE_LEAK (CWE-772): [#def104] [important]
+dnsmasq-2.86test7/src/option.c:1996: alloc_fn: Storage is returned from allocation function "canonicalise_opt".
+dnsmasq-2.86test7/src/option.c:1996: var_assign: Assigning: "name" = storage returned from "canonicalise_opt(arg)".
+dnsmasq-2.86test7/src/option.c:1998: leaked_storage: Variable "name" going out of scope leaks the storage it points to.
+# 1996| if (!(name = canonicalise_opt(arg)) ||
+# 1997| (comma && !(target = canonicalise_opt(comma))))
+# 1998|-> ret_err(_("bad MX name"));
+# 1999|
+# 2000| new = opt_malloc(sizeof(struct mx_srv_record));
+
+Error: RESOURCE_LEAK (CWE-772): [#def106] [important]
+dnsmasq-2.86test7/src/option.c:3477: alloc_fn: Storage is returned from allocation function "opt_malloc".
+dnsmasq-2.86test7/src/option.c:3477: var_assign: Assigning: "new" = storage returned from "opt_malloc(96UL)".
+dnsmasq-2.86test7/src/option.c:3618: leaked_storage: Variable "new" going out of scope leaks the storage it points to.
+# 3616| sprintf(errstr, _("duplicate dhcp-host IP address %s"),
+# 3617| daemon->addrbuff);
+# 3618|-> return 0;
+# 3619| }
+# 3620| }
+
+Error: RESOURCE_LEAK (CWE-772): [#def108] [important]
+dnsmasq-2.86test7/src/option.c:3781: alloc_fn: Storage is returned from allocation function "opt_malloc".
+dnsmasq-2.86test7/src/option.c:3781: var_assign: Assigning: "new" = storage returned from "opt_malloc(32UL)".
+dnsmasq-2.86test7/src/option.c:3786: leaked_storage: Variable "new" going out of scope leaks the storage it points to.
+# 3784|
+# 3785| if (!(comma = split(arg)) || (len = strlen(comma)) == 0)
+# 3786|-> ret_err(gen_err);
+# 3787|
+# 3788| new->wildcard = 0;
+
+Error: RESOURCE_LEAK (CWE-772): [#def109] [important]
+dnsmasq-2.86test7/src/option.c:3921: alloc_fn: Storage is returned from allocation function "opt_malloc".
+dnsmasq-2.86test7/src/option.c:3921: var_assign: Assigning: "new" = storage returned from "opt_malloc(56UL)".
+dnsmasq-2.86test7/src/option.c:3994: leaked_storage: Variable "new" going out of scope leaks the storage it points to.
+# 3992| }
+# 3993|
+# 3994|-> ret_err(gen_err);
+# 3995| }
+# 3996|
+
+Error: CLANG_WARNING: [#def111]
+dnsmasq-2.86test7/src/option.c:4693:25: warning[deadcode.DeadStores]: Value stored to 'tmp' during its initialization is never read
+# 4691| if (!canon)
+# 4692| {
+# 4693|-> struct name_list *tmp = new->names, *next;
+# 4694| for (tmp = new->names; tmp; tmp = next)
+# 4695|
+---
+ src/option.c | 33 +++++++++++++++++++++------------
+ 1 file changed, 21 insertions(+), 12 deletions(-)
+
+diff --git a/src/option.c b/src/option.c
+index ffce9fc..11655fd 100644
+--- a/src/option.c
++++ b/src/option.c
+@@ -798,7 +798,7 @@ static void do_usage(void)
+
+ if (usage[i].arg)
+ {
+- strcpy(buff, usage[i].arg);
++ safe_strncpy(buff, usage[i].arg, sizeof(buff));
+ for (j = 0; tab[j].handle; j++)
+ if (tab[j].handle == *(usage[i].arg))
+ sprintf(buff, "%d", tab[j].val);
+@@ -959,7 +959,7 @@ static int domain_rev4(char *domain, struct in_addr addr, int msize)
+ return 0;
+ }
+
+- domain += sprintf(domain, "in-addr.arpa");
++ sprintf(domain, "in-addr.arpa");
+
+ return 1;
+ }
+@@ -978,7 +978,7 @@ static int domain_rev6(char *domain, struct in6_addr *addr, int msize)
+ int dig = ((unsigned char *)addr)[i>>3];
+ domain += sprintf(domain, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
+ }
+- domain += sprintf(domain, "ip6.arpa");
++ sprintf(domain, "ip6.arpa");
+
+ return 1;
+ }
+@@ -1829,6 +1829,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
+ new->next = li;
+ *up = new;
+ }
++ else
++ free(path);
+
+ }
+
+@@ -1995,7 +1997,11 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
+
+ if (!(name = canonicalise_opt(arg)) ||
+ (comma && !(target = canonicalise_opt(comma))))
+- ret_err(_("bad MX name"));
++ {
++ free(name);
++ free(target);
++ ret_err(_("bad MX name"));
++ }
+
+ new = opt_malloc(sizeof(struct mx_srv_record));
+ new->next = daemon->mxnames;
+@@ -3616,6 +3622,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
+ inet_ntop(AF_INET, &in, daemon->addrbuff, ADDRSTRLEN);
+ sprintf(errstr, _("duplicate dhcp-host IP address %s"),
+ daemon->addrbuff);
++ dhcp_config_free(new);
+ return 0;
+ }
+ }
+@@ -3779,16 +3786,16 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
+
+ case LOPT_NAME_MATCH: /* --dhcp-name-match */
+ {
+- struct dhcp_match_name *new = opt_malloc(sizeof(struct dhcp_match_name));
+- struct dhcp_netid *id = opt_malloc(sizeof(struct dhcp_netid));
++ struct dhcp_match_name *new;
+ ssize_t len;
+
+ if (!(comma = split(arg)) || (len = strlen(comma)) == 0)
+ ret_err(gen_err);
+
++ new = opt_malloc(sizeof(struct dhcp_match_name));
+ new->wildcard = 0;
+- new->netid = id;
+- id->net = opt_string_alloc(set_prefix(arg));
++ new->netid = opt_malloc(sizeof(struct dhcp_netid));
++ new->netid->net = opt_string_alloc(set_prefix(arg));
+
+ if (comma[len-1] == '*')
+ {
+@@ -3992,6 +3999,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
+ }
+ }
+
++ dhcp_netid_free(new->netid);
++ free(new);
+ ret_err(gen_err);
+ }
+
+@@ -4367,7 +4376,7 @@ err:
+ case LOPT_CNAME: /* --cname */
+ {
+ struct cname *new;
+- char *alias, *target, *last, *pen;
++ char *alias, *target=NULL, *last, *pen;
+ int ttl = -1;
+
+ for (last = pen = NULL, comma = arg; comma; comma = split(comma))
+@@ -4382,13 +4391,13 @@ err:
+ if (pen != arg && atoi_check(last, &ttl))
+ last = pen;
+
+- target = canonicalise_opt(last);
+-
+ while (arg != last)
+ {
+ int arglen = strlen(arg);
+ alias = canonicalise_opt(arg);
+
++ if (!target)
++ target = canonicalise_opt(last);
+ if (!alias || !target)
+ {
+ free(target);
+@@ -4691,7 +4700,7 @@ err:
+ struct name_list *nl;
+ if (!canon)
+ {
+- struct name_list *tmp = new->names, *next;
++ struct name_list *tmp, *next;
+ for (tmp = new->names; tmp; tmp = next)
+ {
+ next = tmp->next;
+--
+2.31.1
+
diff --git a/0011-Fix-coverity-detected-issue-in-radv.c.patch b/0011-Fix-coverity-detected-issue-in-radv.c.patch
new file mode 100644
index 0000000..845de43
--- /dev/null
+++ b/0011-Fix-coverity-detected-issue-in-radv.c.patch
@@ -0,0 +1,54 @@
+From 9c088b29dcdb8a3e013120d8272a6e0314a8f3df Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 19:29:23 +0200
+Subject: [PATCH 11/15] Fix coverity detected issue in radv.c
+
+Error: NULL_RETURNS (CWE-476): [#def114]
+dnsmasq-2.86test7/src/radv.c:748: returned_null: "expand" returns "NULL" (checked 10 out of 11 times).
+dnsmasq-2.86test7/src/radv.c:748: var_assigned: Assigning: "p" = "NULL" return value from "expand".
+dnsmasq-2.86test7/src/radv.c:749: dereference: Dereferencing a pointer that might be "NULL" "p" when calling "memset". [Note: The source code implementation of the function has been overridden by a builtin model.]
+dnsmasq-2.86test7/src/outpacket.c:83: example_checked: Example 1: "expand(len)" has its value checked in "p = expand(len)".
+dnsmasq-2.86test7/src/outpacket.c:109: example_checked: Example 2: "expand(1UL)" has its value checked in "p = expand(1UL)".
+dnsmasq-2.86test7/src/radv.c:269: example_checked: Example 3: "expand(16UL)" has its value checked in "ra = expand(16UL)".
+dnsmasq-2.86test7/src/radv.c:363: example_checked: Example 4: "expand(32UL)" has its value checked in "opt = expand(32UL)".
+dnsmasq-2.86test7/src/radv.c:708: example_checked: Example 5: "expand(32UL)" has its value checked in "opt = expand(32UL)".
+ # 747| int len = (maclen + 9) >> 3;
+ # 748| unsigned char *p = expand(len << 3);
+ # 749|-> memset(p, 0, len << 3);
+ # 750| *p++ = ICMP6_OPT_SOURCE_MAC;
+ # 751| *p++ = len;
+
+Error: NULL_RETURNS (CWE-476): [#def115]
+dnsmasq-2.86test7/src/radv.c:748: returned_null: "expand" returns "NULL" (checked 10 out of 11 times).
+dnsmasq-2.86test7/src/radv.c:748: var_assigned: Assigning: "p" = "NULL" return value from "expand".
+dnsmasq-2.86test7/src/radv.c:750: dereference: Incrementing a pointer which might be null: "p".
+dnsmasq-2.86test7/src/outpacket.c:83: example_checked: Example 1: "expand(len)" has its value checked in "p = expand(len)".
+dnsmasq-2.86test7/src/outpacket.c:109: example_checked: Example 2: "expand(1UL)" has its value checked in "p = expand(1UL)".
+dnsmasq-2.86test7/src/radv.c:269: example_checked: Example 3: "expand(16UL)" has its value checked in "ra = expand(16UL)".
+dnsmasq-2.86test7/src/radv.c:363: example_checked: Example 4: "expand(32UL)" has its value checked in "opt = expand(32UL)".
+dnsmasq-2.86test7/src/radv.c:708: example_checked: Example 5: "expand(32UL)" has its value checked in "opt = expand(32UL)".
+ # 748| unsigned char *p = expand(len << 3);
+ # 749| memset(p, 0, len << 3);
+ # 750|-> *p++ = ICMP6_OPT_SOURCE_MAC;
+ # 751| *p++ = len;
+ # 752| memcpy(p, mac, maclen);
+---
+ src/radv.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/src/radv.c b/src/radv.c
+index 3255904..6d6fa32 100644
+--- a/src/radv.c
++++ b/src/radv.c
+@@ -746,6 +746,8 @@ static int add_lla(int index, unsigned int type, char *mac, size_t maclen, void
+ add 7 to round up */
+ int len = (maclen + 9) >> 3;
+ unsigned char *p = expand(len << 3);
++ if (!p)
++ return 1;
+ memset(p, 0, len << 3);
+ *p++ = ICMP6_OPT_SOURCE_MAC;
+ *p++ = len;
+--
+2.31.1
+
diff --git a/0012-Fix-coverity-detected-issues-in-cache.c.patch b/0012-Fix-coverity-detected-issues-in-cache.c.patch
new file mode 100644
index 0000000..e88c64a
--- /dev/null
+++ b/0012-Fix-coverity-detected-issues-in-cache.c.patch
@@ -0,0 +1,41 @@
+From 957b2b25238d82a6c3afced2ff0423ad171fb22e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 20:10:37 +0200
+Subject: [PATCH 12/15] Fix coverity detected issues in cache.c
+
+Error: UNINIT (CWE-457): [#def27]
+dnsmasq-2.86test7/src/cache.c:1193: var_decl: Declaring variable "lrec" without initializer.
+dnsmasq-2.86test7/src/cache.c:1315: uninit_use_in_call: Using uninitialized value "lrec.ttd" when calling "make_non_terminals".
+ # 1313| {
+ # 1314| lrec.name.namep = txt->name;
+ # 1315|-> make_non_terminals(&lrec);
+ # 1316| }
+ # 1317|
+
+Error: CLANG_WARNING: [#def29]
+dnsmasq-2.86test7/src/cache.c:1552:15: warning[core.uninitialized.Assign]: Assigned value is garbage or undefined
+ # 1550| {
+ # 1551| crecp->flags = (source->flags | F_NAMEP) & ~(F_IPV4 | F_IPV6 | F_CNAME | F_SRV | F_DNSKEY | F_DS | F_REVERSE);
+ # 1552|-> crecp->ttd = source->ttd;
+ # 1553| crecp->name.namep = name;
+ # 1554|
+---
+ src/cache.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/cache.c b/src/cache.c
+index 97c51a7..6722fa6 100644
+--- a/src/cache.c
++++ b/src/cache.c
+@@ -1188,7 +1188,7 @@ void cache_reload(void)
+ struct host_record *hr;
+ struct name_list *nl;
+ struct cname *a;
+- struct crec lrec;
++ struct crec lrec = { 0, };
+ struct mx_srv_record *mx;
+ struct txt_record *txt;
+ struct interface_name *intr;
+--
+2.31.1
+
diff --git a/0013-Fix-coverity-issues-detected-in-domain-match.c.patch b/0013-Fix-coverity-issues-detected-in-domain-match.c.patch
new file mode 100644
index 0000000..60df62b
--- /dev/null
+++ b/0013-Fix-coverity-issues-detected-in-domain-match.c.patch
@@ -0,0 +1,134 @@
+From 0dafe990a1395d597bc6022c3936769f7a0ddea7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 21:16:22 +0200
+Subject: [PATCH 13/15] Fix coverity issues detected in domain-match.c
+
+Error: CHECKED_RETURN (CWE-252): [#def28]
+dnsmasq-2.86rc3/src/domain-match.c:414: check_return: Calling "add_resource_record" without checking return value (as is done elsewhere 44 out of 46 times).
+dnsmasq-2.86rc3/src/auth.c:214: example_checked: Example 1: "add_resource_record(header, limit, &trunc, nameoffset, &ansp, dnsmasq_daemon->auth_ttl, NULL, 12, 1, "d", intr->name)" has its value checked in "add_resource_record(header, limit, &trunc, nameoffset, &ansp, dnsmasq_daemon->auth_ttl, NULL, 12, 1, "d", intr->name)".
+dnsmasq-2.86rc3/src/auth.c:239: example_checked: Example 2: "add_resource_record(header, limit, &trunc, nameoffset, &ansp, dnsmasq_daemon->auth_ttl, NULL, 12, 1, "d", name)" has its value checked in "add_resource_record(header, limit, &trunc, nameoffset, &ansp, dnsmasq_daemon->auth_ttl, NULL, 12, 1, "d", name)".
+dnsmasq-2.86rc3/src/rfc1035.c:1463: example_checked: Example 3: "add_resource_record(header, limit, &trunc, nameoffset, &ansp, crec_ttl(crecp, now), &nameoffset, 5, 1, "d", cname_target)" has its value checked in "add_resource_record(header, limit, &trunc, nameoffset, &ansp, crec_ttl(crecp, now), &nameoffset, 5, 1, "d", cname_target)".
+dnsmasq-2.86rc3/src/rfc1035.c:1500: example_checked: Example 4: "add_resource_record(header, limit, &trunc, nameoffset, &ansp, ttl, NULL, 16, t->class, "t", t->len, t->txt)" has its value checked in "add_resource_record(header, limit, &trunc, nameoffset, &ansp, ttl, NULL, 16, t->class, "t", t->len, t->txt)".
+dnsmasq-2.86rc3/src/rfc1035.c:2021: example_checked: Example 5: "add_resource_record(header, limit, NULL, rec->offset, &ansp, crec_ttl(crecp, now), NULL, type, 1, ((crecp->flags & 0x80U) ? "4" : "6"), &crecp->addr)" has its value checked in "add_resource_record(header, limit, NULL, rec->offset, &ansp, crec_ttl(crecp, now), NULL, type, 1, ((crecp->flags & 0x80U) ? "4" : "6"), &crecp->addr)".
+ # 412|
+ # 413| header->ancount = htons(ntohs(header->ancount) + 1);
+ # 414|-> add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_A, C_IN, "4", &addr);
+ # 415| log_query((flags | F_CONFIG | F_FORWARD) & ~F_IPV6, name, (union all_addr *)&addr, NULL);
+ # 416| }
+
+Error: CHECKED_RETURN (CWE-252): [#def29]
+dnsmasq-2.86rc3/src/domain-match.c:429: check_return: Calling "add_resource_record" without checking return value (as is done elsewhere 44 out of 46 times).
+dnsmasq-2.86rc3/src/auth.c:214: example_checked: Example 1: "add_resource_record(header, limit, &trunc, nameoffset, &ansp, dnsmasq_daemon->auth_ttl, NULL, 12, 1, "d", intr->name)" has its value checked in "add_resource_record(header, limit, &trunc, nameoffset, &ansp, dnsmasq_daemon->auth_ttl, NULL, 12, 1, "d", intr->name)".
+dnsmasq-2.86rc3/src/auth.c:239: example_checked: Example 2: "add_resource_record(header, limit, &trunc, nameoffset, &ansp, dnsmasq_daemon->auth_ttl, NULL, 12, 1, "d", name)" has its value checked in "add_resource_record(header, limit, &trunc, nameoffset, &ansp, dnsmasq_daemon->auth_ttl, NULL, 12, 1, "d", name)".
+dnsmasq-2.86rc3/src/rfc1035.c:1463: example_checked: Example 3: "add_resource_record(header, limit, &trunc, nameoffset, &ansp, crec_ttl(crecp, now), &nameoffset, 5, 1, "d", cname_target)" has its value checked in "add_resource_record(header, limit, &trunc, nameoffset, &ansp, crec_ttl(crecp, now), &nameoffset, 5, 1, "d", cname_target)".
+dnsmasq-2.86rc3/src/rfc1035.c:1500: example_checked: Example 4: "add_resource_record(header, limit, &trunc, nameoffset, &ansp, ttl, NULL, 16, t->class, "t", t->len, t->txt)" has its value checked in "add_resource_record(header, limit, &trunc, nameoffset, &ansp, ttl, NULL, 16, t->class, "t", t->len, t->txt)".
+dnsmasq-2.86rc3/src/rfc1035.c:2021: example_checked: Example 5: "add_resource_record(header, limit, NULL, rec->offset, &ansp, crec_ttl(crecp, now), NULL, type, 1, ((crecp->flags & 0x80U) ? "4" : "6"), &crecp->addr)" has its value checked in "add_resource_record(header, limit, NULL, rec->offset, &ansp, crec_ttl(crecp, now), NULL, type, 1, ((crecp->flags & 0x80U) ? "4" : "6"), &crecp->addr)".
+ # 427|
+ # 428| header->ancount = htons(ntohs(header->ancount) + 1);
+ # 429|-> add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_AAAA, C_IN, "6", &addr);
+ # 430| log_query((flags | F_CONFIG | F_FORWARD) & ~F_IPV4, name, (union all_addr *)&addr, NULL);
+ # 431| }
+
+Error: NULL_RETURNS (CWE-476): [#def30]
+dnsmasq-2.86rc3/src/domain-match.c:611: returned_null: "whine_malloc" returns "NULL" (checked 72 out of 76 times).
+dnsmasq-2.86rc3/src/domain-match.c:611: var_assigned: Assigning: "alloc_domain" = "NULL" return value from "whine_malloc".
+dnsmasq-2.86rc3/src/domain-match.c:620: dereference: Dereferencing a pointer that might be "NULL" "alloc_domain" when calling "hostname_isequal".
+dnsmasq-2.86rc3/src/arp.c:88: example_checked: Example 1: "whine_malloc(48UL)" has its value checked in "arp = whine_malloc(48UL)".
+dnsmasq-2.86rc3/src/blockdata.c:24: example_assign: Example 2: Assigning: "new" = return value from "whine_malloc(n * 48UL)".
+dnsmasq-2.86rc3/src/blockdata.c:26: example_checked: Example 2 (cont.): "new" has its value checked in "new".
+dnsmasq-2.86rc3/src/cache.c:1545: example_assign: Example 3: Assigning: "crecp" = return value from "whine_malloc(70UL)".
+dnsmasq-2.86rc3/src/cache.c:1547: example_checked: Example 3 (cont.): "crecp" has its value checked in "crecp".
+dnsmasq-2.86rc3/src/forward.c:1791: example_assign: Example 4: Assigning: "packet" = return value from "whine_malloc(66573UL)".
+dnsmasq-2.86rc3/src/forward.c:1795: example_checked: Example 4 (cont.): "packet" has its value checked in "packet".
+dnsmasq-2.86rc3/src/inotify.c:186: example_checked: Example 5: "whine_malloc(lendir + lenfile + 2UL)" has its value checked in "path = whine_malloc(lendir + lenfile + 2UL)".
+ # 618| if (flags & SERV_IS_LOCAL)
+ # 619| for (serv = daemon->servers; serv; serv = serv->next)
+ # 620|-> if ((serv->flags & SERV_MARK) &&
+ # 621| hostname_isequal(alloc_domain, serv->domain))
+ # 622| break;
+
+Error: RESOURCE_LEAK (CWE-772): [#def31] [important]
+dnsmasq-2.86rc3/src/domain-match.c:611: alloc_fn: Storage is returned from allocation function "whine_malloc".
+dnsmasq-2.86rc3/src/domain-match.c:611: var_assign: Assigning: "alloc_domain" = storage returned from "whine_malloc(1UL)".
+dnsmasq-2.86rc3/src/domain-match.c:620: noescape: Resource "alloc_domain" is not freed or pointed-to in "hostname_isequal".
+dnsmasq-2.86rc3/src/domain-match.c:646: leaked_storage: Variable "alloc_domain" going out of scope leaks the storage it points to.
+ # 644|
+ # 645| if (!(serv = whine_malloc(size)))
+ # 646|-> return 0;
+ # 647|
+ # 648| if (flags & SERV_IS_LOCAL)
+
+Error: NULL_RETURNS (CWE-476): [#def32]
+dnsmasq-2.86rc3/src/domain-match.c:611: returned_null: "whine_malloc" returns "NULL" (checked 72 out of 76 times).
+dnsmasq-2.86rc3/src/domain-match.c:611: var_assigned: Assigning: "alloc_domain" = "NULL" return value from "whine_malloc".
+dnsmasq-2.86rc3/src/domain-match.c:674: dereference: Dereferencing a pointer that might be "NULL" "alloc_domain" when calling "strlen".
+dnsmasq-2.86rc3/src/arp.c:88: example_checked: Example 1: "whine_malloc(48UL)" has its value checked in "arp = whine_malloc(48UL)".
+dnsmasq-2.86rc3/src/blockdata.c:24: example_assign: Example 2: Assigning: "new" = return value from "whine_malloc(n * 48UL)".
+dnsmasq-2.86rc3/src/blockdata.c:26: example_checked: Example 2 (cont.): "new" has its value checked in "new".
+dnsmasq-2.86rc3/src/cache.c:1545: example_assign: Example 3: Assigning: "crecp" = return value from "whine_malloc(70UL)".
+dnsmasq-2.86rc3/src/cache.c:1547: example_checked: Example 3 (cont.): "crecp" has its value checked in "crecp".
+dnsmasq-2.86rc3/src/forward.c:1791: example_assign: Example 4: Assigning: "packet" = return value from "whine_malloc(66573UL)".
+dnsmasq-2.86rc3/src/forward.c:1795: example_checked: Example 4 (cont.): "packet" has its value checked in "packet".
+dnsmasq-2.86rc3/src/inotify.c:186: example_checked: Example 5: "whine_malloc(lendir + lenfile + 2UL)" has its value checked in "path = whine_malloc(lendir + lenfile + 2UL)".
+ # 672| serv->flags = flags;
+ # 673| serv->domain = alloc_domain;
+ # 674|-> serv->domain_len = strlen(alloc_domain);
+ # 675|
+ # 676| if (flags & SERV_4ADDR)
+---
+ src/domain-match.c | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/src/domain-match.c b/src/domain-match.c
+index f8e4796..7124c18 100644
+--- a/src/domain-match.c
++++ b/src/domain-match.c
+@@ -411,7 +411,8 @@ size_t make_local_answer(int flags, int gotname, size_t size, struct dns_header
+ addr.addr4 = srv->addr;
+
+ header->ancount = htons(ntohs(header->ancount) + 1);
+- add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_A, C_IN, "4", &addr);
++ if (!add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_A, C_IN, "4", &addr))
++ return 0;
+ log_query((flags | F_CONFIG | F_FORWARD) & ~F_IPV6, name, (union all_addr *)&addr, NULL);
+ }
+
+@@ -426,7 +427,8 @@ size_t make_local_answer(int flags, int gotname, size_t size, struct dns_header
+ addr.addr6 = srv->addr;
+
+ header->ancount = htons(ntohs(header->ancount) + 1);
+- add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_AAAA, C_IN, "6", &addr);
++ if (!add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_AAAA, C_IN, "6", &addr))
++ return 0;
+ log_query((flags | F_CONFIG | F_FORWARD) & ~F_IPV4, name, (union all_addr *)&addr, NULL);
+ }
+
+@@ -609,9 +611,11 @@ int add_update_server(int flags,
+
+ if (*domain == 0)
+ alloc_domain = whine_malloc(1);
+- else if (!(alloc_domain = canonicalise((char *)domain, NULL)))
++ else
++ alloc_domain = canonicalise((char *)domain, NULL);
++ 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. */
+@@ -643,7 +647,10 @@ int add_update_server(int flags,
+ size = sizeof(struct server);
+
+ if (!(serv = whine_malloc(size)))
+- return 0;
++ {
++ free(alloc_domain);
++ return 0;
++ }
+
+ if (flags & SERV_IS_LOCAL)
+ {
+--
+2.31.1
+
diff --git a/0014-Fix-coverity-detected-issues-in-dnsmasq.c.patch b/0014-Fix-coverity-detected-issues-in-dnsmasq.c.patch
new file mode 100644
index 0000000..6069244
--- /dev/null
+++ b/0014-Fix-coverity-detected-issues-in-dnsmasq.c.patch
@@ -0,0 +1,133 @@
+From f476acbe3c2830e6ff0c50cc36d364a3f3f4fadb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 22:45:29 +0200
+Subject: [PATCH 14/15] Fix coverity detected issues in dnsmasq.c
+
+Error: DEADCODE (CWE-561): [#def12]
+dnsmasq-2.86rc3/src/dnsmasq.c:37: assignment: Assigning: "bind_fallback" = "0".
+dnsmasq-2.86rc3/src/dnsmasq.c:927: const: At condition "bind_fallback", the value of "bind_fallback" must be equal to 0.
+dnsmasq-2.86rc3/src/dnsmasq.c:927: dead_error_condition: The condition "bind_fallback" cannot be true.
+dnsmasq-2.86rc3/src/dnsmasq.c:928: dead_error_line: Execution cannot reach this statement: "my_syslog(4, "setting --bin...".
+dnsmasq-2.86rc3/src/dnsmasq.c:928: effectively_constant: Local variable "bind_fallback" is assigned only once, to a constant value, making it effectively constant throughout its scope. If this is not the intent, examine the logic to see if there is a missing assignment that would make "bind_fallback" not remain constant.
+ # 926|
+ # 927| if (bind_fallback)
+ # 928|-> my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
+ # 929|
+ # 930| if (option_bool(OPT_NOWILD))
+
+Error: REVERSE_NEGATIVE (CWE-191): [#def13]
+dnsmasq-2.86rc3/src/dnsmasq.c:383: negative_sink_in_call: Passing "dnsmasq_daemon->pxefd" to a parameter that cannot be negative.
+dnsmasq-2.86rc3/src/dnsmasq.c:1086: check_after_sink: You might be using variable "dnsmasq_daemon->pxefd" before verifying that it is >= 0.
+ # 1084| {
+ # 1085| poll_listen(daemon->dhcpfd, POLLIN);
+ # 1086|-> if (daemon->pxefd != -1)
+ # 1087| poll_listen(daemon->pxefd, POLLIN);
+ # 1088| }
+
+Error: CHECKED_RETURN (CWE-252): [#def18]
+dnsmasq-2.86rc3/src/dnsmasq.c:1582: check_return: Calling "fcntl(dnsmasq_daemon->helperfd, 4, i & 0xfffffffffffff7ff)" without checking return value. This library function may fail and return an error code.
+ # 1580| /* block in writes until all done */
+ # 1581| if ((i = fcntl(daemon->helperfd, F_GETFL)) != -1)
+ # 1582|-> fcntl(daemon->helperfd, F_SETFL, i & ~O_NONBLOCK);
+ # 1583| do {
+ # 1584| helper_write();
+
+Error: CHECKED_RETURN (CWE-252): [#def22]
+dnsmasq-2.86rc3/src/dnsmasq.c:1991: check_return: Calling "fcntl(confd, 4, flags & 0xfffffffffffff7ff)" without checking return value. This library function may fail and return an error code.
+ # 1989| Reset that here. */
+ # 1990| if ((flags = fcntl(confd, F_GETFL, 0)) != -1)
+ # 1991|-> fcntl(confd, F_SETFL, flags & ~O_NONBLOCK);
+ # 1992|
+ # 1993| buff = tcp_request(confd, now, &tcp_addr, netmask, auth_dns);
+
+Error: CHECKED_RETURN (CWE-252): [#def26]
+dnsmasq-2.86rc3/src/dnssec.c:727: check_return: Calling "extract_name" without checking return value (as is done elsewhere 9 out of 10 times).
+dnsmasq-2.86rc3/src/dnssec.c:459: example_checked: Example 1: "extract_name(header, plen, &p, keyname, 1, 0)" has its value checked in "extract_name(header, plen, &p, keyname, 1, 0)".
+dnsmasq-2.86rc3/src/dnssec.c:269: example_checked: Example 2: "extract_name(header, plen, &state->ip, state->buff, 1, 0)" has its value checked in "extract_name(header, plen, &state->ip, state->buff, 1, 0)".
+dnsmasq-2.86rc3/src/dnssec.c:569: example_checked: Example 3: "extract_name(header, plen, &p, keyname, 1, 0)" has its value checked in "extract_name(header, plen, &p, keyname, 1, 0)".
+dnsmasq-2.86rc3/src/rfc1035.c:648: example_checked: Example 4: "extract_name(header, qlen, &p1, name, 1, 0)" has its value checked in "extract_name(header, qlen, &p1, name, 1, 0)".
+dnsmasq-2.86rc3/src/rfc1035.c:787: example_checked: Example 5: "extract_name(header, qlen, &p1, name, 1, 0)" has its value checked in "extract_name(header, qlen, &p1, name, 1, 0)".
+ # 725| /* namebuff used for workspace above, restore to leave unchanged on exit */
+ # 726| p = (unsigned char*)(rrset[0]);
+ # 727|-> extract_name(header, plen, &p, name, 1, 0);
+ # 728|
+ # 729| if (key)
+
+Error: CHECKED_RETURN (CWE-252): [#def27]
+dnsmasq-2.86rc3/src/dnssec.c:1020: check_return: Calling "extract_name" without checking return value (as is done elsewhere 7 out of 8 times).
+dnsmasq-2.86rc3/src/auth.c:140: example_checked: Example 1: "extract_name(header, qlen, &p, name, 1, 4)" has its value checked in "extract_name(header, qlen, &p, name, 1, 4)".
+dnsmasq-2.86rc3/src/dnssec.c:771: example_checked: Example 2: "extract_name(header, plen, &p, name, 1, 4)" has its value checked in "extract_name(header, plen, &p, name, 1, 4)".
+dnsmasq-2.86rc3/src/hash-questions.c:57: example_checked: Example 3: "extract_name(header, plen, &p, name, 1, 4)" has its value checked in "extract_name(header, plen, &p, name, 1, 4)".
+dnsmasq-2.86rc3/src/rfc1035.c:1028: example_checked: Example 4: "extract_name(header, qlen, &p, name, 1, 4)" has its value checked in "extract_name(header, qlen, &p, name, 1, 4)".
+dnsmasq-2.86rc3/src/rfc1035.c:1438: example_checked: Example 5: "extract_name(header, qlen, &p, name, 1, 4)" has its value checked in "extract_name(header, qlen, &p, name, 1, 4)".
+ # 1018|
+ # 1019| p = (unsigned char *)(header+1);
+ # 1020|-> extract_name(header, plen, &p, name, 1, 4);
+ # 1021| p += 4; /* qtype, qclass */
+ # 1022|
+---
+ src/dnsmasq.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/src/dnsmasq.c b/src/dnsmasq.c
+index 602daed..3e1bfe8 100644
+--- a/src/dnsmasq.c
++++ b/src/dnsmasq.c
+@@ -34,7 +34,6 @@ static void poll_resolv(int force, int do_reload, time_t now);
+
+ int main (int argc, char **argv)
+ {
+- int bind_fallback = 0;
+ time_t now;
+ struct sigaction sigact;
+ struct iname *if_tmp;
+@@ -59,6 +58,8 @@ int main (int argc, char **argv)
+ int did_bind = 0;
+ struct server *serv;
+ char *netlink_warn;
++#else
++ int bind_fallback = 0;
+ #endif
+ #if defined(HAVE_DHCP) || defined(HAVE_DHCP6)
+ struct dhcp_context *context;
+@@ -377,7 +378,7 @@ int main (int argc, char **argv)
+ bindtodevice(bound_device, daemon->dhcpfd);
+ did_bind = 1;
+ }
+- if (daemon->enable_pxe && bound_device)
++ if (daemon->enable_pxe && bound_device && daemon->pxefd != -1)
+ {
+ bindtodevice(bound_device, daemon->pxefd);
+ did_bind = 1;
+@@ -920,8 +921,10 @@ int main (int argc, char **argv)
+ my_syslog(LOG_WARNING, _("warning: failed to change owner of %s: %s"),
+ daemon->log_file, strerror(log_err));
+
++#ifndef HAVE_LINUX_NETWORK
+ if (bind_fallback)
+ my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
++#endif
+
+ if (option_bool(OPT_NOWILD))
+ warn_bound_listeners();
+@@ -1575,7 +1578,7 @@ static void async_event(int pipe, time_t now)
+ {
+ /* block in writes until all done */
+ if ((i = fcntl(daemon->helperfd, F_GETFL)) != -1)
+- fcntl(daemon->helperfd, F_SETFL, i & ~O_NONBLOCK);
++ while(retry_send(fcntl(daemon->helperfd, F_SETFL, i & ~O_NONBLOCK)));
+ do {
+ helper_write();
+ } while (!helper_buf_empty() || do_script_run(now));
+@@ -1984,7 +1987,7 @@ static void check_dns_listeners(time_t now)
+ attribute from the listening socket.
+ Reset that here. */
+ if ((flags = fcntl(confd, F_GETFL, 0)) != -1)
+- fcntl(confd, F_SETFL, flags & ~O_NONBLOCK);
++ while(retry_send(fcntl(confd, F_SETFL, flags & ~O_NONBLOCK)));
+
+ buff = tcp_request(confd, now, &tcp_addr, netmask, auth_dns);
+
+--
+2.31.1
+
diff --git a/0015-Fix-coverity-issues-in-dnssec.c.patch b/0015-Fix-coverity-issues-in-dnssec.c.patch
new file mode 100644
index 0000000..67b1d6d
--- /dev/null
+++ b/0015-Fix-coverity-issues-in-dnssec.c.patch
@@ -0,0 +1,62 @@
+From 82c23fb1f0d9e46c6ce4bc4a57f0d377cc6089b7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
+Date: Fri, 3 Sep 2021 22:51:36 +0200
+Subject: [PATCH 15/15] Fix coverity issues in dnssec.c
+
+Error: CHECKED_RETURN (CWE-252): [#def26]
+dnsmasq-2.86rc3/src/dnssec.c:727: check_return: Calling "extract_name" without checking return value (as is done elsewhere 9 out of 10 times).
+dnsmasq-2.86rc3/src/dnssec.c:459: example_checked: Example 1: "extract_name(header, plen, &p, keyname, 1, 0)" has its value checked in "extract_name(header, plen, &p, keyname, 1, 0)".
+dnsmasq-2.86rc3/src/dnssec.c:269: example_checked: Example 2: "extract_name(header, plen, &state->ip, state->buff, 1, 0)" has its value checked in "extract_name(header, plen, &state->ip, state->buff, 1, 0)".
+dnsmasq-2.86rc3/src/dnssec.c:569: example_checked: Example 3: "extract_name(header, plen, &p, keyname, 1, 0)" has its value checked in "extract_name(header, plen, &p, keyname, 1, 0)".
+dnsmasq-2.86rc3/src/rfc1035.c:648: example_checked: Example 4: "extract_name(header, qlen, &p1, name, 1, 0)" has its value checked in "extract_name(header, qlen, &p1, name, 1, 0)".
+dnsmasq-2.86rc3/src/rfc1035.c:787: example_checked: Example 5: "extract_name(header, qlen, &p1, name, 1, 0)" has its value checked in "extract_name(header, qlen, &p1, name, 1, 0)".
+ # 725| /* namebuff used for workspace above, restore to leave unchanged on exit */
+ # 726| p = (unsigned char*)(rrset[0]);
+ # 727|-> extract_name(header, plen, &p, name, 1, 0);
+ # 728|
+ # 729| if (key)
+
+Error: CHECKED_RETURN (CWE-252): [#def27]
+dnsmasq-2.86rc3/src/dnssec.c:1020: check_return: Calling "extract_name" without checking return value (as is done elsewhere 7 out of 8 times).
+dnsmasq-2.86rc3/src/auth.c:140: example_checked: Example 1: "extract_name(header, qlen, &p, name, 1, 4)" has its value checked in "extract_name(header, qlen, &p, name, 1, 4)".
+dnsmasq-2.86rc3/src/dnssec.c:771: example_checked: Example 2: "extract_name(header, plen, &p, name, 1, 4)" has its value checked in "extract_name(header, plen, &p, name, 1, 4)".
+dnsmasq-2.86rc3/src/hash-questions.c:57: example_checked: Example 3: "extract_name(header, plen, &p, name, 1, 4)" has its value checked in "extract_name(header, plen, &p, name, 1, 4)".
+dnsmasq-2.86rc3/src/rfc1035.c:1028: example_checked: Example 4: "extract_name(header, qlen, &p, name, 1, 4)" has its value checked in "extract_name(header, qlen, &p, name, 1, 4)".
+dnsmasq-2.86rc3/src/rfc1035.c:1438: example_checked: Example 5: "extract_name(header, qlen, &p, name, 1, 4)" has its value checked in "extract_name(header, qlen, &p, name, 1, 4)".
+ # 1018|
+ # 1019| p = (unsigned char *)(header+1);
+ # 1020|-> extract_name(header, plen, &p, name, 1, 4);
+ # 1021| p += 4; /* qtype, qclass */
+ # 1022|
+---
+ src/dnssec.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/src/dnssec.c b/src/dnssec.c
+index 94ebb6f..8800a5b 100644
+--- a/src/dnssec.c
++++ b/src/dnssec.c
+@@ -724,7 +724,8 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
+
+ /* namebuff used for workspace above, restore to leave unchanged on exit */
+ p = (unsigned char*)(rrset[0]);
+- extract_name(header, plen, &p, name, 1, 0);
++ if (!extract_name(header, plen, &p, name, 1, 0))
++ return STAT_BOGUS;
+
+ if (key)
+ {
+@@ -1017,7 +1018,9 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
+ }
+
+ p = (unsigned char *)(header+1);
+- extract_name(header, plen, &p, name, 1, 4);
++ if (!extract_name(header, plen, &p, name, 1, 4))
++ return STAT_BOGUS;
++
+ p += 4; /* qtype, qclass */
+
+ /* If the key needed to validate the DS is on the same domain as the DS, we'll
+--
+2.31.1
+
diff --git a/dnsmasq.spec b/dnsmasq.spec
index ccbefb0..3ef217f 100644
--- a/dnsmasq.spec
+++ b/dnsmasq.spec
@@ -41,8 +41,24 @@ 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=1978718
-Patch4: dnsmasq-2.85-lease-hostname.patch
+
+Patch10: 0001-Retry-on-interrupted-error-in-tftp.patch
+Patch11: 0002-Add-safety-checks-to-places-pointed-by-Coverity.patch
+Patch12: 0003-Small-safeguard-to-unexpected-data.patch
+Patch13: 0004-Fix-bunch-of-warnings-in-auth.c.patch
+Patch14: 0005-Fix-few-coverity-warnings-in-lease-tools.patch
+Patch15: 0006-Fix-coverity-formats-issues-in-blockdata.patch
+Patch16: 0007-Retry-dhcp6-ping-on-interrupts.patch
+Patch17: 0008-Fix-coverity-warnings-on-dbus.patch
+Patch18: 0009-Address-coverity-issues-detected-in-util.c.patch
+Patch19: 0010-Fix-coverity-detected-issues-in-option.c.patch
+Patch20: 0011-Fix-coverity-detected-issue-in-radv.c.patch
+Patch21: 0012-Fix-coverity-detected-issues-in-cache.c.patch
+Patch22: 0013-Fix-coverity-issues-detected-in-domain-match.c.patch
+Patch23: 0014-Fix-coverity-detected-issues-in-dnsmasq.c.patch
+Patch24: 0015-Fix-coverity-issues-in-dnssec.c.patch
+
+
Requires: nettle
https://src.fedoraproject.org/rpms/dnsmasq/c/682b4a82c275ad242fb38bfd2358...
2 years, 9 months
pemensik pushed to dnsmasq (rawhide). "Start before nss-lookup.target,
hint modification to listen on IP (#1984618)"
by notifications@fedoraproject.org
Notification time stamped 2021-07-22 19:30:17 UTC
From 97b69aa4f1729856fd925c2a69039d3171cbca6d Mon Sep 17 00:00:00 2001
From: Petr Menšík <pemensik(a)redhat.com>
Date: Jul 22 2021 19:29:28 +0000
Subject: Start before nss-lookup.target, hint modification to listen on IP (#1984618)
---
diff --git a/dnsmasq-2.81-configuration.patch b/dnsmasq-2.81-configuration.patch
index 3b3cadd..f23aa2f 100644
--- a/dnsmasq-2.81-configuration.patch
+++ b/dnsmasq-2.81-configuration.patch
@@ -1,4 +1,4 @@
-From 3a593d133f91c5126105efd03246b3f61f103dd4 Mon Sep 17 00:00:00 2001
+From 194e7521399048e37c5c2cff18b9c8d442b893ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
Date: Tue, 30 Jun 2020 18:06:29 +0200
Subject: [PATCH] Modify upstream configuration to safe defaults
@@ -7,11 +7,11 @@ Most important change would be to listen only on localhost. Default
configuration should not listen to request from remote hosts. Match also
user and paths to directories shipped in Fedora.
---
- dnsmasq.conf.example | 24 +++++++++++++++++++-----
- 1 file changed, 19 insertions(+), 5 deletions(-)
+ dnsmasq.conf.example | 29 ++++++++++++++++++++++++-----
+ 1 file changed, 24 insertions(+), 5 deletions(-)
diff --git a/dnsmasq.conf.example b/dnsmasq.conf.example
-index bf19424..36fba33 100644
+index bf19424..8b85f44 100644
--- a/dnsmasq.conf.example
+++ b/dnsmasq.conf.example
@@ -22,7 +22,7 @@
@@ -53,7 +53,7 @@ index bf19424..36fba33 100644
# On systems which support it, dnsmasq binds the wildcard address,
# even when it is listening on only some interfaces. It then discards
# requests that it shouldn't reply to. This has the advantage of
-@@ -121,7 +127,11 @@
+@@ -121,7 +127,16 @@
# want dnsmasq to really bind only the interfaces it is listening on,
# uncomment this option. About the only time you may need this is when
# running another nameserver on the same machine.
@@ -63,10 +63,15 @@ index bf19424..36fba33 100644
+# interfaces, bind only to lo device. Comment out to bind on single
+# wildcard socket.
+bind-interfaces
++
++# Comment out above line and uncoment following 2 lines.
++# Update interface name, use ip link to get its name.
++#bind-dynamic
++#interface=eno1
# If you don't want dnsmasq to read /etc/hosts, uncomment the
# following line.
-@@ -535,7 +545,7 @@
+@@ -535,7 +550,7 @@
# The DHCP server needs somewhere on disk to keep its lease database.
# This defaults to a sane location, but if you want to change it, use
# the line below.
@@ -75,7 +80,7 @@ index bf19424..36fba33 100644
# Set the DHCP server to authoritative mode. In this mode it will barge in
# and take over the lease for any client which broadcasts on the network,
-@@ -673,7 +683,11 @@
+@@ -673,7 +688,11 @@
# Include all files in a directory which end in .conf
#conf-dir=/etc/dnsmasq.d/,*.conf
@@ -88,5 +93,5 @@ index bf19424..36fba33 100644
#dhcp-ignore-names=tag:wpad-ignore
+
--
-2.26.2
+2.31.1
diff --git a/dnsmasq.service b/dnsmasq.service
index 08faf75..d88c06f 100644
--- a/dnsmasq.service
+++ b/dnsmasq.service
@@ -1,6 +1,10 @@
[Unit]
Description=DNS caching server.
+Before=nss-lookup.target
+Wants=nss-lookup.target
After=network.target
+; Use bind-dynamic or uncomment following to listen on non-local IP address
+;After=network-online.target
[Service]
ExecStart=/usr/sbin/dnsmasq
diff --git a/dnsmasq.spec b/dnsmasq.spec
index 07eede0..6ef1082 100644
--- a/dnsmasq.spec
+++ b/dnsmasq.spec
@@ -20,7 +20,7 @@
Name: dnsmasq
Version: 2.85
-Release: 4%{?extraversion:.%{extraversion}}%{?dist}
+Release: 5%{?extraversion:.%{extraversion}}%{?dist}
Summary: A lightweight DHCP/caching DNS server
License: GPLv2 or GPLv3
@@ -184,6 +184,9 @@ install -Dpm 644 %{SOURCE2} %{buildroot}%{_sysusersdir}/%{name}.conf
%{_mandir}/man1/dhcp_*
%changelog
+* Thu Jul 22 2021 Petr Menšík <pemensik(a)redhat.com> - 2.85-5
+- Start before nss-lookup.target, hint modification to listen on IP (#1984618)
+
* Thu Jul 22 2021 Petr Menšík <pemensik(a)redhat.com> - 2.85-4
- Update lease if hostname is assigned to a new lease (#1978718)
https://src.fedoraproject.org/rpms/dnsmasq/c/97b69aa4f1729856fd925c2a6903...
2 years, 11 months
pemensik pushed to dnsmasq (f34). "Start before nss-lookup.target,
hint modification to listen on IP (#1984618)"
by notifications@fedoraproject.org
Notification time stamped 2021-07-23 10:46:08 UTC
From 313c023c07b2719df0adf695bbd246ec77709633 Mon Sep 17 00:00:00 2001
From: Petr Menšík <pemensik(a)redhat.com>
Date: Jul 23 2021 10:43:47 +0000
Subject: Start before nss-lookup.target, hint modification to listen on IP (#1984618)
---
diff --git a/dnsmasq-2.81-configuration.patch b/dnsmasq-2.81-configuration.patch
index 3b3cadd..f23aa2f 100644
--- a/dnsmasq-2.81-configuration.patch
+++ b/dnsmasq-2.81-configuration.patch
@@ -1,4 +1,4 @@
-From 3a593d133f91c5126105efd03246b3f61f103dd4 Mon Sep 17 00:00:00 2001
+From 194e7521399048e37c5c2cff18b9c8d442b893ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik(a)redhat.com>
Date: Tue, 30 Jun 2020 18:06:29 +0200
Subject: [PATCH] Modify upstream configuration to safe defaults
@@ -7,11 +7,11 @@ Most important change would be to listen only on localhost. Default
configuration should not listen to request from remote hosts. Match also
user and paths to directories shipped in Fedora.
---
- dnsmasq.conf.example | 24 +++++++++++++++++++-----
- 1 file changed, 19 insertions(+), 5 deletions(-)
+ dnsmasq.conf.example | 29 ++++++++++++++++++++++++-----
+ 1 file changed, 24 insertions(+), 5 deletions(-)
diff --git a/dnsmasq.conf.example b/dnsmasq.conf.example
-index bf19424..36fba33 100644
+index bf19424..8b85f44 100644
--- a/dnsmasq.conf.example
+++ b/dnsmasq.conf.example
@@ -22,7 +22,7 @@
@@ -53,7 +53,7 @@ index bf19424..36fba33 100644
# On systems which support it, dnsmasq binds the wildcard address,
# even when it is listening on only some interfaces. It then discards
# requests that it shouldn't reply to. This has the advantage of
-@@ -121,7 +127,11 @@
+@@ -121,7 +127,16 @@
# want dnsmasq to really bind only the interfaces it is listening on,
# uncomment this option. About the only time you may need this is when
# running another nameserver on the same machine.
@@ -63,10 +63,15 @@ index bf19424..36fba33 100644
+# interfaces, bind only to lo device. Comment out to bind on single
+# wildcard socket.
+bind-interfaces
++
++# Comment out above line and uncoment following 2 lines.
++# Update interface name, use ip link to get its name.
++#bind-dynamic
++#interface=eno1
# If you don't want dnsmasq to read /etc/hosts, uncomment the
# following line.
-@@ -535,7 +545,7 @@
+@@ -535,7 +550,7 @@
# The DHCP server needs somewhere on disk to keep its lease database.
# This defaults to a sane location, but if you want to change it, use
# the line below.
@@ -75,7 +80,7 @@ index bf19424..36fba33 100644
# Set the DHCP server to authoritative mode. In this mode it will barge in
# and take over the lease for any client which broadcasts on the network,
-@@ -673,7 +683,11 @@
+@@ -673,7 +688,11 @@
# Include all files in a directory which end in .conf
#conf-dir=/etc/dnsmasq.d/,*.conf
@@ -88,5 +93,5 @@ index bf19424..36fba33 100644
#dhcp-ignore-names=tag:wpad-ignore
+
--
-2.26.2
+2.31.1
diff --git a/dnsmasq.service b/dnsmasq.service
index 08faf75..d88c06f 100644
--- a/dnsmasq.service
+++ b/dnsmasq.service
@@ -1,6 +1,10 @@
[Unit]
Description=DNS caching server.
+Before=nss-lookup.target
+Wants=nss-lookup.target
After=network.target
+; Use bind-dynamic or uncomment following to listen on non-local IP address
+;After=network-online.target
[Service]
ExecStart=/usr/sbin/dnsmasq
diff --git a/dnsmasq.spec b/dnsmasq.spec
index 53805f3..a495e40 100644
--- a/dnsmasq.spec
+++ b/dnsmasq.spec
@@ -20,7 +20,7 @@
Name: dnsmasq
Version: 2.85
-Release: 2%{?extraversion:.%{extraversion}}%{?dist}
+Release: 3%{?extraversion:.%{extraversion}}%{?dist}
Summary: A lightweight DHCP/caching DNS server
License: GPLv2 or GPLv3
@@ -184,6 +184,9 @@ install -Dpm 644 %{SOURCE2} %{buildroot}%{_sysusersdir}/%{name}.conf
%{_mandir}/man1/dhcp_*
%changelog
+* Thu Jul 22 2021 Petr Menšík <pemensik(a)redhat.com> - 2.85-3
+- Start before nss-lookup.target, hint modification to listen on IP (#1984618)
+
* Thu Jul 22 2021 Petr Menšík <pemensik(a)redhat.com> - 2.85-2
- Update lease if hostname is assigned to a new lease (#1978718)
https://src.fedoraproject.org/rpms/dnsmasq/c/313c023c07b2719df0adf695bbd2...
2 years, 11 months
pemensik pushed to dnsmasq (master). "Rebase to 2.78 (..more)"
by notifications@fedoraproject.org
From 1447e0aebc6b23107b7997a8e52398277cfb46da Mon Sep 17 00:00:00 2001
From: Petr Menšík <pemensik(a)redhat.com>
Date: Oct 03 2017 15:30:29 +0000
Subject: Rebase to 2.78
Signed-off-by: Petr Menšík <pemensik(a)redhat.com>
---
diff --git a/.gitignore b/.gitignore
index bd16c9f..7899088 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,3 +25,4 @@ dnsmasq-2.52.tar.lzma
/dnsmasq-2.76.tar.xz
/dnsmasq-2.77rc2.tar.xz
/dnsmasq-2.77.tar.xz
+/dnsmasq-2.78.tar.xz
diff --git a/dnsmasq-2.77-CVE-2017-13704.patch b/dnsmasq-2.77-CVE-2017-13704.patch
deleted file mode 100644
index c60b382..0000000
--- a/dnsmasq-2.77-CVE-2017-13704.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From 63437ffbb58837b214b4b92cb1c54bc5f3279928 Mon Sep 17 00:00:00 2001
-From: Simon Kelley <simon(a)thekelleys.org.uk>
-Date: Wed, 6 Sep 2017 22:34:21 +0100
-Subject: [PATCH] Fix CVE-2017-13704, which resulted in a crash on a large DNS
- query.
-
-A DNS query recieved by UDP which exceeds 512 bytes (or the EDNS0 packet size,
-if different.) is enough to cause SIGSEGV.
----
- src/auth.c | 5 -----
- src/forward.c | 8 ++++++++
- src/rfc1035.c | 5 -----
- 3 files changed, 8 insertions(+), 10 deletions(-)
-
-diff --git a/src/auth.c b/src/auth.c
-index 2c24e16..7f95f98 100644
---- a/src/auth.c
-+++ b/src/auth.c
-@@ -119,11 +119,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
- struct cname *a, *candidate;
- unsigned int wclen;
-
-- /* Clear buffer beyond request to avoid risk of
-- information disclosure. */
-- memset(((char *)header) + qlen, 0,
-- (limit - ((char *)header)) - qlen);
--
- if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY )
- return 0;
-
-diff --git a/src/forward.c b/src/forward.c
-index f22556a..e3fa94b 100644
---- a/src/forward.c
-+++ b/src/forward.c
-@@ -1188,6 +1188,10 @@ void receive_query(struct listener *listen, time_t now)
- (msg.msg_flags & MSG_TRUNC) ||
- (header->hb3 & HB3_QR))
- return;
-+
-+ /* Clear buffer beyond request to avoid risk of
-+ information disclosure. */
-+ memset(daemon->packet + n, 0, daemon->edns_pktsz - n);
-
- source_addr.sa.sa_family = listen->family;
-
-@@ -1688,6 +1692,10 @@ unsigned char *tcp_request(int confd, time_t now,
-
- if (size < (int)sizeof(struct dns_header))
- continue;
-+
-+ /* Clear buffer beyond request to avoid risk of
-+ information disclosure. */
-+ memset(payload + size, 0, 65536 - size);
-
- query_count++;
-
-diff --git a/src/rfc1035.c b/src/rfc1035.c
-index 26f5301..af2fe46 100644
---- a/src/rfc1035.c
-+++ b/src/rfc1035.c
-@@ -1223,11 +1223,6 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
- struct mx_srv_record *rec;
- size_t len;
-
-- /* Clear buffer beyond request to avoid risk of
-- information disclosure. */
-- memset(((char *)header) + qlen, 0,
-- (limit - ((char *)header)) - qlen);
--
- if (ntohs(header->ancount) != 0 ||
- ntohs(header->nscount) != 0 ||
- ntohs(header->qdcount) == 0 ||
---
-2.9.5
-
diff --git a/dnsmasq-2.77-CVE-2017-14491-2.patch b/dnsmasq-2.77-CVE-2017-14491-2.patch
deleted file mode 100644
index 31a065c..0000000
--- a/dnsmasq-2.77-CVE-2017-14491-2.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From 62cb936cb7ad5f219715515ae7d32dd281a5aa1f Mon Sep 17 00:00:00 2001
-From: Simon Kelley <simon(a)thekelleys.org.uk>
-Date: Tue, 26 Sep 2017 22:00:11 +0100
-Subject: [PATCH 10/10] Security fix, CVE-2017-14491, DNS heap buffer overflow.
-
-Further fix to 0549c73b7ea6b22a3c49beb4d432f185a81efcbc
-Handles case when RR name is not a pointer to the question,
-only occurs for some auth-mode replies, therefore not
-detected by fuzzing (?)
----
- src/rfc1035.c | 27 +++++++++++++++------------
- 1 file changed, 15 insertions(+), 12 deletions(-)
-
-diff --git a/src/rfc1035.c b/src/rfc1035.c
-index 27af023..56ab88b 100644
---- a/src/rfc1035.c
-+++ b/src/rfc1035.c
-@@ -1086,32 +1086,35 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int
-
- va_start(ap, format); /* make ap point to 1st unamed argument */
-
-- /* nameoffset (1 or 2) + type (2) + class (2) + ttl (4) + 0 (2) */
-- CHECK_LIMIT(12);
--
- if (nameoffset > 0)
- {
-+ CHECK_LIMIT(2);
- PUTSHORT(nameoffset | 0xc000, p);
- }
- else
- {
- char *name = va_arg(ap, char *);
-- if (name)
-- p = do_rfc1035_name(p, name, limit);
-- if (!p)
-- {
-- va_end(ap);
-- goto truncated;
-- }
--
-+ if (name && !(p = do_rfc1035_name(p, name, limit)))
-+ {
-+ va_end(ap);
-+ goto truncated;
-+ }
-+
- if (nameoffset < 0)
- {
-+ CHECK_LIMIT(2);
- PUTSHORT(-nameoffset | 0xc000, p);
- }
- else
-- *p++ = 0;
-+ {
-+ CHECK_LIMIT(1);
-+ *p++ = 0;
-+ }
- }
-
-+ /* type (2) + class (2) + ttl (4) + rdlen (2) */
-+ CHECK_LIMIT(10);
-+
- PUTSHORT(type, p);
- PUTSHORT(class, p);
- PUTLONG(ttl, p); /* TTL */
---
-2.9.5
-
diff --git a/dnsmasq-2.77-CVE-2017-14491.patch b/dnsmasq-2.77-CVE-2017-14491.patch
deleted file mode 100644
index 9b62e90..0000000
--- a/dnsmasq-2.77-CVE-2017-14491.patch
+++ /dev/null
@@ -1,263 +0,0 @@
-From 445282d13b90712ef90d2c2141d0e19bb1d896d2 Mon Sep 17 00:00:00 2001
-From: Simon Kelley <simon(a)thekelleys.org.uk>
-Date: Mon, 25 Sep 2017 18:17:11 +0100
-Subject: [PATCH] Security fix, CVE-2017-14491 DNS heap buffer overflow.
-
-Fix heap overflow in DNS code. This is a potentially serious
-security hole. It allows an attacker who can make DNS
-requests to dnsmasq, and who controls the contents of
-a domain, which is thereby queried, to overflow
-(by 2 bytes) a heap buffer and either crash, or
-even take control of, dnsmasq.
-
-(original commit 0549c73b7ea6b22a3c49beb4d432f185a81efcbc)
----
- src/dnsmasq.h | 2 +-
- src/dnssec.c | 2 +-
- src/option.c | 2 +-
- src/rfc1035.c | 50 +++++++++++++++++++++++++++++++++++++++++---------
- src/rfc2131.c | 4 ++--
- src/rfc3315.c | 4 ++--
- src/util.c | 7 ++++++-
- 7 files changed, 54 insertions(+), 17 deletions(-)
-
-diff --git a/src/dnsmasq.h b/src/dnsmasq.h
-index 06fae35..7a18898 100644
---- a/src/dnsmasq.h
-+++ b/src/dnsmasq.h
-@@ -1179,7 +1179,7 @@ u32 rand32(void);
- u64 rand64(void);
- int legal_hostname(char *c);
- char *canonicalise(char *s, int *nomem);
--unsigned char *do_rfc1035_name(unsigned char *p, char *sval);
-+unsigned char *do_rfc1035_name(unsigned char *p, char *sval, char *limit);
- void *safe_malloc(size_t size);
- void safe_pipe(int *fd, int read_noblock);
- void *whine_malloc(size_t size);
-diff --git a/src/dnssec.c b/src/dnssec.c
-index 3330eef..b6cb55f 100644
---- a/src/dnssec.c
-+++ b/src/dnssec.c
-@@ -2230,7 +2230,7 @@ size_t dnssec_generate_query(struct dns_header *header, unsigned char *end, char
-
- p = (unsigned char *)(header+1);
-
-- p = do_rfc1035_name(p, name);
-+ p = do_rfc1035_name(p, name, NULL);
- *p++ = 0;
- PUTSHORT(type, p);
- PUTSHORT(class, p);
-diff --git a/src/option.c b/src/option.c
-index 064ef62..22bd19a 100644
---- a/src/option.c
-+++ b/src/option.c
-@@ -1415,7 +1415,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
- }
-
- p = newp;
-- end = do_rfc1035_name(p + len, dom);
-+ end = do_rfc1035_name(p + len, dom, NULL);
- *end++ = 0;
- len = end - p;
- free(dom);
-diff --git a/src/rfc1035.c b/src/rfc1035.c
-index 1671883..3397a26 100644
---- a/src/rfc1035.c
-+++ b/src/rfc1035.c
-@@ -1062,6 +1062,7 @@ int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bog
- return 0;
- }
-
-+
- int add_resource_record(struct dns_header *header, char *limit, int *truncp, int nameoffset, unsigned char **pp,
- unsigned long ttl, int *offset, unsigned short type, unsigned short class, char *format, ...)
- {
-@@ -1071,12 +1072,21 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int
- unsigned short usval;
- long lval;
- char *sval;
-+#define CHECK_LIMIT(size) \
-+ if (limit && p + (size) > (unsigned char*)limit) \
-+ { \
-+ va_end(ap); \
-+ goto truncated; \
-+ }
-
- if (truncp && *truncp)
- return 0;
--
-+
- va_start(ap, format); /* make ap point to 1st unamed argument */
--
-+
-+ /* nameoffset (1 or 2) + type (2) + class (2) + ttl (4) + 0 (2) */
-+ CHECK_LIMIT(12);
-+
- if (nameoffset > 0)
- {
- PUTSHORT(nameoffset | 0xc000, p);
-@@ -1085,7 +1095,13 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int
- {
- char *name = va_arg(ap, char *);
- if (name)
-- p = do_rfc1035_name(p, name);
-+ p = do_rfc1035_name(p, name, limit);
-+ if (!p)
-+ {
-+ va_end(ap);
-+ goto truncated;
-+ }
-+
- if (nameoffset < 0)
- {
- PUTSHORT(-nameoffset | 0xc000, p);
-@@ -1106,6 +1122,7 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int
- {
- #ifdef HAVE_IPV6
- case '6':
-+ CHECK_LIMIT(IN6ADDRSZ);
- sval = va_arg(ap, char *);
- memcpy(p, sval, IN6ADDRSZ);
- p += IN6ADDRSZ;
-@@ -1113,36 +1130,47 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int
- #endif
-
- case '4':
-+ CHECK_LIMIT(INADDRSZ);
- sval = va_arg(ap, char *);
- memcpy(p, sval, INADDRSZ);
- p += INADDRSZ;
- break;
-
- case 'b':
-+ CHECK_LIMIT(1);
- usval = va_arg(ap, int);
- *p++ = usval;
- break;
-
- case 's':
-+ CHECK_LIMIT(2);
- usval = va_arg(ap, int);
- PUTSHORT(usval, p);
- break;
-
- case 'l':
-+ CHECK_LIMIT(4);
- lval = va_arg(ap, long);
- PUTLONG(lval, p);
- break;
-
- case 'd':
-- /* get domain-name answer arg and store it in RDATA field */
-- if (offset)
-- *offset = p - (unsigned char *)header;
-- p = do_rfc1035_name(p, va_arg(ap, char *));
-- *p++ = 0;
-+ /* get domain-name answer arg and store it in RDATA field */
-+ if (offset)
-+ *offset = p - (unsigned char *)header;
-+ p = do_rfc1035_name(p, va_arg(ap, char *), limit);
-+ if (!p)
-+ {
-+ va_end(ap);
-+ goto truncated;
-+ }
-+ CHECK_LIMIT(1);
-+ *p++ = 0;
- break;
-
- case 't':
- usval = va_arg(ap, int);
-+ CHECK_LIMIT(usval);
- sval = va_arg(ap, char *);
- if (usval != 0)
- memcpy(p, sval, usval);
-@@ -1154,20 +1182,24 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int
- usval = sval ? strlen(sval) : 0;
- if (usval > 255)
- usval = 255;
-+ CHECK_LIMIT(usval + 1);
- *p++ = (unsigned char)usval;
- memcpy(p, sval, usval);
- p += usval;
- break;
- }
-
-+#undef CHECK_LIMIT
- va_end(ap); /* clean up variable argument pointer */
-
- j = p - sav - 2;
-- PUTSHORT(j, sav); /* Now, store real RDLength */
-+ /* this has already been checked against limit before */
-+ PUTSHORT(j, sav); /* Now, store real RDLength */
-
- /* check for overflow of buffer */
- if (limit && ((unsigned char *)limit - p) < 0)
- {
-+truncated:
- if (truncp)
- *truncp = 1;
- return 0;
-diff --git a/src/rfc2131.c b/src/rfc2131.c
-index a679470..052498c 100644
---- a/src/rfc2131.c
-+++ b/src/rfc2131.c
-@@ -2454,10 +2454,10 @@ static void do_options(struct dhcp_context *context,
-
- if (fqdn_flags & 0x04)
- {
-- p = do_rfc1035_name(p, hostname);
-+ p = do_rfc1035_name(p, hostname, NULL);
- if (domain)
- {
-- p = do_rfc1035_name(p, domain);
-+ p = do_rfc1035_name(p, domain, NULL);
- *p++ = 0;
- }
- }
-diff --git a/src/rfc3315.c b/src/rfc3315.c
-index 054ecd0..715b6db 100644
---- a/src/rfc3315.c
-+++ b/src/rfc3315.c
-@@ -1479,10 +1479,10 @@ static struct dhcp_netid *add_options(struct state *state, int do_refresh)
- if ((p = expand(len + 2)))
- {
- *(p++) = state->fqdn_flags;
-- p = do_rfc1035_name(p, state->hostname);
-+ p = do_rfc1035_name(p, state->hostname, NULL);
- if (state->send_domain)
- {
-- p = do_rfc1035_name(p, state->send_domain);
-+ p = do_rfc1035_name(p, state->send_domain, NULL);
- *p = 0;
- }
- }
-diff --git a/src/util.c b/src/util.c
-index 145e53a..471faa9 100644
---- a/src/util.c
-+++ b/src/util.c
-@@ -227,15 +227,20 @@ char *canonicalise(char *in, int *nomem)
- return ret;
- }
-
--unsigned char *do_rfc1035_name(unsigned char *p, char *sval)
-+unsigned char *do_rfc1035_name(unsigned char *p, char *sval, char *limit)
- {
- int j;
-
- while (sval && *sval)
- {
-+ if (limit && p + 1 > (unsigned char*)limit)
-+ return p;
-+
- unsigned char *cp = p++;
- for (j = 0; *sval && (*sval != '.'); sval++, j++)
- {
-+ if (limit && p + 1 > (unsigned char*)limit)
-+ return p;
- #ifdef HAVE_DNSSEC
- if (option_bool(OPT_DNSSEC_VALID) && *sval == NAME_ESCAPE)
- *p++ = (*(++sval))-1;
---
-2.9.5
-
diff --git a/dnsmasq-2.77-CVE-2017-14492.patch b/dnsmasq-2.77-CVE-2017-14492.patch
deleted file mode 100644
index 1430b4c..0000000
--- a/dnsmasq-2.77-CVE-2017-14492.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 24036ea507862c7b7898b68289c8130f85599c10 Mon Sep 17 00:00:00 2001
-From: Simon Kelley <simon(a)thekelleys.org.uk>
-Date: Mon, 25 Sep 2017 18:47:15 +0100
-Subject: [PATCH 3/9] Security fix, CVE-2017-14492, DHCPv6 RA heap overflow.
-
-Fix heap overflow in IPv6 router advertisement code.
-This is a potentially serious security hole, as a
-crafted RA request can overflow a buffer and crash or
-control dnsmasq. Attacker must be on the local network.
----
- src/radv.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/src/radv.c b/src/radv.c
-index 1032189..9b7e52c 100644
---- a/src/radv.c
-+++ b/src/radv.c
-@@ -198,6 +198,9 @@ void icmp6_packet(time_t now)
- /* look for link-layer address option for logging */
- if (sz >= 16 && packet[8] == ICMP6_OPT_SOURCE_MAC && (packet[9] * 8) + 8 <= sz)
- {
-+ if ((packet[9] * 8 - 2) * 3 - 1 >= MAXDNAME) {
-+ return;
-+ }
- print_mac(daemon->namebuff, &packet[10], (packet[9] * 8) - 2);
- mac = daemon->namebuff;
- }
---
-2.9.5
-
diff --git a/dnsmasq-2.77-CVE-2017-14493.patch b/dnsmasq-2.77-CVE-2017-14493.patch
deleted file mode 100644
index d80553c..0000000
--- a/dnsmasq-2.77-CVE-2017-14493.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 3d4ff1ba8419546490b464418223132529514033 Mon Sep 17 00:00:00 2001
-From: Simon Kelley <simon(a)thekelleys.org.uk>
-Date: Mon, 25 Sep 2017 18:52:50 +0100
-Subject: [PATCH 4/9] Security fix, CVE-2017-14493, DHCPv6 - Stack buffer
- overflow.
-
-Fix stack overflow in DHCPv6 code. An attacker who can send
-a DHCPv6 request to dnsmasq can overflow the stack frame and
-crash or control dnsmasq.
----
- src/rfc3315.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/src/rfc3315.c b/src/rfc3315.c
-index 1687931..920907c 100644
---- a/src/rfc3315.c
-+++ b/src/rfc3315.c
-@@ -206,6 +206,9 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
- /* RFC-6939 */
- if ((opt = opt6_find(opts, end, OPTION6_CLIENT_MAC, 3)))
- {
-+ if (opt6_len(opt) - 2 > DHCP_CHADDR_MAX) {
-+ return 0;
-+ }
- state->mac_type = opt6_uint(opt, 0, 2);
- state->mac_len = opt6_len(opt) - 2;
- memcpy(&state->mac[0], opt6_ptr(opt, 2), state->mac_len);
---
-2.9.5
-
diff --git a/dnsmasq-2.77-CVE-2017-14494.patch b/dnsmasq-2.77-CVE-2017-14494.patch
deleted file mode 100644
index 7b49907..0000000
--- a/dnsmasq-2.77-CVE-2017-14494.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 33e3f1029c9ec6c63e430ff51063a6301d4b2262 Mon Sep 17 00:00:00 2001
-From: Simon Kelley <simon(a)thekelleys.org.uk>
-Date: Mon, 25 Sep 2017 20:05:11 +0100
-Subject: [PATCH 5/9] Security fix, CVE-2017-14494, Infoleak handling DHCPv6
- forwarded requests.
-
-Fix information leak in DHCPv6. A crafted DHCPv6 packet can
-cause dnsmasq to forward memory from outside the packet
-buffer to a DHCPv6 server when acting as a relay.
----
- src/rfc3315.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/src/rfc3315.c b/src/rfc3315.c
-index 920907c..4ca43e0 100644
---- a/src/rfc3315.c
-+++ b/src/rfc3315.c
-@@ -216,6 +216,9 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
-
- for (opt = opts; opt; opt = opt6_next(opt, end))
- {
-+ if (opt6_ptr(opt, 0) + opt6_len(opt) >= end) {
-+ return 0;
-+ }
- int o = new_opt6(opt6_type(opt));
- if (opt6_type(opt) == OPTION6_RELAY_MSG)
- {
---
-2.9.5
-
diff --git a/dnsmasq-2.77-CVE-2017-14495.patch b/dnsmasq-2.77-CVE-2017-14495.patch
deleted file mode 100644
index 0f793aa..0000000
--- a/dnsmasq-2.77-CVE-2017-14495.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 51eadb692a5123b9838e5a68ecace3ac579a3a45 Mon Sep 17 00:00:00 2001
-From: Simon Kelley <simon(a)thekelleys.org.uk>
-Date: Mon, 25 Sep 2017 20:16:50 +0100
-Subject: [PATCH 7/9] Security fix, CVE-2017-14495, OOM in DNS response
- creation.
-
-Fix out-of-memory Dos vulnerability. An attacker which can
-send malicious DNS queries to dnsmasq can trigger memory
-allocations in the add_pseudoheader function
-The allocated memory is never freed which leads to a DoS
-through memory exhaustion. dnsmasq is vulnerable only
-if one of the following option is specified:
---add-mac, --add-cpe-id or --add-subnet.
----
- src/edns0.c | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
-
-diff --git a/src/edns0.c b/src/edns0.c
-index 95b74ee..89b2692 100644
---- a/src/edns0.c
-+++ b/src/edns0.c
-@@ -192,9 +192,15 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
- !(p = skip_section(p,
- ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount),
- header, plen)))
-+ {
-+ free(buff);
- return plen;
-+ }
- if (p + 11 > limit)
-- return plen; /* Too big */
-+ {
-+ free(buff);
-+ return plen; /* Too big */
-+ }
- *p++ = 0; /* empty name */
- PUTSHORT(T_OPT, p);
- PUTSHORT(udp_sz, p); /* max packet length, 512 if not given in EDNS0 header */
---
-2.9.5
-
diff --git a/dnsmasq-2.77-CVE-2017-14496.patch b/dnsmasq-2.77-CVE-2017-14496.patch
deleted file mode 100644
index 36420e8..0000000
--- a/dnsmasq-2.77-CVE-2017-14496.patch
+++ /dev/null
@@ -1,66 +0,0 @@
-From 897c113fda0886a28a986cc6ba17bb93bd6cb1c7 Mon Sep 17 00:00:00 2001
-From: Simon Kelley <simon(a)thekelleys.org.uk>
-Date: Mon, 25 Sep 2017 20:11:58 +0100
-Subject: [PATCH 6/9] Security fix, CVE-2017-14496, Integer underflow in DNS
- response creation.
-
-Fix DoS in DNS. Invalid boundary checks in the
-add_pseudoheader function allows a memcpy call with negative
-size An attacker which can send malicious DNS queries
-to dnsmasq can trigger a DoS remotely.
-dnsmasq is vulnerable only if one of the following option is
-specified: --add-mac, --add-cpe-id or --add-subnet.
----
- src/edns0.c | 13 ++++++++++++-
- 1 file changed, 12 insertions(+), 1 deletion(-)
-
-diff --git a/src/edns0.c b/src/edns0.c
-index f5b798c..95b74ee 100644
---- a/src/edns0.c
-+++ b/src/edns0.c
-@@ -144,7 +144,7 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
- GETSHORT(len, p);
-
- /* malformed option, delete the whole OPT RR and start again. */
-- if (i + len > rdlen)
-+ if (i + 4 + len > rdlen)
- {
- rdlen = 0;
- is_last = 0;
-@@ -193,6 +193,8 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
- ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount),
- header, plen)))
- return plen;
-+ if (p + 11 > limit)
-+ return plen; /* Too big */
- *p++ = 0; /* empty name */
- PUTSHORT(T_OPT, p);
- PUTSHORT(udp_sz, p); /* max packet length, 512 if not given in EDNS0 header */
-@@ -204,6 +206,11 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
- /* Copy back any options */
- if (buff)
- {
-+ if (p + rdlen > limit)
-+ {
-+ free(buff);
-+ return plen; /* Too big */
-+ }
- memcpy(p, buff, rdlen);
- free(buff);
- p += rdlen;
-@@ -220,8 +227,12 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
- /* Add new option */
- if (optno != 0 && replace != 2)
- {
-+ if (p + 4 > limit)
-+ return plen; /* Too big */
- PUTSHORT(optno, p);
- PUTSHORT(optlen, p);
-+ if (p + optlen > limit)
-+ return plen; /* Too big */
- memcpy(p, opt, optlen);
- p += optlen;
- PUTSHORT(p - datap, lenp);
---
-2.9.5
-
diff --git a/dnsmasq-2.77-arcount.patch b/dnsmasq-2.77-arcount.patch
deleted file mode 100644
index e6bf0d7..0000000
--- a/dnsmasq-2.77-arcount.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From a3303e196e5d304ec955c4d63afb923ade66c6e8 Mon Sep 17 00:00:00 2001
-From: Simon Kelley <simon(a)thekelleys.org.uk>
-Date: Thu, 7 Sep 2017 20:45:00 +0100
-Subject: [PATCH] Don't return arcount=1 if EDNS0 RR won't fit in the packet.
-
-Omitting the EDNS0 RR but setting arcount gives a malformed packet.
-Also, don't accept UDP packet size less than 512 in recieved EDNS0.
----
- src/edns0.c | 5 ++++-
- src/forward.c | 2 ++
- 2 files changed, 6 insertions(+), 1 deletion(-)
-
-diff --git a/src/edns0.c b/src/edns0.c
-index 3fde17f..f5b798c 100644
---- a/src/edns0.c
-+++ b/src/edns0.c
-@@ -208,7 +208,10 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
- free(buff);
- p += rdlen;
- }
-- header->arcount = htons(ntohs(header->arcount) + 1);
-+
-+ /* Only bump arcount if RR is going to fit */
-+ if (((ssize_t)optlen) <= (limit - (p + 4)))
-+ header->arcount = htons(ntohs(header->arcount) + 1);
- }
-
- if (((ssize_t)optlen) > (limit - (p + 4)))
-diff --git a/src/forward.c b/src/forward.c
-index e3fa94b..942b02d 100644
---- a/src/forward.c
-+++ b/src/forward.c
-@@ -1412,6 +1412,8 @@ void receive_query(struct listener *listen, time_t now)
- defaults to 512 */
- if (udp_size > daemon->edns_pktsz)
- udp_size = daemon->edns_pktsz;
-+ else if (udp_size < PACKETSZ)
-+ udp_size = PACKETSZ; /* Sanity check - can't reduce below default. RFC 6891 6.2.3 */
- }
-
- #ifdef HAVE_AUTH
---
-2.9.5
-
diff --git a/dnsmasq-2.77-misc-cleanups.patch b/dnsmasq-2.77-misc-cleanups.patch
deleted file mode 100644
index 1c7edd7..0000000
--- a/dnsmasq-2.77-misc-cleanups.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From 6a0b00f0d66490e074323d04782e75c4ba8a3f8d Mon Sep 17 00:00:00 2001
-From: Simon Kelley <simon(a)thekelleys.org.uk>
-Date: Mon, 25 Sep 2017 20:19:55 +0100
-Subject: [PATCH 8/9] Misc code cleanups arising from Google analysis. No
- security impleications or CVEs.
-
----
- src/edns0.c | 2 +-
- src/rfc1035.c | 4 +++-
- src/rfc2131.c | 2 +-
- 3 files changed, 5 insertions(+), 3 deletions(-)
-
-diff --git a/src/edns0.c b/src/edns0.c
-index 89b2692..7ed5a47 100644
---- a/src/edns0.c
-+++ b/src/edns0.c
-@@ -159,7 +159,7 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
- /* delete option if we're to replace it. */
- p -= 4;
- rdlen -= len + 4;
-- memcpy(p, p+len+4, rdlen - i);
-+ memmove(p, p+len+4, rdlen - i);
- PUTSHORT(rdlen, lenp);
- lenp -= 2;
- }
-diff --git a/src/rfc1035.c b/src/rfc1035.c
-index 826f8a4..27af023 100644
---- a/src/rfc1035.c
-+++ b/src/rfc1035.c
-@@ -37,7 +37,7 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
- /* end marker */
- {
- /* check that there are the correct no of bytes after the name */
-- if (!CHECK_LEN(header, p, plen, extrabytes))
-+ if (!CHECK_LEN(header, p1 ? p1 : p, plen, extrabytes))
- return 0;
-
- if (isExtract)
-@@ -498,6 +498,8 @@ static unsigned char *do_doctor(unsigned char *p, int count, struct dns_header *
- {
- unsigned int i, len = *p1;
- unsigned char *p2 = p1;
-+ if ((p1 + len - p) >= rdlen)
-+ return 0; /* bad packet */
- /* make counted string zero-term and sanitise */
- for (i = 0; i < len; i++)
- {
-diff --git a/src/rfc2131.c b/src/rfc2131.c
-index f7c1f80..f3a7e53 100644
---- a/src/rfc2131.c
-+++ b/src/rfc2131.c
-@@ -157,7 +157,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
- for (offset = 0; offset < (len - 5); offset += elen + 5)
- {
- elen = option_uint(opt, offset + 4 , 1);
-- if (option_uint(opt, offset, 4) == BRDBAND_FORUM_IANA)
-+ if (option_uint(opt, offset, 4) == BRDBAND_FORUM_IANA && offset + elen + 5 <= len)
- {
- unsigned char *x = option_ptr(opt, offset + 5);
- unsigned char *y = option_ptr(opt, offset + elen + 5);
---
-2.9.5
-
diff --git a/dnsmasq-2.77-stdio.h.patch b/dnsmasq-2.77-stdio.h.patch
deleted file mode 100644
index dc53025..0000000
--- a/dnsmasq-2.77-stdio.h.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From b476faf1c4f96c093ea1a8a0c824dea9f55b665f Mon Sep 17 00:00:00 2001
-From: Christian Hesse <list(a)eworm.de>
-Date: Mon, 25 Sep 2017 17:36:24 +0100
-Subject: [PATCH] Do not include stdio.h before dnsmasq.h
-
-We define some constants in dnsmasq.h, which have an influence on
-stdio.h. So do not include stdio.h before dnsmasq.h.
----
- src/dnsmasq.h | 6 ++++++
- src/helper.c | 1 -
- 2 files changed, 6 insertions(+), 1 deletion(-)
-
-diff --git a/src/dnsmasq.h b/src/dnsmasq.h
-index 7a18898..421488b 100644
---- a/src/dnsmasq.h
-+++ b/src/dnsmasq.h
-@@ -16,6 +16,12 @@
-
- #define COPYRIGHT "Copyright (c) 2000-2016 Simon Kelley"
-
-+/* We do defines that influence behavior of stdio.h, so complain
-+ if included too early. */
-+#ifdef _STDIO_H
-+# error "Header file stdio.h included too early!"
-+#endif
-+
- #ifndef NO_LARGEFILE
- /* Ensure we can use files >2GB (log files may grow this big) */
- # define _LARGEFILE_SOURCE 1
-diff --git a/src/helper.c b/src/helper.c
-index 4fffa27..68ce9a7 100644
---- a/src/helper.c
-+++ b/src/helper.c
-@@ -14,7 +14,6 @@
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
--#include <stdio.h>
- #include "dnsmasq.h"
-
- #ifdef HAVE_SCRIPT
---
-2.9.5
-
diff --git a/dnsmasq.spec b/dnsmasq.spec
index ec4e468..af552d2 100644
--- a/dnsmasq.spec
+++ b/dnsmasq.spec
@@ -12,8 +12,8 @@
%define _hardened_build 1
Name: dnsmasq
-Version: 2.77
-Release: 9%{?extraversion:.%{extraversion}}%{?dist}
+Version: 2.78
+Release: 1%{?extraversion:.%{extraversion}}%{?dist}
Summary: A lightweight DHCP/caching DNS server
Group: System Environment/Daemons
@@ -22,18 +22,8 @@ URL: http://www.thekelleys.org.uk/dnsmasq/
Source0: http://www.thekelleys.org.uk/dnsmasq/%{?extrapath}%{name}-%{version}%{?ex...
Source1: %{name}.service
-Patch1: dnsmasq-2.77-CVE-2017-13704.patch
-Patch2: dnsmasq-2.77-CVE-2017-14491.patch
-Patch3: dnsmasq-2.77-CVE-2017-14492.patch
-Patch4: dnsmasq-2.77-CVE-2017-14493.patch
-Patch5: dnsmasq-2.77-CVE-2017-14494.patch
-Patch6: dnsmasq-2.77-CVE-2017-14496.patch
-Patch7: dnsmasq-2.77-CVE-2017-14495.patch
-Patch8: dnsmasq-2.77-misc-cleanups.patch
-Patch9: dnsmasq-2.77-CVE-2017-14491-2.patch
-Patch10: dnsmasq-2.77-stdio.h.patch
-Patch11: dnsmasq-2.77-arcount.patch
-Patch12: dnsmasq-2.77-underflow.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=1495409
+Patch1: dnsmasq-2.77-underflow.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@@ -68,18 +58,7 @@ query/remove a DHCP server's leases.
%prep
%setup -q -n %{name}-%{version}%{?extraversion}
-%patch1 -p1 -b .CVE-2017-13704
-%patch2 -p1 -b .CVE-2017-14491
-%patch3 -p1 -b .CVE-2017-14492
-%patch4 -p1 -b .CVE-2017-14493
-%patch5 -p1 -b .CVE-2017-14494
-%patch6 -p1 -b .CVE-2017-14496
-%patch7 -p1 -b .CVE-2017-14495
-%patch8 -p1 -b .misc-cleanups
-%patch9 -p1 -b .CVE-2017-14491-2
-%patch10 -p1 -b .stdio.h
-%patch11 -p1 -b .arcount
-%patch12 -p1 -b .underflow
+%patch1 -p1 -b .underflow
# 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
@@ -166,6 +145,9 @@ rm -rf $RPM_BUILD_ROOT
%{_mandir}/man1/dhcp_*
%changelog
+* Tue Oct 03 2017 Petr Menšík <pemensik(a)redhat.com> - 2.78-1
+- Rebase to 2.78
+
* Tue Oct 03 2017 Petr Menšík <pemensik(a)redhat.com> - 2.77-9
- More patches related to CVE-2017-14491
diff --git a/sources b/sources
index 8d29c8c..ed48c35 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-SHA512 (dnsmasq-2.77.tar.xz) = 6ca98a71a8fdfd606e29c58b34dadfa63148c39f931570cca67a287e044d52c6ec2f8acbf5620ada3312e9db3a2fd63877188d829c070beaa730607e3309e768
+SHA512 (dnsmasq-2.78.tar.xz) = 9b79b84e5a768d52f90f6335ccef2c404ecd7a13e78e49f4cd0755fffc6cf34d0dc96ad4c72cad1dab3c5743a8d0d789b3e9b6e625b03c5675bb898ca61a698b
https://src.fedoraproject.org/rpms/dnsmasq/c/1447e0aebc6b23107b7997a8e523...
6 years, 8 months
dnsmasq configuration
by Simon Slater
G'day all,
I've a qustion about the dhcp server configuration in dnsmasq. The
way I've configured it it is listening on eth1 as it ought, but is
offering on eth0 which it oughtn't. What have I missed in the
configuration?
# Configuration file for dnsmasq.
#
interface=eth1
except-interface=eth0
dhcp-range=192.168.1.100,192.168.1.199,255.255.255.0,10m
dhcp-option=28,192.168.1.255
log-queries
log-dhcp
[simon@dell ~]$
and /var/log/messages:
Mar 28 11:45:33 dell dnsmasq[12161]: DHCP packet: transaction-id is
1613319306
Mar 28 11:45:33 dell dnsmasq[12161]: Available DHCP range: 192.168.1.100
--
192.168.1.199
Mar 28 11:45:33 dell dnsmasq[12161]: DHCPDISCOVER(eth1) 192.168.1.103
00:10:5a:62:2a:a5
Mar 28 11:45:33 dell dnsmasq[12161]: DHCPOFFER(eth1) 192.168.1.103
00:10:5a:62:2a:a5
Mar 28 11:45:33 dell dnsmasq[12161]: requested options: 1:netmask,
28:broadcast, 2:time-offset,
3:router,
Mar 28 11:45:33 dell dnsmasq[12161]: requested options: 15:domain-name,
6:dns-server,
12:hostname,
Mar 28 11:45:33 dell dnsmasq[12161]: requested options: 40:nis-domain,
41:nis-server,
42:ntp-server
Mar 28 11:45:33 dell dnsmasq[12161]: sent size: 1 option:
53:message-type 02
Mar 28 11:45:33 dell dnsmasq[12161]: sent size: 4 option:
54:server-identifier
c0:a8:01:01
Mar 28 11:45:33 dell dnsmasq[12161]: sent size: 4 option: 51:lease-time
00:00:02:58
Mar 28 11:45:33 dell dnsmasq[12161]: sent size: 4 option: 58:T1
00:00:01:2c
Mar 28 11:45:33 dell dnsmasq[12161]: sent size: 4 option: 59:T2
00:00:02:0d
Mar 28 11:45:33 dell dnsmasq[12161]: sent size: 4 option: 1:netmask
ff:ff:ff:00
Mar 28 11:45:33 dell dnsmasq[12161]: sent size: 4 option: 3:router
c0:a8:01:01
Mar 28 11:45:33 dell dnsmasq[12161]: sent size: 4 option: 6:dns-server
c0:a8:01:01
Mar 28 11:45:33 dell dnsmasq[12161]: sent size: 11 option:
15:domain-name
6c:6f:63:61:6c:64:6f:6d:61:69:6e
Mar 28 11:45:33 dell dnsmasq[12161]: sent size: 4 option: 28:broadcast
c0:a8:01:ff
Mar 28 11:45:33 dell kernel: [IPTABLES DROP] : IN= OUT=eth0
SRC=192.168.1.9 DST=192.168.1.103 LEN=333 TOS=0x00 PREC=0x00 TTL=64
ID=19755 PROTO=UDP SPT=67 DPT=68 LEN=313
How do I configure dnsmasq to offer dhcp on eth1?
Thanks in advance.
--
Regards,
Simon Slater
Registered Linux User #463789. Be counted at: http://counter.li.org/
15 years, 3 months