update dnsmasq to 2.86

This commit is contained in:
yangl777 2022-03-22 11:42:25 +08:00
parent 62c1829b4b
commit 3b6c1529d5
28 changed files with 1988 additions and 163 deletions

View File

@ -0,0 +1,35 @@
From f5f56c001dddd486859dc6301e6cbe00ba604fe8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@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

View File

@ -0,0 +1,77 @@
From 061013293ceddce509ae06a31a045e803103f1ce Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@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

View File

@ -0,0 +1,28 @@
From 920cd815bafea084f68cc4309399aea77bd7f66b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@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

View File

@ -0,0 +1,153 @@
From e61af561900b4d2dd976a575b2efd388be092742 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@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

View File

@ -0,0 +1,148 @@
From be7f213066282baeed46cc34223601c462db9cbf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@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

View File

@ -0,0 +1,48 @@
From 3a077065ce846e301b532127ebecdd2771ad75ed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@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

View File

@ -0,0 +1,32 @@
From 467b621fb7da6e1318ac7204325b0adb01b3ff19 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@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

View File

@ -0,0 +1,131 @@
From bbfdf6a435cbd5f71ae76f962ce86786346589aa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@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

View File

@ -0,0 +1,110 @@
From 7b975696a7bda5b86fcf168644f177544adb6fe9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@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

View File

@ -0,0 +1,236 @@
From db835f8c40e83c6392e69ffc7f2cc500f7682dd4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@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

View File

@ -0,0 +1,54 @@
From 9c088b29dcdb8a3e013120d8272a6e0314a8f3df Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@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

View File

@ -0,0 +1,41 @@
From 957b2b25238d82a6c3afced2ff0423ad171fb22e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@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

View File

@ -0,0 +1,134 @@
From 0dafe990a1395d597bc6022c3936769f7a0ddea7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@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

View File

@ -0,0 +1,133 @@
From f476acbe3c2830e6ff0c50cc36d364a3f3f4fadb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@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

View File

@ -0,0 +1,62 @@
From 82c23fb1f0d9e46c6ce4bc4a57f0d377cc6089b7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@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

View File

@ -1,114 +0,0 @@
From d55e2d086d1ff30c427fa5e0ecc79746de8a81b7 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Fri, 9 Apr 2021 15:19:28 +0100
Subject: [PATCH] Handle DHCPREBIND requests in the DHCPv6 server.
Patch by srk, based on submitted patch from liaichun@huawei.com
---
src/rfc3315.c | 60 +++++++++++++++++++++++++++++++++++----------------
1 files changed, 42 insertions(+), 18 deletions(-)
diff --git a/src/rfc3315.c b/src/rfc3315.c
index 982c68a..5c2ff97 100644
--- a/src/rfc3315.c
+++ b/src/rfc3315.c
@@ -919,11 +919,14 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
case DHCP6RENEW:
+ case DHCP6REBIND:
{
+ int address_assigned = 0;
+
/* set reply message type */
*outmsgtypep = DHCP6REPLY;
- log6_quiet(state, "DHCPRENEW", NULL, NULL);
+ log6_quiet(state, msg_type == DHCP6RENEW ? "DHCPRENEW" : "DHCPREBIND", NULL, NULL);
for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end))
{
@@ -952,24 +955,35 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA,
state->iaid, &req_addr)))
{
- /* If the server cannot find a client entry for the IA the server
- returns the IA containing no addresses with a Status Code option set
- to NoBinding in the Reply message. */
- save_counter(iacntr);
- t1cntr = 0;
-
- log6_packet(state, "DHCPREPLY", &req_addr, _("lease not found"));
-
- o1 = new_opt6(OPTION6_STATUS_CODE);
- put_opt6_short(DHCP6NOBINDING);
- put_opt6_string(_("no binding found"));
- end_opt6(o1);
-
- preferred_time = valid_time = 0;
- break;
+ if (msg_type == DHCP6REBIND)
+ {
+ /* When rebinding, we can create a lease if it doesn't exist. */
+ lease = lease6_allocate(&req_addr, state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA);
+ if (lease)
+ lease_set_iaid(lease, state->iaid);
+ else
+ break;
+ }
+ else
+ {
+ /* If the server cannot find a client entry for the IA the server
+ returns the IA containing no addresses with a Status Code option set
+ to NoBinding in the Reply message. */
+ save_counter(iacntr);
+ t1cntr = 0;
+
+ log6_packet(state, "DHCPREPLY", &req_addr, _("lease not found"));
+
+ o1 = new_opt6(OPTION6_STATUS_CODE);
+ put_opt6_short(DHCP6NOBINDING);
+ put_opt6_string(_("no binding found"));
+ end_opt6(o1);
+
+ preferred_time = valid_time = 0;
+ break;
+ }
}
-
if ((this_context = address6_available(state->context, &req_addr, tagif, 1)) ||
(this_context = address6_valid(state->context, &req_addr, tagif, 1)))
{
@@ -1000,6 +1014,8 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
if (preferred_time == 0)
message = _("deprecated");
+
+ address_assigned = 1;
}
else
{
@@ -1022,10 +1038,18 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
end_ia(t1cntr, min_time, 1);
end_opt6(o);
}
+
+ if (!address_assigned && msg_type == DHCP6REBIND)
+ {
+ /* can't create lease for any address, return error */
+ o1 = new_opt6(OPTION6_STATUS_CODE);
+ put_opt6_short(DHCP6NOADDRS);
+ put_opt6_string(_("no addresses available"));
+ end_opt6(o1);
+ }
tagif = add_options(state, 0);
break;
-
}
case DHCP6CONFIRM:
--
2.20.1

View File

@ -0,0 +1,97 @@
From 194e7521399048e37c5c2cff18b9c8d442b893ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Tue, 30 Jun 2020 18:06:29 +0200
Subject: [PATCH] Modify upstream configuration to safe defaults
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 | 29 ++++++++++++++++++++++++-----
1 file changed, 24 insertions(+), 5 deletions(-)
diff --git a/dnsmasq.conf.example b/dnsmasq.conf.example
index bf19424..8b85f44 100644
--- a/dnsmasq.conf.example
+++ b/dnsmasq.conf.example
@@ -22,7 +22,7 @@
# Uncomment these to enable DNSSEC validation and caching:
# (Requires dnsmasq to be built with DNSSEC option.)
-#conf-file=%%PREFIX%%/share/dnsmasq/trust-anchors.conf
+#conf-file=/usr/share/dnsmasq/trust-anchors.conf
#dnssec
# Replies which are not DNSSEC signed may be legitimate, because the domain
@@ -96,14 +96,16 @@
# If you want dnsmasq to change uid and gid to something other
# than the default, edit the following lines.
-#user=
-#group=
+user=dnsmasq
+group=dnsmasq
# If you want dnsmasq to listen for DHCP and DNS requests only on
# specified interfaces (and the loopback) give the name of the
# interface (eg eth0) here.
# Repeat the line for more than one interface.
#interface=
+# Listen only on localhost by default
+interface=lo
# Or you can specify which interface _not_ to listen on
#except-interface=
# Or which to listen on by address (remember to include 127.0.0.1 if
@@ -114,6 +116,10 @@
# disable DHCP and TFTP on it.
#no-dhcp-interface=
+# Serve DNS and DHCP only to networks directly connected to this machine.
+# Any interface= line will override it.
+#local-service
+
# 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,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.
-#bind-interfaces
+#
+# To listen only on localhost and do not receive packets on other
+# 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 +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.
-#dhcp-leasefile=/var/lib/misc/dnsmasq.leases
+#dhcp-leasefile=/var/lib/dnsmasq/dnsmasq.leases
# 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 +688,11 @@
# Include all files in a directory which end in .conf
#conf-dir=/etc/dnsmasq.d/,*.conf
+# Include all files in /etc/dnsmasq.d except RPM backup files
+conf-dir=/etc/dnsmasq.d,.rpmnew,.rpmsave,.rpmorig
+
# If a DHCP client claims that its name is "wpad", ignore that.
# This fixes a security hole. see CERT Vulnerability VU#598349
#dhcp-name-match=set:wpad-ignore,wpad
#dhcp-ignore-names=tag:wpad-ignore
+
--
2.31.1

View File

@ -0,0 +1,26 @@
From bea12dc31409180f6cb3a0578c2340c0116ef003 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Fri, 2 Jul 2021 10:03:47 +0200
Subject: [PATCH] Modify and propagate changed lease
If hostname is reset on existing lease, propagate such change to leases
file and script.
---
src/lease.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/lease.c b/src/lease.c
index b56647d..1a9f1c6 100644
--- a/src/lease.c
+++ b/src/lease.c
@@ -1021,6 +1021,7 @@ void lease_set_hostname(struct dhcp_lease *lease, const char *name, int auth, ch
}
kill_name(lease_tmp);
+ lease_tmp->flags |= LEASE_CHANGED; /* run script on change */
break;
}
}
--
2.31.1

View File

@ -0,0 +1,67 @@
From 068e849c713fa5e95eeb210792c061b7e212eab5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Wed, 13 Oct 2021 16:58:39 +0200
Subject: [PATCH] Ensure serverarray is rebuilt once server can be removed
Because cleanup_servers is called from each place which can remove
server, use that function to refresh serverarray after changes. Make it
static, since it does not have to be called from other places.
---
src/dnsmasq.h | 1 -
src/domain-match.c | 8 +++++++-
src/network.c | 1 -
3 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 08f2785..3f82412 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -1757,7 +1757,6 @@ void dump_packet(int mask, void *packet, size_t len, union mysockaddr *src, unio
#endif
/* domain-match.c */
-void build_server_array(void);
int lookup_domain(char *qdomain, int flags, int *lowout, int *highout);
int filter_servers(int seed, int flags, int *lowout, int *highout);
int is_local_answer(time_t now, int first, char *name);
diff --git a/src/domain-match.c b/src/domain-match.c
index 45528c1..e5b409e 100644
--- a/src/domain-match.c
+++ b/src/domain-match.c
@@ -23,7 +23,7 @@ static int order_servers(struct server *s, struct server *s2);
/* If the server is USE_RESOLV or LITERAL_ADDRES, it lives on the local_domains chain. */
#define SERV_IS_LOCAL (SERV_USE_RESOLV | SERV_LITERAL_ADDRESS)
-void build_server_array(void)
+static void build_server_array(void)
{
struct server *serv;
int count = 0;
@@ -592,6 +592,12 @@ void cleanup_servers(void)
else
up = &serv->next;
}
+
+ /* If we're delaying things, we don't call check_servers(), but
+ reload_servers() may have deleted some servers, rendering the server_array
+ invalid, so just rebuild that here. Once reload_servers() succeeds,
+ we call check_servers() above, which calls build_server_array itself. */
+ build_server_array();
}
int add_update_server(int flags,
diff --git a/src/network.c b/src/network.c
index 3fc179d..0b68866 100644
--- a/src/network.c
+++ b/src/network.c
@@ -1653,7 +1653,6 @@ void check_servers(int no_loop_check)
}
cleanup_servers(); /* remove servers we just deleted. */
- build_server_array();
}
/* Return zero if no servers found, in that case we keep polling.
--
2.31.1

View File

@ -0,0 +1,274 @@
From de372d6914ae20a1f9997815f258efbf3b14c39b Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Sat, 18 Sep 2021 23:01:12 +0100
Subject: [PATCH] Fix confusion is server=/domain/# combined with
server|address=/domain/....
The 2.86 domain matching rewrite failed to take into account the possibilty that
server=/example.com/#
could be combined with, for example
address=/example.com/1.2.3.4
resulting in the struct server datastructure for the former getting passed
to forward_query(), rapidly followed by a SEGV.
This fix makes server=/example.com/# a fully fledged member of the
priority list, which is now IPv6 addr, IPv4 addr, all zero return,
resolvconf servers, upstream servers, no-data return
Thanks to dl6er@dl6er.de for finding and characterising the bug.
---
src/dnsmasq.h | 34 +++++++-------
src/domain-match.c | 113 +++++++++++++++++++++++----------------------
2 files changed, 75 insertions(+), 72 deletions(-)
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 56a3f1d..327ad65 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -530,23 +530,23 @@ union mysockaddr {
/* The actual values here matter, since we sort on them to get records in the order
- IPv6 addr, IPv4 addr, all zero return, no-data return, send upstream. */
-#define SERV_LITERAL_ADDRESS 1 /* addr is the answer, or NoDATA is the answer, depending on the next three flags */
-#define SERV_ALL_ZEROS 2 /* return all zeros for A and AAAA */
-#define SERV_4ADDR 4 /* addr is IPv4 */
-#define SERV_6ADDR 8 /* addr is IPv6 */
-#define SERV_HAS_SOURCE 16 /* source address defined */
-#define SERV_FOR_NODOTS 32 /* server for names with no domain part only */
-#define SERV_WARNED_RECURSIVE 64 /* avoid warning spam */
-#define SERV_FROM_DBUS 128 /* 1 if source is DBus */
-#define SERV_MARK 256 /* for mark-and-delete and log code */
-#define SERV_WILDCARD 512 /* domain has leading '*' */
-#define SERV_USE_RESOLV 1024 /* forward this domain in the normal way */
-#define SERV_FROM_RESOLV 2048 /* 1 for servers from resolv, 0 for command line. */
-#define SERV_FROM_FILE 4096 /* read from --servers-file */
-#define SERV_LOOP 8192 /* server causes forwarding loop */
-#define SERV_DO_DNSSEC 16384 /* Validate DNSSEC when using this server */
-#define SERV_GOT_TCP 32768 /* Got some data from the TCP connection */
+ IPv6 addr, IPv4 addr, all zero return, resolvconf servers, upstream server, no-data return */
+#define SERV_LITERAL_ADDRESS 1 /* addr is the answer, or NoDATA is the answer, depending on the next four flags */
+#define SERV_USE_RESOLV 2 /* forward this domain in the normal way */
+#define SERV_ALL_ZEROS 4 /* return all zeros for A and AAAA */
+#define SERV_4ADDR 8 /* addr is IPv4 */
+#define SERV_6ADDR 16 /* addr is IPv6 */
+#define SERV_HAS_SOURCE 32 /* source address defined */
+#define SERV_FOR_NODOTS 64 /* server for names with no domain part only */
+#define SERV_WARNED_RECURSIVE 128 /* avoid warning spam */
+#define SERV_FROM_DBUS 256 /* 1 if source is DBus */
+#define SERV_MARK 512 /* for mark-and-delete and log code */
+#define SERV_WILDCARD 1024 /* domain has leading '*' */
+#define SERV_FROM_RESOLV 2048 /* 1 for servers from resolv, 0 for command line. */
+#define SERV_FROM_FILE 4096 /* read from --servers-file */
+#define SERV_LOOP 8192 /* server causes forwarding loop */
+#define SERV_DO_DNSSEC 16384 /* Validate DNSSEC when using this server */
+#define SERV_GOT_TCP 32768 /* Got some data from the TCP connection */
struct serverfd {
int fd;
diff --git a/src/domain-match.c b/src/domain-match.c
index b22948c..8f29621 100644
--- a/src/domain-match.c
+++ b/src/domain-match.c
@@ -207,16 +207,16 @@ int lookup_domain(char *domain, int flags, int *lowout, int *highout)
}
}
- if (found)
+ if (found && filter_servers(try, flags, &nlow, &nhigh))
+ /* We have a match, but it may only be (say) an IPv6 address, and
+ if the query wasn't for an AAAA record, it's no good, and we need
+ to continue generalising */
{
/* We've matched a setting which says to use servers without a domain.
Continue the search with empty query */
- if (daemon->serverarray[try]->flags & SERV_USE_RESOLV)
+ if (daemon->serverarray[nlow]->flags & SERV_USE_RESOLV)
crop_query = qlen;
- else if (filter_servers(try, flags, &nlow, &nhigh))
- /* We have a match, but it may only be (say) an IPv6 address, and
- if the query wasn't for an AAAA record, it's no good, and we need
- to continue generalising */
+ else
break;
}
}
@@ -273,7 +273,7 @@ int filter_servers(int seed, int flags, int *lowout, int *highout)
nlow--;
while (nhigh < daemon->serverarraysz-1 && order_servers(daemon->serverarray[nhigh], daemon->serverarray[nhigh+1]) == 0)
- nhigh++;
+ nhigh++;
nhigh++;
@@ -293,10 +293,10 @@ int filter_servers(int seed, int flags, int *lowout, int *highout)
else
{
/* Now the servers are on order between low and high, in the order
- IPv6 addr, IPv4 addr, return zero for both, send upstream, no-data return.
+ IPv6 addr, IPv4 addr, return zero for both, resolvconf servers, send upstream, no-data return.
See which of those match our query in that priority order and narrow (low, high) */
-
+
for (i = nlow; i < nhigh && (daemon->serverarray[i]->flags & SERV_6ADDR); i++);
if (i != nlow && (flags & F_IPV6))
@@ -321,32 +321,40 @@ int filter_servers(int seed, int flags, int *lowout, int *highout)
{
nlow = i;
- /* now look for a server */
- for (i = nlow; i < nhigh && !(daemon->serverarray[i]->flags & SERV_LITERAL_ADDRESS); i++);
-
+ /* Short to resolv.conf servers */
+ for (i = nlow; i < nhigh && (daemon->serverarray[i]->flags & SERV_USE_RESOLV); i++);
+
if (i != nlow)
- {
- /* If we want a server that can do DNSSEC, and this one can't,
- return nothing, similarly if were looking only for a server
- for a particular domain. */
- if ((flags & F_DNSSECOK) && !(daemon->serverarray[nlow]->flags & SERV_DO_DNSSEC))
- nlow = nhigh;
- else if ((flags & F_DOMAINSRV) && daemon->serverarray[nlow]->domain_len == 0)
- nlow = nhigh;
- else
- nhigh = i;
- }
+ nhigh = i;
else
{
- /* --local=/domain/, only return if we don't need a server. */
- if (flags & (F_DNSSECOK | F_DOMAINSRV | F_SERVER))
- nhigh = i;
+ /* now look for a server */
+ for (i = nlow; i < nhigh && !(daemon->serverarray[i]->flags & SERV_LITERAL_ADDRESS); i++);
+
+ if (i != nlow)
+ {
+ /* If we want a server that can do DNSSEC, and this one can't,
+ return nothing, similarly if were looking only for a server
+ for a particular domain. */
+ if ((flags & F_DNSSECOK) && !(daemon->serverarray[nlow]->flags & SERV_DO_DNSSEC))
+ nlow = nhigh;
+ else if ((flags & F_DOMAINSRV) && daemon->serverarray[nlow]->domain_len == 0)
+ nlow = nhigh;
+ else
+ nhigh = i;
+ }
+ else
+ {
+ /* --local=/domain/, only return if we don't need a server. */
+ if (flags & (F_DNSSECOK | F_DOMAINSRV | F_SERVER))
+ nhigh = i;
+ }
}
}
}
}
}
-
+
*lowout = nlow;
*highout = nhigh;
@@ -521,10 +529,10 @@ static int order_qsort(const void *a, const void *b)
/* Sort all literal NODATA and local IPV4 or IPV6 responses together,
in a very specific order. We flip the SERV_LITERAL_ADDRESS bit
so the order is IPv6 literal, IPv4 literal, all-zero literal,
- upstream server, NXDOMAIN literal. */
+ unqualified servers, upstream server, NXDOMAIN literal. */
if (rc == 0)
- rc = ((s2->flags & (SERV_LITERAL_ADDRESS | SERV_4ADDR | SERV_6ADDR | SERV_ALL_ZEROS)) ^ SERV_LITERAL_ADDRESS) -
- ((s1->flags & (SERV_LITERAL_ADDRESS | SERV_4ADDR | SERV_6ADDR | SERV_ALL_ZEROS)) ^ SERV_LITERAL_ADDRESS);
+ rc = ((s2->flags & (SERV_LITERAL_ADDRESS | SERV_4ADDR | SERV_6ADDR | SERV_USE_RESOLV | SERV_ALL_ZEROS)) ^ SERV_LITERAL_ADDRESS) -
+ ((s1->flags & (SERV_LITERAL_ADDRESS | SERV_4ADDR | SERV_6ADDR | SERV_USE_RESOLV | SERV_ALL_ZEROS)) ^ SERV_LITERAL_ADDRESS);
/* Finally, order by appearance in /etc/resolv.conf etc, for --strict-order */
if (rc == 0)
@@ -634,7 +642,7 @@ int add_update_server(int flags,
{
size_t size;
- if (flags & SERV_LITERAL_ADDRESS)
+ if (flags & SERV_IS_LOCAL)
{
if (flags & SERV_6ADDR)
size = sizeof(struct serv_addr6);
@@ -656,10 +664,19 @@ int add_update_server(int flags,
{
serv->next = daemon->local_domains;
daemon->local_domains = serv;
+
+ if (flags & SERV_4ADDR)
+ ((struct serv_addr4*)serv)->addr = local_addr->addr4;
+
+ if (flags & SERV_6ADDR)
+ ((struct serv_addr6*)serv)->addr = local_addr->addr6;
}
else
{
struct server *s;
+
+ memset(serv, 0, sizeof(struct server));
+
/* Add to the end of the chain, for order */
if (!daemon->servers)
daemon->servers = serv;
@@ -669,37 +686,23 @@ int add_update_server(int flags,
s->next = serv;
}
- serv->next = NULL;
+#ifdef HAVE_LOOP
+ serv->uid = rand32();
+#endif
+
+ if (interface)
+ safe_strncpy(serv->interface, interface, sizeof(serv->interface));
+ if (addr)
+ serv->addr = *addr;
+ if (source_addr)
+ serv->source_addr = *source_addr;
}
}
- if (!(flags & SERV_IS_LOCAL))
- memset(serv, 0, sizeof(struct server));
-
serv->flags = flags;
serv->domain = alloc_domain;
serv->domain_len = strlen(alloc_domain);
- if (flags & SERV_4ADDR)
- ((struct serv_addr4*)serv)->addr = local_addr->addr4;
-
- if (flags & SERV_6ADDR)
- ((struct serv_addr6*)serv)->addr = local_addr->addr6;
-
- if (!(flags & SERV_IS_LOCAL))
- {
-#ifdef HAVE_LOOP
- serv->uid = rand32();
-#endif
-
- if (interface)
- safe_strncpy(serv->interface, interface, sizeof(serv->interface));
- if (addr)
- serv->addr = *addr;
- if (source_addr)
- serv->source_addr = *source_addr;
- }
-
return 1;
}
--
2.31.1

View File

@ -0,0 +1,33 @@
From 6ad1f6f44e77619eeb1f9f16e205c24a1dc3e68b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Thu, 14 Oct 2021 20:56:17 +0200
Subject: [PATCH] Compare order case insensitive
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
DNS labels are defined case insensitive. When queried over TCP, query
name is not put to lower case. Make it match even when domain differs
only by used case.
Signed-off-by: Petr Menšík <pemensik@redhat.com>
---
src/domain-match.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/domain-match.c b/src/domain-match.c
index e5b409e..3a69aa1 100644
--- a/src/domain-match.c
+++ b/src/domain-match.c
@@ -495,7 +495,7 @@ static int order(char *qdomain, size_t qlen, struct server *serv)
if (qlen > dlen)
return -1;
- return strcmp(qdomain, serv->domain);
+ return strcasecmp(qdomain, serv->domain);
}
static int order_servers(struct server *s1, struct server *s2)
--
2.31.1

View File

@ -7,40 +7,39 @@ Conflict: NA
Reference: NA Reference: NA
--- ---
src/dnsmasq.c | 2 +- src/dnsmasq.c | 1 +
src/dnsmasq.h | 4 ++- src/dnsmasq.h | 4 +++-
src/option.c | 5 +++- src/option.c | 3 +++
src/rfc3315.c | 35 +++++++++++++++++++++++++- src/rfc3315.c | 35 ++++++++++++++++++++++++++++++++++-
4 files changed, 46 insertions(+) 4 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/src/dnsmasq.c b/src/dnsmasq.c diff --git a/src/dnsmasq.c b/src/dnsmasq.c
index fc085eb..e44c360 100644 index bbdcaae..6e65e92 100644
--- a/src/dnsmasq.c --- a/src/dnsmasq.c
+++ b/src/dnsmasq.c +++ b/src/dnsmasq.c
@@ -260,7 +260,7 @@ int main (int argc, char **argv) @@ -282,6 +282,7 @@ int main (int argc, char **argv)
if (daemon->dhcp6)
{ {
daemon->doing_ra = option_bool(OPT_RA); daemon->doing_ra = option_bool(OPT_RA);
-
+ daemon->bind_mac_with_ip6 = option_bool(OPT_BIND_MAC_IP6); + daemon->bind_mac_with_ip6 = option_bool(OPT_BIND_MAC_IP6);
for (context = daemon->dhcp6; context; context = context->next) for (context = daemon->dhcp6; context; context = context->next)
{ {
if (context->flags & CONTEXT_DHCP) if (context->flags & CONTEXT_DHCP)
diff --git a/src/dnsmasq.h b/src/dnsmasq.h diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 68e6287..e7f1a0d 100644 index 3f82412..f1d2521 100644
--- a/src/dnsmasq.h --- a/src/dnsmasq.h
+++ b/src/dnsmasq.h +++ b/src/dnsmasq.h
@@ -269,7 +269,8 @@ struct event_desc { @@ -275,7 +275,8 @@ struct event_desc {
#define OPT_SINGLE_PORT 60 #define OPT_UMBRELLA_DEVID 64
#define OPT_LEASE_RENEW 61 #define OPT_CMARK_ALST_EN 65
#define OPT_LOG_DEBUG 62 #define OPT_QUIET_TFTP 66
-#define OPT_LAST 63 -#define OPT_LAST 67
+#define OPT_BIND_MAC_IP6 63 +#define OPT_BIND_MAC_IP6 67
+#define OPT_LAST 64 +#define OPT_LAST 68
#define OPTION_BITS (sizeof(unsigned int)*8) #define OPTION_BITS (sizeof(unsigned int)*8)
#define OPTION_SIZE ( (OPT_LAST/OPTION_BITS)+((OPT_LAST%OPTION_BITS)!=0) ) #define OPTION_SIZE ( (OPT_LAST/OPTION_BITS)+((OPT_LAST%OPTION_BITS)!=0) )
@@ -1049,6 +1050,7 @@ extern struct daemon { @@ -1139,6 +1140,7 @@ extern struct daemon {
int override; int override;
int enable_pxe; int enable_pxe;
int doing_ra, doing_dhcp6; int doing_ra, doing_dhcp6;
@ -49,37 +48,35 @@ index 68e6287..e7f1a0d 100644
struct dhcp_netid_list *force_broadcast, *bootp_dynamic; struct dhcp_netid_list *force_broadcast, *bootp_dynamic;
struct hostsfile *dhcp_hosts_file, *dhcp_opts_file, *dynamic_dirs; struct hostsfile *dhcp_hosts_file, *dhcp_opts_file, *dynamic_dirs;
diff --git a/src/option.c b/src/option.c diff --git a/src/option.c b/src/option.c
index 1f698da..f02d389 100644 index 11655fd..9c407f4 100644
--- a/src/option.c --- a/src/option.c
+++ b/src/option.c +++ b/src/option.c
@@ -167,7 +167,8 @@ struct myoption { @@ -174,6 +174,7 @@ struct myoption {
#define LOPT_PXE_VENDOR 361 #define LOPT_CMARK_ALST_EN 365
#define LOPT_DYNHOST 362 #define LOPT_CMARK_ALST 366
#define LOPT_LOG_DEBUG 363 #define LOPT_QUIET_TFTP 367
- +#define LOPT_BIND_MAC_IP6 368
+#define LOPT_BIND_MAC_IP6 364
+
#ifdef HAVE_GETOPT_LONG #ifdef HAVE_GETOPT_LONG
static const struct option opts[] = static const struct option opts[] =
#else @@ -353,6 +354,7 @@ static const struct myoption opts[] =
@@ -339,6 +340,7 @@ static const struct myoption opts[] =
{ "dhcp-ignore-clid", 0, 0, LOPT_IGNORE_CLID },
{ "dynamic-host", 1, 0, LOPT_DYNHOST },
{ "log-debug", 0, 0, LOPT_LOG_DEBUG }, { "log-debug", 0, 0, LOPT_LOG_DEBUG },
{ "umbrella", 2, 0, LOPT_UMBRELLA },
{ "quiet-tftp", 0, 0, LOPT_QUIET_TFTP },
+ { "bind-mac-with-ip6", 0, 0 , LOPT_BIND_MAC_IP6 }, + { "bind-mac-with-ip6", 0, 0 , LOPT_BIND_MAC_IP6 },
{ NULL, 0, 0, 0 } { NULL, 0, 0, 0 }
}; };
@@ -518,6 +520,7 @@ static struct { @@ -539,6 +541,7 @@ static struct {
{ LOPT_DUMPFILE, ARG_ONE, "<path>", gettext_noop("Path to debug packet dump file"), NULL },
{ LOPT_DUMPMASK, ARG_ONE, "<hex>", gettext_noop("Mask which packets to dump"), NULL },
{ LOPT_SCRIPT_TIME, OPT_LEASE_RENEW, NULL, gettext_noop("Call dhcp-script when lease expiry changes."), NULL }, { LOPT_SCRIPT_TIME, OPT_LEASE_RENEW, NULL, gettext_noop("Call dhcp-script when lease expiry changes."), NULL },
{ LOPT_UMBRELLA, ARG_ONE, "[=<optspec>]", gettext_noop("Send Cisco Umbrella identifiers including remote IP."), NULL },
{ LOPT_QUIET_TFTP, OPT_QUIET_TFTP, NULL, gettext_noop("Do not log routine TFTP."), NULL },
+ { LOPT_BIND_MAC_IP6, OPT_BIND_MAC_IP6, NULL, gettext_noop("Bind mac with ipv6 address. This is an experimental feature and it conflicts with rfc3315."), NULL }, + { LOPT_BIND_MAC_IP6, OPT_BIND_MAC_IP6, NULL, gettext_noop("Bind mac with ipv6 address. This is an experimental feature and it conflicts with rfc3315."), NULL },
{ 0, 0, NULL, NULL, NULL } { 0, 0, NULL, NULL, NULL }
}; };
diff --git a/src/rfc3315.c b/src/rfc3315.c diff --git a/src/rfc3315.c b/src/rfc3315.c
index b3f0a0a..a5a092c 100644 index 5c2ff97..b0e6e57 100644
--- a/src/rfc3315.c --- a/src/rfc3315.c
+++ b/src/rfc3315.c +++ b/src/rfc3315.c
@@ -49,6 +49,7 @@ static void end_ia(int t1cntr, unsigned int min_time, int do_fuzz); @@ -49,6 +49,7 @@ static void end_ia(int t1cntr, unsigned int min_time, int do_fuzz);
@ -100,7 +97,7 @@ index b3f0a0a..a5a092c 100644
{ {
mark_config_used(state->context, &addr); mark_config_used(state->context, &addr);
if (have_config(config, CONFIG_TIME)) if (have_config(config, CONFIG_TIME))
@@ -1259,6 +1261,37 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_ @@ -1283,6 +1285,37 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
} }
@ -140,3 +137,4 @@ index b3f0a0a..a5a092c 100644
void *oro; void *oro;
-- --
2.23.0 2.23.0

Binary file not shown.

BIN
dnsmasq-2.86.tar.xz Normal file

Binary file not shown.

View File

@ -1,9 +1,13 @@
[Unit] [Unit]
Description=DNS caching server. Description=DNS caching server.
Before=nss-lookup.target
Wants=nss-lookup.target
After=network.target After=network.target
[Service] [Service]
ExecStart=/usr/sbin/dnsmasq -k ExecStart=/usr/sbin/dnsmasq
Type=forking
PIDFile=/run/dnsmasq.pid
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

View File

@ -1,5 +1,5 @@
Name: dnsmasq Name: dnsmasq
Version: 2.85 Version: 2.86
Release: 1 Release: 1
Summary: Dnsmasq provides network infrastructure for small networks Summary: Dnsmasq provides network infrastructure for small networks
License: GPLv2 or GPLv3 License: GPLv2 or GPLv3
@ -8,11 +8,30 @@ Source0: http://www.thekelleys.org.uk/dnsmasq/%{name}-%{version}.tar.xz
Source1: dnsmasq.service Source1: dnsmasq.service
Source2: dnsmasq-systemd-sysusers.conf Source2: dnsmasq-systemd-sysusers.conf
Patch1: dnsmasq-2.77-underflow.patch Patch1: backport-dnsmasq-2.77-underflow.patch
Patch2: dnsmasq-2.78-fips.patch Patch2: backport-dnsmasq-2.81-configuration.patch
Patch3: bugfix-allow-binding-mac-with-ipv6.patch Patch3: backport-dnsmasq-2.78-fips.patch
Patch4: bugfix-deal-with-CONFRIM-when-binding-mac-with-ipv6.patch Patch4: backport-0001-Retry-on-interrupted-error-in-tftp.patch
Patch14: backport-Handle-DHCPREBIND-requests-in-the-DHCPv6-server.patch Patch5: backport-0002-Add-safety-checks-to-places-pointed-by-Coverity.patch
Patch6: backport-0003-Small-safeguard-to-unexpected-data.patch
Patch7: backport-0004-Fix-bunch-of-warnings-in-auth.c.patch
Patch8: backport-0005-Fix-few-coverity-warnings-in-lease-tools.patch
Patch9: backport-0006-Fix-coverity-formats-issues-in-blockdata.patch
Patch10: backport-0007-Retry-dhcp6-ping-on-interrupts.patch
Patch11: backport-0008-Fix-coverity-warnings-on-dbus.patch
Patch12: backport-0009-Address-coverity-issues-detected-in-util.c.patch
Patch13: backport-0010-Fix-coverity-detected-issues-in-option.c.patch
Patch14: backport-0011-Fix-coverity-detected-issue-in-radv.c.patch
Patch15: backport-0012-Fix-coverity-detected-issues-in-cache.c.patch
Patch16: backport-0013-Fix-coverity-issues-detected-in-domain-match.c.patch
Patch17: backport-0014-Fix-coverity-detected-issues-in-dnsmasq.c.patch
Patch18: backport-0015-Fix-coverity-issues-in-dnssec.c.patch
Patch19: backport-dnsmasq-2.86-domain-match-local.patch
Patch20: backport-dnsmasq-2.86-build_server_array.patch
Patch21: backport-dnsmasq-2.87-tcp-strcasecmp.patch
Patch22: bugfix-allow-binding-mac-with-ipv6.patch
Patch23: bugfix-deal-with-CONFRIM-when-binding-mac-with-ipv6.patch
BuildRequires: gcc BuildRequires: gcc
BuildRequires: dbus-devel pkgconfig libidn2-devel nettle-devel systemd BuildRequires: dbus-devel pkgconfig libidn2-devel nettle-devel systemd
@ -42,15 +61,11 @@ 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" sed -i 's|/var/lib/misc/dnsmasq.leases|/var/lib/dnsmasq/dnsmasq.leases|g' "$file"
done done
sed -i 's|#user=|user=dnsmasq|;s|#group=|group=dnsmasq|;s|%%%%PREFIX%%%%|%{_prefix}|' dnsmasq.conf.example
sed -i 's|#define CHGRP "dip"|#define CHGRP "dnsmasq"|' src/config.h sed -i 's|#define CHGRP "dip"|#define CHGRP "dnsmasq"|' src/config.h
sed -i 's|#define CHUSER "nobody"|#define CHUSER "dnsmasq"|' src/config.h sed -i 's|#define CHUSER "nobody"|#define CHUSER "dnsmasq"|' src/config.h
sed -i "s|\(#\s*define RUNFILE\) \"/var/run/dnsmasq.pid\"|\1 \"%{_rundir}/dnsmasq.pid\"|" src/config.h
sed -i 's|^COPTS[[:space:]]*=|\0 -DHAVE_DBUS -DHAVE_LIBIDN2 -DHAVE_DNSSEC|' Makefile sed -i 's|^COPTS[[:space:]]*=|\0 -DHAVE_DBUS -DHAVE_LIBIDN2 -DHAVE_DNSSEC|' Makefile
cat << EOF >> dnsmasq.conf.example
conf-dir=/etc/dnsmasq.d,.rpmnew,.rpmsave,.rpmorig
EOF
%build %build
%make_build CFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_LD_FLAGS" %make_build CFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_LD_FLAGS"
%make_build -C contrib/lease-tools CFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_LD_FLAGS" %make_build -C contrib/lease-tools CFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_LD_FLAGS"
@ -106,6 +121,9 @@ install -Dpm644 %{SOURCE2} $RPM_BUILD_ROOT%{_sysusersdir}/dnsmasq.conf
%{_mandir}/man8/dnsmasq* %{_mandir}/man8/dnsmasq*
%changelog %changelog
* Tue Mar 22 2022 yanglu <yanglu72@h-partners.com> - 2.86-1
- update dnsmasq to 2.86
* Wed Jul 14 2021 gaihuiying <gaihuiying1@huawei.com> - 2.85-1 * Wed Jul 14 2021 gaihuiying <gaihuiying1@huawei.com> - 2.85-1
- update dnsmasq to 2.85 - update dnsmasq to 2.85