Update to 2.87 (#2129658)

This commit is contained in:
Petr Menšík 2022-09-27 15:35:46 +02:00
parent e28b110acb
commit fb936db8eb
28 changed files with 27 additions and 3098 deletions

2
.gitignore vendored
View File

@ -44,3 +44,5 @@ dnsmasq-2.52.tar.lzma
/dnsmasq-2.85.tar.xz.asc
/dnsmasq-2.86.tar.xz
/dnsmasq-2.86.tar.xz.asc
/dnsmasq-2.87.tar.xz
/dnsmasq-2.87.tar.xz.asc

View File

@ -1,35 +0,0 @@
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

@ -1,77 +0,0 @@
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

@ -1,28 +0,0 @@
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

@ -1,153 +0,0 @@
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

@ -1,148 +0,0 @@
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

@ -1,48 +0,0 @@
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

@ -1,32 +0,0 @@
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

@ -1,131 +0,0 @@
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

@ -1,110 +0,0 @@
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

@ -1,236 +0,0 @@
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

@ -1,54 +0,0 @@
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

@ -1,41 +0,0 @@
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

@ -1,134 +0,0 @@
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

@ -1,133 +0,0 @@
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

@ -1,62 +0,0 @@
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,16 +1,15 @@
From 77c7cabbeab1fbe1f7296f33762771f208586e59 Mon Sep 17 00:00:00 2001
From 46b9670a418419d9e04bbe9a0d6c5a85f3c63265 Mon Sep 17 00:00:00 2001
From: Doran Moppert <dmoppert@redhat.com>
Date: Tue, 26 Sep 2017 14:48:20 +0930
Subject: [PATCH] google patch hand-applied
---
src/edns0.c | 10 +++++-----
src/forward.c | 4 ++++
src/rfc1035.c | 3 +++
3 files changed, 12 insertions(+), 5 deletions(-)
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/src/edns0.c b/src/edns0.c
index 7bd26b8..7f96414 100644
index c498eb1..0eb3873 100644
--- a/src/edns0.c
+++ b/src/edns0.c
@@ -212,11 +212,11 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
@ -30,26 +29,11 @@ index 7bd26b8..7f96414 100644
memcpy(p, buff, rdlen);
free(buff);
p += rdlen;
diff --git a/src/forward.c b/src/forward.c
index 3d638e4..e254e35 100644
--- a/src/forward.c
+++ b/src/forward.c
@@ -1558,6 +1558,10 @@ void receive_query(struct listener *listen, time_t now)
udp_size = PACKETSZ; /* Sanity check - can't reduce below default. RFC 6891 6.2.3 */
}
+ // Make sure the udp size is not smaller than the incoming message so that we
+ // do not underflow
+ if (udp_size < n) udp_size = n;
+
#ifdef HAVE_CONNTRACK
#ifdef HAVE_AUTH
if (!auth_dns || local_auth)
diff --git a/src/rfc1035.c b/src/rfc1035.c
index 6fc4f26..66fa00c 100644
index 60ef272..93701f6 100644
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -1396,6 +1396,9 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
@@ -1411,6 +1411,9 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
size_t len;
int rd_bit = (header->hb3 & HB3_RD);
@ -60,5 +44,5 @@ index 6fc4f26..66fa00c 100644
if (ntohs(header->ancount) != 0 ||
ntohs(header->nscount) != 0 ||
--
2.31.1
2.37.3

View File

@ -1,536 +0,0 @@
From d571d74b63382f52572f2b060c8caf867dea76dc Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Wed, 31 Jul 2019 17:23:45 +0200
Subject: [PATCH] Fix TCP listener after interface is recreated
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Squashed commit of the following:
commit 023433cad60a47bf83037cd8f8d403d1086163e0
Author: Petr Menšík <pemensik@redhat.com>
Date: Mon Jul 15 17:16:44 2019 +0200
Remove duplicate address family from listener
Since address already contain family, remove separate family from
listener. Use now family from address itself.
commit d9b9235139b15a953ba9220e1d33a62d853f4e73
Author: Petr Menšík <pemensik@redhat.com>
Date: Mon Jul 15 17:13:12 2019 +0200
Handle listening on duplicate addresses
Save listening address into listener. Use it to find existing listeners
before creating new one. If it exist, increase just used counter.
Release only listeners not already used.
Duplicates family in listener.
commit a9836313966ecb0689c52bbc4ddbc7a78f7bb677
Author: Petr Mensik <pemensik@redhat.com>
Date: Tue Jul 9 14:05:59 2019 +0200
Cleanup interfaces no longer available
Clean addresses and interfaces not found after enumerate. Free unused
records to speed up checking active interfaces and reduce used memory.
commit 1474c5146b6278fc61df385a8e08b23ccc11b1ab
Author: Petr Mensik <pemensik@redhat.com>
Date: Wed Jul 3 17:02:16 2019 +0200
Compare address and interface index for allowed interface
If interface is recreated with the same address but different index, it
would not change any other parameter.
Test also address family on incoming TCP queries.
commit 94b2f5d33e043652a00b8c70e573994925cd26fe
Author: Petr Mensik <pemensik@redhat.com>
Date: Thu Jul 4 20:28:08 2019 +0200
Log listening on new interfaces
Log in debug mode listening on interfaces. They can be dynamically
found, include interface number, since it is checked on TCP connections.
Print also addresses found on them.
---
src/dnsmasq.c | 3 +-
src/dnsmasq.h | 3 +-
src/forward.c | 27 +++++-----
src/network.c | 147 +++++++++++++++++++++++++++++++++++++++++---------
src/tftp.c | 29 +++++-----
5 files changed, 155 insertions(+), 54 deletions(-)
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
index 769e063..4755125 100644
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -1820,7 +1820,8 @@ static void check_dns_listeners(time_t now)
addr.addr4 = tcp_addr.in.sin_addr;
for (iface = daemon->interfaces; iface; iface = iface->next)
- if (iface->index == if_index)
+ if (iface->index == if_index &&
+ iface->addr.sa.sa_family == tcp_addr.sa.sa_family)
break;
if (!iface && !loopback_exception(listener->tcpfd, tcp_addr.sa.sa_family, &addr, intr_name))
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index c46bfeb..17b5f4e 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -569,7 +569,8 @@ struct irec {
};
struct listener {
- int fd, tcpfd, tftpfd, family;
+ int fd, tcpfd, tftpfd, used;
+ union mysockaddr addr;
struct irec *iface; /* only sometimes valid for non-wildcard */
struct listener *next;
};
diff --git a/src/forward.c b/src/forward.c
index 77059ed..043c2e2 100644
--- a/src/forward.c
+++ b/src/forward.c
@@ -1279,8 +1279,9 @@ void receive_query(struct listener *listen, time_t now)
CMSG_SPACE(sizeof(struct sockaddr_dl))];
#endif
} control_u;
+ int family = listen->addr.sa.sa_family;
/* Can always get recvd interface for IPv6 */
- int check_dst = !option_bool(OPT_NOWILD) || listen->family == AF_INET6;
+ int check_dst = !option_bool(OPT_NOWILD) || family == AF_INET6;
/* packet buffer overwritten */
daemon->srv_save = NULL;
@@ -1292,7 +1293,7 @@ void receive_query(struct listener *listen, time_t now)
{
auth_dns = listen->iface->dns_auth;
- if (listen->family == AF_INET)
+ if (family == AF_INET)
{
dst_addr_4 = dst_addr.addr4 = listen->iface->addr.in.sin_addr;
netmask = listen->iface->netmask;
@@ -1322,9 +1323,9 @@ void receive_query(struct listener *listen, time_t now)
information disclosure. */
memset(daemon->packet + n, 0, daemon->edns_pktsz - n);
- source_addr.sa.sa_family = listen->family;
+ source_addr.sa.sa_family = family;
- if (listen->family == AF_INET)
+ if (family == AF_INET)
{
/* Source-port == 0 is an error, we can't send back to that.
http://www.ietf.org/mail-archive/web/dnsop/current/msg11441.html */
@@ -1344,7 +1345,7 @@ void receive_query(struct listener *listen, time_t now)
{
struct addrlist *addr;
- if (listen->family == AF_INET6)
+ if (family == AF_INET6)
{
for (addr = daemon->interface_addrs; addr; addr = addr->next)
if ((addr->flags & ADDRLIST_IPV6) &&
@@ -1382,7 +1383,7 @@ void receive_query(struct listener *listen, time_t now)
return;
#if defined(HAVE_LINUX_NETWORK)
- if (listen->family == AF_INET)
+ if (family == AF_INET)
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
{
@@ -1395,7 +1396,7 @@ void receive_query(struct listener *listen, time_t now)
if_index = p.p->ipi_ifindex;
}
#elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
- if (listen->family == AF_INET)
+ if (family == AF_INET)
{
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
{
@@ -1420,7 +1421,7 @@ void receive_query(struct listener *listen, time_t now)
}
#endif
- if (listen->family == AF_INET6)
+ if (family == AF_INET6)
{
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon->v6pktinfo)
@@ -1441,16 +1442,16 @@ void receive_query(struct listener *listen, time_t now)
if (!indextoname(listen->fd, if_index, ifr.ifr_name))
return;
- if (!iface_check(listen->family, &dst_addr, ifr.ifr_name, &auth_dns))
+ if (!iface_check(family, &dst_addr, ifr.ifr_name, &auth_dns))
{
if (!option_bool(OPT_CLEVERBIND))
enumerate_interfaces(0);
- if (!loopback_exception(listen->fd, listen->family, &dst_addr, ifr.ifr_name) &&
- !label_exception(if_index, listen->family, &dst_addr))
+ if (!loopback_exception(listen->fd, family, &dst_addr, ifr.ifr_name) &&
+ !label_exception(if_index, family, &dst_addr))
return;
}
- if (listen->family == AF_INET && option_bool(OPT_LOCALISE))
+ if (family == AF_INET && option_bool(OPT_LOCALISE))
{
struct irec *iface;
@@ -1495,7 +1496,7 @@ void receive_query(struct listener *listen, time_t now)
#endif
char *types = querystr(auth_dns ? "auth" : "query", type);
- if (listen->family == AF_INET)
+ if (family == AF_INET)
log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff,
(union all_addr *)&source_addr.in.sin_addr, types);
else
diff --git a/src/network.c b/src/network.c
index 881d823..8c4b3bb 100644
--- a/src/network.c
+++ b/src/network.c
@@ -388,10 +388,11 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
/* check whether the interface IP has been added already
we call this routine multiple times. */
for (iface = daemon->interfaces; iface; iface = iface->next)
- if (sockaddr_isequal(&iface->addr, addr))
+ if (sockaddr_isequal(&iface->addr, addr) && iface->index == if_index)
{
iface->dad = !!(iface_flags & IFACE_TENTATIVE);
iface->found = 1; /* for garbage collection */
+ iface->netmask = netmask;
return 1;
}
@@ -532,7 +533,82 @@ static int iface_allowed_v4(struct in_addr local, int if_index, char *label,
return iface_allowed((struct iface_param *)vparam, if_index, label, &addr, netmask, prefix, 0);
}
-
+
+/*
+ * Clean old interfaces no longer found.
+ */
+static void clean_interfaces()
+{
+ struct irec *iface;
+ struct irec **up = &daemon->interfaces;
+
+ for (iface = *up; iface; iface = *up)
+ {
+ if (!iface->found && !iface->done)
+ {
+ *up = iface->next;
+ free(iface->name);
+ free(iface);
+ }
+ else
+ {
+ up = &iface->next;
+ }
+ }
+}
+
+/** Release listener if no other interface needs it.
+ *
+ * @return 1 if released, 0 if still required
+ */
+static int release_listener(struct listener *l)
+{
+ if (l->used > 1)
+ {
+ struct irec *iface;
+ for (iface = daemon->interfaces; iface; iface = iface->next)
+ if (iface->done && sockaddr_isequal(&l->addr, &iface->addr))
+ {
+ if (iface->found)
+ {
+ /* update listener to point to active interface instead */
+ if (!l->iface->found)
+ l->iface = iface;
+ }
+ else
+ {
+ l->used--;
+ iface->done = 0;
+ }
+ }
+
+ /* Someone is still using this listener, skip its deletion */
+ if (l->used > 0)
+ return 0;
+ }
+
+ if (l->iface->done)
+ {
+ int port;
+
+ port = prettyprint_addr(&l->iface->addr, daemon->addrbuff);
+ my_syslog(LOG_DEBUG, _("stopped listening on %s(#%d): %s port %d"),
+ l->iface->name, l->iface->index, daemon->addrbuff, port);
+ /* In case it ever returns */
+ l->iface->done = 0;
+ }
+
+ if (l->fd != -1)
+ close(l->fd);
+ if (l->tcpfd != -1)
+ close(l->tcpfd);
+ if (l->tftpfd != -1)
+ close(l->tftpfd);
+
+ free(l);
+ return 1;
+}
+
int enumerate_interfaces(int reset)
{
static struct addrlist *spare = NULL;
@@ -630,6 +706,7 @@ int enumerate_interfaces(int reset)
in OPT_CLEVERBIND mode, that at listener will just disappear after
a call to enumerate_interfaces, this is checked OK on all calls. */
struct listener *l, *tmp, **up;
+ int freed = 0;
for (up = &daemon->listeners, l = daemon->listeners; l; l = tmp)
{
@@ -637,25 +714,17 @@ int enumerate_interfaces(int reset)
if (!l->iface || l->iface->found)
up = &l->next;
- else
+ else if (release_listener(l))
{
- *up = l->next;
-
- /* In case it ever returns */
- l->iface->done = 0;
-
- if (l->fd != -1)
- close(l->fd);
- if (l->tcpfd != -1)
- close(l->tcpfd);
- if (l->tftpfd != -1)
- close(l->tftpfd);
-
- free(l);
+ *up = tmp;
+ freed = 1;
}
}
+
+ if (freed)
+ clean_interfaces();
}
-
+
errno = errsave;
spare = param.spare;
@@ -893,10 +962,11 @@ static struct listener *create_listeners(union mysockaddr *addr, int do_tftp, in
{
l = safe_malloc(sizeof(struct listener));
l->next = NULL;
- l->family = addr->sa.sa_family;
l->fd = fd;
l->tcpfd = tcpfd;
- l->tftpfd = tftpfd;
+ l->tftpfd = tftpfd;
+ l->addr = *addr;
+ l->used = 1;
l->iface = NULL;
}
@@ -935,20 +1005,43 @@ void create_wildcard_listeners(void)
daemon->listeners = l;
}
+static struct listener *find_listener(union mysockaddr *addr)
+{
+ struct listener *l;
+ for (l = daemon->listeners; l; l = l->next)
+ if (sockaddr_isequal(&l->addr, addr))
+ return l;
+ return NULL;
+}
+
void create_bound_listeners(int dienow)
{
struct listener *new;
struct irec *iface;
struct iname *if_tmp;
+ struct listener *existing;
for (iface = daemon->interfaces; iface; iface = iface->next)
- if (!iface->done && !iface->dad && iface->found &&
- (new = create_listeners(&iface->addr, iface->tftp_ok, dienow)))
+ if (!iface->done && !iface->dad && iface->found)
{
- new->iface = iface;
- new->next = daemon->listeners;
- daemon->listeners = new;
- iface->done = 1;
+ existing = find_listener(&iface->addr);
+ if (existing)
+ {
+ iface->done = 1;
+ existing->used++; /* increase usage counter */
+ }
+ else if ((new = create_listeners(&iface->addr, iface->tftp_ok, dienow)))
+ {
+ int port;
+
+ new->iface = iface;
+ new->next = daemon->listeners;
+ daemon->listeners = new;
+ iface->done = 1;
+ port = prettyprint_addr(&iface->addr, daemon->addrbuff);
+ my_syslog(LOG_DEBUG, _("listening on %s(#%d): %s port %d"),
+ iface->name, iface->index, daemon->addrbuff, port);
+ }
}
/* Check for --listen-address options that haven't been used because there's
@@ -966,8 +1059,12 @@ void create_bound_listeners(int dienow)
if (!if_tmp->used &&
(new = create_listeners(&if_tmp->addr, !!option_bool(OPT_TFTP), dienow)))
{
+ int port;
+
new->next = daemon->listeners;
daemon->listeners = new;
+ port = prettyprint_addr(&if_tmp->addr, daemon->addrbuff);
+ my_syslog(LOG_DEBUG, _("listening on %s port %d"), daemon->addrbuff, port);
}
}
diff --git a/src/tftp.c b/src/tftp.c
index 4c18577..fdd2855 100644
--- a/src/tftp.c
+++ b/src/tftp.c
@@ -61,8 +61,9 @@ void tftp_request(struct listener *listen, time_t now)
char *prefix = daemon->tftp_prefix;
struct tftp_prefix *pref;
union all_addr addra;
+ int family = listen->addr.sa.sa_family;
/* Can always get recvd interface for IPv6 */
- int check_dest = !option_bool(OPT_NOWILD) || listen->family == AF_INET6;
+ int check_dest = !option_bool(OPT_NOWILD) || family == AF_INET6;
union {
struct cmsghdr align; /* this ensures alignment */
char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
@@ -121,10 +122,10 @@ void tftp_request(struct listener *listen, time_t now)
if (msg.msg_controllen < sizeof(struct cmsghdr))
return;
- addr.sa.sa_family = listen->family;
+ addr.sa.sa_family = family;
#if defined(HAVE_LINUX_NETWORK)
- if (listen->family == AF_INET)
+ if (family == AF_INET)
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
{
@@ -138,7 +139,7 @@ void tftp_request(struct listener *listen, time_t now)
}
#elif defined(HAVE_SOLARIS_NETWORK)
- if (listen->family == AF_INET)
+ if (family == AF_INET)
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
{
union {
@@ -154,7 +155,7 @@ void tftp_request(struct listener *listen, time_t now)
}
#elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
- if (listen->family == AF_INET)
+ if (family == AF_INET)
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
{
union {
@@ -171,7 +172,7 @@ void tftp_request(struct listener *listen, time_t now)
#endif
- if (listen->family == AF_INET6)
+ if (family == AF_INET6)
{
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon->v6pktinfo)
@@ -194,7 +195,7 @@ void tftp_request(struct listener *listen, time_t now)
addra.addr4 = addr.in.sin_addr;
- if (listen->family == AF_INET6)
+ if (family == AF_INET6)
addra.addr6 = addr.in6.sin6_addr;
if (daemon->tftp_interfaces)
@@ -210,12 +211,12 @@ void tftp_request(struct listener *listen, time_t now)
else
{
/* Do the same as DHCP */
- if (!iface_check(listen->family, &addra, name, NULL))
+ if (!iface_check(family, &addra, name, NULL))
{
if (!option_bool(OPT_CLEVERBIND))
enumerate_interfaces(0);
- if (!loopback_exception(listen->tftpfd, listen->family, &addra, name) &&
- !label_exception(if_index, listen->family, &addra))
+ if (!loopback_exception(listen->tftpfd, family, &addra, name) &&
+ !label_exception(if_index, family, &addra))
return;
}
@@ -281,7 +282,7 @@ void tftp_request(struct listener *listen, time_t now)
prefix = pref->prefix;
}
- if (listen->family == AF_INET)
+ if (family == AF_INET)
{
addr.in.sin_port = htons(port);
#ifdef HAVE_SOCKADDR_SA_LEN
@@ -304,7 +305,7 @@ void tftp_request(struct listener *listen, time_t now)
if (option_bool(OPT_SINGLE_PORT))
transfer->sockfd = listen->tftpfd;
- else if ((transfer->sockfd = socket(listen->family, SOCK_DGRAM, 0)) == -1)
+ else if ((transfer->sockfd = socket(family, SOCK_DGRAM, 0)) == -1)
{
free(transfer);
return;
@@ -337,7 +338,7 @@ void tftp_request(struct listener *listen, time_t now)
{
if (++port <= daemon->end_tftp_port)
{
- if (listen->family == AF_INET)
+ if (family == AF_INET)
addr.in.sin_port = htons(port);
else
addr.in6.sin6_port = htons(port);
@@ -375,7 +376,7 @@ void tftp_request(struct listener *listen, time_t now)
if ((opt = next(&p, end)) && !option_bool(OPT_TFTP_NOBLOCK))
{
/* 32 bytes for IP, UDP and TFTP headers, 52 bytes for IPv6 */
- int overhead = (listen->family == AF_INET) ? 32 : 52;
+ int overhead = (family == AF_INET) ? 32 : 52;
transfer->blocksize = atoi(opt);
if (transfer->blocksize < 1)
transfer->blocksize = 1;
--
2.21.1

View File

@ -1,26 +0,0 @@
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

@ -1,4 +1,4 @@
From 068e849c713fa5e95eeb210792c061b7e212eab5 Mon Sep 17 00:00:00 2001
From 3ae3f53359a6e40535dac1cfd4887e80331a48fc 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
@ -13,10 +13,10 @@ static, since it does not have to be called from other places.
3 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 08f2785..3f82412 100644
index 36d17fe..e46dba2 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
@@ -1810,7 +1810,6 @@ void dump_packet_icmp(int mask, void *packet, size_t len, union mysockaddr *src,
#endif
/* domain-match.c */
@ -25,7 +25,7 @@ index 08f2785..3f82412 100644
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
index f7db0fe..d5840d9 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);
@ -37,10 +37,10 @@ index 45528c1..e5b409e 100644
{
struct server *serv;
int count = 0;
@@ -592,6 +592,12 @@ void cleanup_servers(void)
else
up = &serv->next;
}
@@ -602,6 +602,12 @@ void cleanup_servers(void)
daemon->servers_tail = serv;
}
}
+
+ /* If we're delaying things, we don't call check_servers(), but
+ reload_servers() may have deleted some servers, rendering the server_array
@ -51,10 +51,10 @@ index 45528c1..e5b409e 100644
int add_update_server(int flags,
diff --git a/src/network.c b/src/network.c
index 3fc179d..0b68866 100644
index 6166484..f9dbcd8 100644
--- a/src/network.c
+++ b/src/network.c
@@ -1653,7 +1653,6 @@ void check_servers(int no_loop_check)
@@ -1701,7 +1701,6 @@ void check_servers(int no_loop_check)
}
cleanup_servers(); /* remove servers we just deleted. */
@ -63,5 +63,5 @@ index 3fc179d..0b68866 100644
/* Return zero if no servers found, in that case we keep polling.
--
2.31.1
2.37.3

View File

@ -1,274 +0,0 @@
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

@ -1,247 +0,0 @@
From e816d085585b95c5f27ceaa5ea74d42f943375f7 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Mon, 3 Jan 2022 23:32:30 +0000
Subject: [PATCH] Fix massive confusion on server reload.
The 2.86 upstream server rewrite severely broke re-reading
of server configuration. It would get everyting right the first
time, but on re-reading /etc/resolv.conf or --servers-file
or setting things with DBUS, the results were just wrong.
This should put things right again.
---
src/domain-match.c | 154 +++++++++++++++++++++++++--------------------
1 file changed, 85 insertions(+), 69 deletions(-)
diff --git a/src/domain-match.c b/src/domain-match.c
index 3a69aa1..f4fd093 100644
--- a/src/domain-match.c
+++ b/src/domain-match.c
@@ -37,7 +37,7 @@ static void build_server_array(void)
if (serv->flags & SERV_WILDCARD)
daemon->server_has_wildcard = 1;
}
-
+
for (serv = daemon->local_domains; serv; serv = serv->next)
{
count++;
@@ -543,22 +543,35 @@ static int order_qsort(const void *a, const void *b)
return rc;
}
+/* Must be called before add_update_server() to set daemon->servers_tail */
void mark_servers(int flag)
{
- struct server *serv;
+ struct server *serv, **up;
/* mark everything with argument flag */
for (serv = daemon->servers; serv; serv = serv->next)
- if (serv->flags & flag)
- serv->flags |= SERV_MARK;
- else
- serv->flags &= ~SERV_MARK;
-
- for (serv = daemon->local_domains; serv; serv = serv->next)
- if (serv->flags & flag)
- serv->flags |= SERV_MARK;
- else
- serv->flags &= ~SERV_MARK;
+ {
+ if (serv->flags & flag)
+ serv->flags |= SERV_MARK;
+ else
+ serv->flags &= ~SERV_MARK;
+ }
+
+ /* --address etc is different: since they are expected to be
+ 1) numerous and 2) not reloaded often. We just delete
+ and recreate. */
+ if (flag)
+ for (serv = daemon->local_domains, up = &daemon->local_domains; serv; serv = serv->next)
+ {
+ if (serv->flags & flag)
+ {
+ *up = serv->next;
+ free(serv->domain);
+ free(serv);
+ }
+ else
+ up = &serv->next;
+ }
}
void cleanup_servers(void)
@@ -566,7 +579,7 @@ void cleanup_servers(void)
struct server *serv, *tmp, **up;
/* unlink and free anything still marked. */
- for (serv = daemon->servers, up = &daemon->servers; serv; serv = tmp)
+ for (serv = daemon->servers, up = &daemon->servers; serv; serv = tmp)
{
tmp = serv->next;
if (serv->flags & SERV_MARK)
@@ -580,19 +593,6 @@ void cleanup_servers(void)
up = &serv->next;
}
- for (serv = daemon->local_domains, up = &daemon->local_domains; serv; serv = tmp)
- {
- tmp = serv->next;
- if (serv->flags & SERV_MARK)
- {
- *up = serv->next;
- free(serv->domain);
- free(serv);
- }
- 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,
@@ -630,56 +630,71 @@ int add_update_server(int flags,
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. */
+
if (flags & SERV_IS_LOCAL)
- for (serv = daemon->servers; serv; serv = serv->next)
- if ((serv->flags & SERV_MARK) &&
- hostname_isequal(alloc_domain, serv->domain))
- break;
-
- if (serv)
- {
- free(alloc_domain);
- alloc_domain = serv->domain;
- }
- else
{
size_t size;
- if (flags & SERV_IS_LOCAL)
- {
- if (flags & SERV_6ADDR)
- size = sizeof(struct serv_addr6);
- else if (flags & SERV_4ADDR)
- size = sizeof(struct serv_addr4);
- else
- size = sizeof(struct serv_local);
- }
+ if (flags & SERV_6ADDR)
+ size = sizeof(struct serv_addr6);
+ else if (flags & SERV_4ADDR)
+ size = sizeof(struct serv_addr4);
else
- size = sizeof(struct server);
+ size = sizeof(struct serv_local);
if (!(serv = whine_malloc(size)))
{
free(alloc_domain);
return 0;
}
-
- if (flags & SERV_IS_LOCAL)
+
+ 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
+ {
+ /* Upstream servers. See if there is a suitable candidate, if so unmark
+ and move to the end of the list, for order. The entry found may already
+ be at the end. */
+ struct server **up, *tmp;
+
+ for (serv = daemon->servers, up = &daemon->servers; serv; serv = tmp)
{
- serv->next = daemon->local_domains;
- daemon->local_domains = serv;
+ tmp = serv->next;
+ if ((serv->flags & SERV_MARK) &&
+ hostname_isequal(alloc_domain, serv->domain))
+ {
+ /* Need to move down? */
+ if (serv->next)
+ {
+ struct server *s;
+ *up = serv->next;
+ for (s = daemon->servers; s->next; s = s->next);
+ s->next = serv;
+ serv->next = NULL;
+ }
+ break;
+ }
+ }
- 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 (serv)
+ {
+ free(alloc_domain);
+ alloc_domain = serv->domain;
}
else
{
- struct server *s;
+ if (!(serv = whine_malloc(sizeof(struct server))))
+ {
+ free(alloc_domain);
+ return 0;
+ }
memset(serv, 0, sizeof(struct server));
@@ -688,23 +703,24 @@ int add_update_server(int flags,
daemon->servers = serv;
else
{
+ struct server *s;
for (s = daemon->servers; s->next; s = s->next);
s->next = serv;
}
+ }
#ifdef HAVE_LOOP
- serv->uid = rand32();
+ 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 (interface)
+ safe_strncpy(serv->interface, interface, sizeof(serv->interface));
+ if (addr)
+ serv->addr = *addr;
+ if (source_addr)
+ serv->source_addr = *source_addr;
}
-
+
serv->flags = flags;
serv->domain = alloc_domain;
serv->domain_len = strlen(alloc_domain);
--
2.34.1

View File

@ -1,90 +0,0 @@
From f0d061c9977d6c9bc2ddd4e6cf6ffe1ed9cd285a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Fri, 17 Jun 2022 11:40:56 +0200
Subject: [PATCH] Correct add_update_server losing first unmarked entries
Beginning of servers list were updated when first server(s) record is
not marked. That was a mistake, which forgot updating also up pointer to
correct value. Move that loop to separate reuse_server function, which
is close to similar loop in cleanup_servers. Makes it easier to compare
and do correct. Removed tmp variable, because this code does not
invalidate previous serv pointer.
Modified for 2.86
---
src/domain-match.c | 52 ++++++++++++++++++++++++++--------------------
1 file changed, 29 insertions(+), 23 deletions(-)
diff --git a/src/domain-match.c b/src/domain-match.c
index f4fd093..8409c4d 100644
--- a/src/domain-match.c
+++ b/src/domain-match.c
@@ -600,6 +600,34 @@ void cleanup_servers(void)
build_server_array();
}
+/* Upstream servers. See if there is a suitable candidate, if so unmark
+ and move to the end of the list, for order. The entry found may already
+ be at the end. */
+static struct server *reuse_server(char *alloc_domain)
+{
+ struct server **up, *serv;
+
+ for (serv = daemon->servers, up = &daemon->servers; serv; serv = serv->next)
+ {
+ if ((serv->flags & SERV_MARK) &&
+ hostname_isequal(alloc_domain, serv->domain))
+ {
+ /* Need to move down? */
+ if (serv->next)
+ {
+ struct server *s;
+ *up = serv->next;
+ for (s = daemon->servers; s->next; s = s->next);
+ s->next = serv;
+ serv->next = NULL;
+ }
+ return serv;
+ }
+ up = &serv->next;
+ }
+ return NULL;
+}
+
int add_update_server(int flags,
union mysockaddr *addr,
union mysockaddr *source_addr,
@@ -659,29 +687,7 @@ int add_update_server(int flags,
}
else
{
- /* Upstream servers. See if there is a suitable candidate, if so unmark
- and move to the end of the list, for order. The entry found may already
- be at the end. */
- struct server **up, *tmp;
-
- for (serv = daemon->servers, up = &daemon->servers; serv; serv = tmp)
- {
- tmp = serv->next;
- if ((serv->flags & SERV_MARK) &&
- hostname_isequal(alloc_domain, serv->domain))
- {
- /* Need to move down? */
- if (serv->next)
- {
- struct server *s;
- *up = serv->next;
- for (s = daemon->servers; s->next; s = s->next);
- s->next = serv;
- serv->next = NULL;
- }
- break;
- }
- }
+ serv = reuse_server(alloc_domain);
if (serv)
{
--
2.35.3

View File

@ -1,62 +0,0 @@
From 1f8f78a49b8fd6b2862a3882053b1c6e6e111e5c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Mon, 10 Jan 2022 12:34:42 +0100
Subject: [PATCH] Add root group writeable flag to log file
Some systems strips even root process capability of writing to different
users file. That include systemd under Fedora. When
log-facility=/var/log/dnsmasq.log is used, log file with mode 0640
is created. But restart then fails, because such log file can be used
only when created new. Existing file cannot be opened by root when
starting, causing fatal error. Avoid that by adding root group writeable flag.
Ensure group is always root when granting write access. If it is
anything else, administrator has to configure correct rights.
---
src/log.c | 23 ++++++++++++++++++-----
1 file changed, 18 insertions(+), 5 deletions(-)
diff --git a/src/log.c b/src/log.c
index 1ec3447..bcd6e52 100644
--- a/src/log.c
+++ b/src/log.c
@@ -100,10 +100,23 @@ int log_start(struct passwd *ent_pw, int errfd)
/* If we're running as root and going to change uid later,
change the ownership here so that the file is always owned by
the dnsmasq user. Then logrotate can just copy the owner.
- Failure of the chown call is OK, (for instance when started as non-root) */
- if (log_to_file && !log_stderr && ent_pw && ent_pw->pw_uid != 0 &&
- fchown(log_fd, ent_pw->pw_uid, -1) != 0)
- ret = errno;
+ Failure of the chown call is OK, (for instance when started as non-root).
+
+ If we've created a file with group-id root, we also make
+ the file group-writable. This gives processes in the root group
+ write access to the file and avoids the problem that on some systems,
+ once the file is owned by the dnsmasq user, it can't be written
+ whilst dnsmasq is running as root during startup.
+ */
+ if (log_to_file && !log_stderr && ent_pw && ent_pw->pw_uid != 0)
+ {
+ struct stat ls;
+ if (getgid() == 0 && fstat(log_fd, &ls) == 0 && ls.st_gid == 0 &&
+ (ls.st_mode & S_IWGRP) == 0)
+ (void)fchmod(log_fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
+ if (fchown(log_fd, ent_pw->pw_uid, -1) != 0)
+ ret = errno;
+ }
return ret;
}
@@ -118,7 +131,7 @@ int log_reopen(char *log_file)
/* NOTE: umask is set to 022 by the time this gets called */
if (log_file)
- log_fd = open(log_file, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IRGRP);
+ log_fd = open(log_file, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IRGRP);
else
{
#if defined(HAVE_SOLARIS_NETWORK) || defined(__ANDROID__)
--
2.31.1

View File

@ -1,33 +0,0 @@
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

@ -19,8 +19,8 @@
%bcond_with sourcegit
Name: dnsmasq
Version: 2.86
Release: 11%{?extraversion:.%{extraversion}}%{?dist}
Version: 2.87
Release: 1%{?extraversion:.%{extraversion}}%{?dist}
Summary: A lightweight DHCP/caching DNS server
License: GPLv2 or GPLv3
@ -35,8 +35,6 @@ Source4: %{url}%{?extrapath}test-release-public-key
%else
Source4: http://www.thekelleys.org.uk/srkgpg.txt
%endif
# https://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2022q2/016325.html
Source5: https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
# https://bugzilla.redhat.com/show_bug.cgi?id=1495409
Patch1: dnsmasq-2.77-underflow.patch
@ -44,36 +42,9 @@ Patch1: dnsmasq-2.77-underflow.patch
Patch2: dnsmasq-2.81-configuration.patch
Patch3: dnsmasq-2.78-fips.patch
Patch10: 0001-Retry-on-interrupted-error-in-tftp.patch
Patch11: 0002-Add-safety-checks-to-places-pointed-by-Coverity.patch
Patch12: 0003-Small-safeguard-to-unexpected-data.patch
Patch13: 0004-Fix-bunch-of-warnings-in-auth.c.patch
Patch14: 0005-Fix-few-coverity-warnings-in-lease-tools.patch
Patch15: 0006-Fix-coverity-formats-issues-in-blockdata.patch
Patch16: 0007-Retry-dhcp6-ping-on-interrupts.patch
Patch17: 0008-Fix-coverity-warnings-on-dbus.patch
Patch18: 0009-Address-coverity-issues-detected-in-util.c.patch
Patch19: 0010-Fix-coverity-detected-issues-in-option.c.patch
Patch20: 0011-Fix-coverity-detected-issue-in-radv.c.patch
Patch21: 0012-Fix-coverity-detected-issues-in-cache.c.patch
Patch22: 0013-Fix-coverity-issues-detected-in-domain-match.c.patch
Patch23: 0014-Fix-coverity-detected-issues-in-dnsmasq.c.patch
Patch24: 0015-Fix-coverity-issues-in-dnssec.c.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2006367
Patch25: dnsmasq-2.86-domain-match-local.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2009975
# replaces/enhances http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=d290630d31f4517ab26392d00753d1397f9a4114
Patch26: dnsmasq-2.86-build_server_array.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2014019
Patch28: dnsmasq-2.87-tcp-strcasecmp.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2024166
# http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=1f8f78a49b8fd6b2862a3882053b1c6e6e111e5c
Patch29: dnsmasq-2.87-root-log-writeable.patch
# https://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2022q1/016166.html
# https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=553c4c99cca173e9964d0edbd0676ed96c30f62b
Patch30: https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=patch;h=553c4c99cca173e9964d0edbd0676ed96c30f62b#/dnsmasq-2.87-resolv.conf-reread.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2061944
Patch31: dnsmasq-2.87-reuse-server.patch
#Patch26: dnsmasq-2.86-build_server_array.patch
@ -134,8 +105,6 @@ git checkout -b rpmbuild
# Apply patches on top
%autopatch -p1
cp -p %{SOURCE5} COPYING
# use /var/lib/dnsmasq instead of /var/lib/misc
for file in dnsmasq.conf.example man/dnsmasq.8 man/es/dnsmasq.8 src/config.h; do
sed -i 's|/var/lib/misc/dnsmasq.leases|/var/lib/dnsmasq/dnsmasq.leases|g' "$file"
@ -218,6 +187,9 @@ install -Dpm 644 %{SOURCE2} %{buildroot}%{_sysusersdir}/%{name}.conf
%{_mandir}/man1/dhcp_*
%changelog
* Tue Sep 27 2022 Petr Menšík <pemensik@redhat.com> - 2.87-1
- Update to 2.87 (#2129658)
* Thu Jul 21 2022 Fedora Release Engineering <releng@fedoraproject.org> - 2.86-11
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild

View File

@ -1,339 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@ -1,2 +1,2 @@
SHA512 (dnsmasq-2.86.tar.xz) = 487eae0afbc8bb3d5282a729ffb0cb2c9bdc7d8e46e2e8aa114cd7c5d82e0fd66f49926e7fa4028577548d6f57e8a865aca17f33963a589874584d608ab2deaf
SHA512 (dnsmasq-2.86.tar.xz.asc) = 852023cd5bf48e5e603288398989c63b3c4724d9d1d8abb0eb0ffcbe526d99f93371e244c706bf249387f337465433d439017fc23cfbdbae030900c2989605e6
SHA512 (dnsmasq-2.87.tar.xz) = 965071ff35aed558a661e7f57ff82de170f4ad7fcdd6a4070ce7915c9f5e41450d8d86b2a0c2c30bf52ddc3aaeb22af18bb6da71a1cccb3c409429ef0ef308f3
SHA512 (dnsmasq-2.87.tar.xz.asc) = 539abb6c5ad50c2e3eaa534dde63be4003b4ed96d471ba9d96fed028d5ddf76111591626de6def823438731c363383282a75139346304f2819aef64a0943a300