summaryrefslogtreecommitdiff
path: root/repo/dnsmasq
diff options
context:
space:
mode:
authordavidovski <david@davidovski.xyz>2022-06-27 23:09:07 +0100
committerdavidovski <david@davidovski.xyz>2022-06-27 23:09:07 +0100
commitf6332a43c35387c4a2dea1746be5fd092890ae0e (patch)
treed6599f63de04096f3fc21a98e0b3bb39d55a3531 /repo/dnsmasq
parentf13e0cac13f90f7f57bce3b26b2e6383de6e4ad2 (diff)
added lf and iptables
Diffstat (limited to 'repo/dnsmasq')
-rw-r--r--repo/dnsmasq/0000-fix-heap-overflow-in-dns-replies.patch66
-rw-r--r--repo/dnsmasq/0001-Retry-on-interrupted-error-in-tftp.patch27
-rw-r--r--repo/dnsmasq/0002-Add-safety-checks-to-places-pointed-by-Coverity.patch45
-rw-r--r--repo/dnsmasq/0003-Small-safeguard-to-unexpected-data.patch30
-rw-r--r--repo/dnsmasq/0004-Fix-bunch-of-warnings-in-auth.c.patch80
-rw-r--r--repo/dnsmasq/0005-Fix-few-coverity-warnings-in-lease-tools.patch92
-rw-r--r--repo/dnsmasq/0006-Fix-coverity-formats-issues-in-blockdata.patch23
-rw-r--r--repo/dnsmasq/0007-Retry-dhcp6-ping-on-interrupts.patch23
-rw-r--r--repo/dnsmasq/0008-Fix-coverity-warnings-on-dbus.patch84
-rw-r--r--repo/dnsmasq/0009-Address-coverity-issues-detected-in-util.c.patch58
-rw-r--r--repo/dnsmasq/0010-Fix-coverity-detected-issues-in-option.c.patch135
-rw-r--r--repo/dnsmasq/0011-Fix-coverity-detected-issue-in-radv.c.patch23
-rw-r--r--repo/dnsmasq/0012-Fix-coverity-detected-issues-in-cache.c.patch23
-rw-r--r--repo/dnsmasq/0013-Fix-coverity-issues-detected-in-domain-match.c.patch60
-rw-r--r--repo/dnsmasq/0014-Fix-coverity-detected-issues-in-dnsmasq.c.patch69
-rw-r--r--repo/dnsmasq/0015-Fix-coverity-issues-in-dnssec.c.patch35
-rw-r--r--repo/dnsmasq/0020-Fix-crash-after-re-reading-empty-resolv.conf.patch38
-rw-r--r--repo/dnsmasq/CVE-2022-0934.patch189
-rw-r--r--repo/dnsmasq/config.h.patch12
-rw-r--r--repo/dnsmasq/dnsmasq-dnssec.pre-install6
-rw-r--r--repo/dnsmasq/dnsmasq-dnssec.pre-upgrade6
-rw-r--r--repo/dnsmasq/dnsmasq.conf.patch38
-rw-r--r--repo/dnsmasq/dnsmasq.confd22
-rw-r--r--repo/dnsmasq/dnsmasq.initd151
-rw-r--r--repo/dnsmasq/dnsmasq.pre-install6
-rw-r--r--repo/dnsmasq/dnsmasq.pre-upgrade6
-rw-r--r--repo/dnsmasq/dnsmasq.xibuild64
27 files changed, 1411 insertions, 0 deletions
diff --git a/repo/dnsmasq/0000-fix-heap-overflow-in-dns-replies.patch b/repo/dnsmasq/0000-fix-heap-overflow-in-dns-replies.patch
new file mode 100644
index 0000000..ab15361
--- /dev/null
+++ b/repo/dnsmasq/0000-fix-heap-overflow-in-dns-replies.patch
@@ -0,0 +1,66 @@
+Patch-Source: https://src.fedoraproject.org/rpms/dnsmasq/blob/f36/f/dnsmasq-2.77-underflow.patch
+--
+From 77c7cabbeab1fbe1f7296f33762771f208586e59 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(-)
+
+diff --git a/src/edns0.c b/src/edns0.c
+index 7bd26b8..7f96414 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
+ /* Copy back any options */
+ if (buff)
+ {
+- if (p + rdlen > limit)
+- {
+- free(buff);
+- return plen; /* Too big */
+- }
++ if (p + rdlen > limit)
++ {
++ free(buff);
++ return plen; /* Too big */
++ }
+ 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
+--- 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,
+ size_t len;
+ int rd_bit = (header->hb3 & HB3_RD);
+
++ // Make sure we do not underflow here too.
++ if (qlen > (limit - ((char *)header))) return 0;
++
+ /* never answer queries with RD unset, to avoid cache snooping. */
+ if (ntohs(header->ancount) != 0 ||
+ ntohs(header->nscount) != 0 ||
+--
+2.31.1
+
diff --git a/repo/dnsmasq/0001-Retry-on-interrupted-error-in-tftp.patch b/repo/dnsmasq/0001-Retry-on-interrupted-error-in-tftp.patch
new file mode 100644
index 0000000..6fa3ac3
--- /dev/null
+++ b/repo/dnsmasq/0001-Retry-on-interrupted-error-in-tftp.patch
@@ -0,0 +1,27 @@
+Patch-Source: https://src.fedoraproject.org/rpms/dnsmasq/blob/f36/f/0001-Retry-on-interrupted-error-in-tftp.patch (backport from upstream)
+--
+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
+
+diff --git a/src/tftp.c b/src/tftp.c
+index 37bdff2..3d87523 100644
+--- a/src/tftp.c
++++ b/src/tftp.c
+@@ -600,7 +600,7 @@ void check_tftp_listeners(time_t now)
+ /* Wrong source address. See rfc1350 para 4. */
+ prettyprint_addr(&peer, daemon->addrbuff);
+ len = tftp_err(ERR_TID, daemon->packet, _("ignoring packet from %s (TID mismatch)"), daemon->addrbuff);
+- sendto(transfer->sockfd, daemon->packet, len, 0, &peer.sa, sa_len(&peer));
++ while(retry_send(sendto(transfer->sockfd, daemon->packet, len, 0, &peer.sa, sa_len(&peer))));
+ }
+ }
+ }
+--
+2.31.1
+
diff --git a/repo/dnsmasq/0002-Add-safety-checks-to-places-pointed-by-Coverity.patch b/repo/dnsmasq/0002-Add-safety-checks-to-places-pointed-by-Coverity.patch
new file mode 100644
index 0000000..1c84ecd
--- /dev/null
+++ b/repo/dnsmasq/0002-Add-safety-checks-to-places-pointed-by-Coverity.patch
@@ -0,0 +1,45 @@
+Patch-Source: https://src.fedoraproject.org/rpms/dnsmasq/blob/f36/f/0002-Add-safety-checks-to-places-pointed-by-Coverity.patch (backport from upstream)
+--
+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
+
+diff --git a/src/cache.c b/src/cache.c
+index 8add610..97c51a7 100644
+--- a/src/cache.c
++++ b/src/cache.c
+@@ -433,7 +433,7 @@ static struct crec *cache_scan_free(char *name, union all_addr *addr, unsigned s
+ else if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) &&
+ (flags & crecp->flags & F_REVERSE) &&
+ (flags & crecp->flags & (F_IPV4 | F_IPV6)) &&
+- memcmp(&crecp->addr, addr, addrlen) == 0)
++ addr && memcmp(&crecp->addr, addr, addrlen) == 0)
+ {
+ *up = crecp->hash_next;
+ cache_unlink(crecp);
+@@ -2013,7 +2013,7 @@ void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg)
+ else
+ source = "cached";
+
+- if (strlen(name) == 0)
++ if (name && !name[0])
+ name = ".";
+
+ if (option_bool(OPT_EXTRALOG))
+diff --git a/src/forward.c b/src/forward.c
+index 3d638e4..f07c908 100644
+--- a/src/forward.c
++++ b/src/forward.c
+@@ -2276,7 +2276,7 @@ int allocate_rfd(struct randfd_list **fdlp, struct server *serv)
+ }
+ }
+
+- if (j == daemon->numrrand)
++ if (!rfd) /* should be when j == daemon->numrrand */
+ {
+ struct randfd_list *rfl_poll;
+
+--
+2.31.1
+
diff --git a/repo/dnsmasq/0003-Small-safeguard-to-unexpected-data.patch b/repo/dnsmasq/0003-Small-safeguard-to-unexpected-data.patch
new file mode 100644
index 0000000..8d90e96
--- /dev/null
+++ b/repo/dnsmasq/0003-Small-safeguard-to-unexpected-data.patch
@@ -0,0 +1,30 @@
+Patch-Source: https://src.fedoraproject.org/rpms/dnsmasq/blob/f36/f/0003-Small-safeguard-to-unexpected-data.patch
+--
+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
+
diff --git a/repo/dnsmasq/0004-Fix-bunch-of-warnings-in-auth.c.patch b/repo/dnsmasq/0004-Fix-bunch-of-warnings-in-auth.c.patch
new file mode 100644
index 0000000..f3b7caa
--- /dev/null
+++ b/repo/dnsmasq/0004-Fix-bunch-of-warnings-in-auth.c.patch
@@ -0,0 +1,80 @@
+Patch-Source: https://src.fedoraproject.org/rpms/dnsmasq/blob/f36/f/0004-Fix-bunch-of-warnings-in-auth.c.patch (backport from upstream)
+--
+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
+
+diff --git a/src/auth.c b/src/auth.c
+index 172a4b2..4f03c39 100644
+--- a/src/auth.c
++++ b/src/auth.c
+@@ -417,7 +417,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+
+ if (!found && is_name_synthetic(flag, name, &addr) )
+ {
+- found = 1;
+ nxdomain = 0;
+
+ log_query(F_FORWARD | F_CONFIG | flag, name, &addr, NULL);
+@@ -433,7 +432,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ if (qtype == T_SOA)
+ {
+ auth = soa = 1; /* inhibits auth section */
+- found = 1;
+ log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<SOA>");
+ }
+ else if (qtype == T_AXFR)
+@@ -469,7 +467,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ soa = 1; /* inhibits auth section */
+ ns = 1; /* ensure we include NS records! */
+ axfr = 1;
+- found = 1;
+ axfroffset = nameoffset;
+ log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<AXFR>");
+ }
+@@ -477,7 +474,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ {
+ auth = 1;
+ ns = 1; /* inhibits auth section */
+- found = 1;
+ log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<NS>");
+ }
+ }
+@@ -498,7 +494,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ *cut = '.'; /* restore domain part */
+ log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid));
+ *cut = 0; /* remove domain part */
+- found = 1;
+ if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+ daemon->auth_ttl, NULL, qtype, C_IN,
+ qtype == T_A ? "4" : "6", &crecp->addr))
+@@ -519,7 +514,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ if ((crecp->flags & flag) && (local_query || filter_zone(zone, flag, &(crecp->addr))))
+ {
+ log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid));
+- found = 1;
+ if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+ daemon->auth_ttl, NULL, qtype, C_IN,
+ qtype == T_A ? "4" : "6", &crecp->addr))
+@@ -614,7 +608,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ if (subnet->prefixlen >= 16 )
+ p += sprintf(p, "%u.", a & 0xff);
+ a = a >> 8;
+- p += sprintf(p, "%u.in-addr.arpa", a & 0xff);
++ sprintf(p, "%u.in-addr.arpa", a & 0xff);
+
+ }
+ else
+@@ -627,7 +621,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ int dig = ((unsigned char *)&subnet->addr.addr6)[i>>3];
+ p += sprintf(p, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
+ }
+- p += sprintf(p, "ip6.arpa");
++ sprintf(p, "ip6.arpa");
+
+ }
+ }
+--
+2.31.1
+
diff --git a/repo/dnsmasq/0005-Fix-few-coverity-warnings-in-lease-tools.patch b/repo/dnsmasq/0005-Fix-few-coverity-warnings-in-lease-tools.patch
new file mode 100644
index 0000000..dafed7d
--- /dev/null
+++ b/repo/dnsmasq/0005-Fix-few-coverity-warnings-in-lease-tools.patch
@@ -0,0 +1,92 @@
+Patch-Source: https://src.fedoraproject.org/rpms/dnsmasq/blob/f36/f/0005-Fix-few-coverity-warnings-in-lease-tools.patch (backport from upstream)
+--
+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
+
+diff --git a/contrib/lease-tools/dhcp_release.c b/contrib/lease-tools/dhcp_release.c
+index c1c835b..84f5610 100644
+--- a/contrib/lease-tools/dhcp_release.c
++++ b/contrib/lease-tools/dhcp_release.c
+@@ -280,6 +280,7 @@ int main(int argc, char **argv)
+
+ /* This voodoo fakes up a packet coming from the correct interface, which really matters for
+ a DHCP server */
++ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, argv[1], sizeof(ifr.ifr_name)-1);
+ ifr.ifr_name[sizeof(ifr.ifr_name)-1] = '\0';
+ if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) == -1)
+diff --git a/contrib/lease-tools/dhcp_release6.c b/contrib/lease-tools/dhcp_release6.c
+index d680222..9b3438f 100644
+--- a/contrib/lease-tools/dhcp_release6.c
++++ b/contrib/lease-tools/dhcp_release6.c
+@@ -318,6 +318,12 @@ void usage(const char* arg, FILE* stream)
+ fprintf (stream, "Usage: %s %s\n", arg, usage_string);
+ }
+
++static void fail_fatal(const char *errstr, int exitcode)
++{
++ perror(errstr);
++ exit(exitcode);
++}
++
+ int send_release_packet(const char* iface, struct dhcp6_packet* packet)
+ {
+ struct sockaddr_in6 server_addr, client_addr;
+@@ -343,18 +349,19 @@ int send_release_packet(const char* iface, struct dhcp6_packet* packet)
+ client_addr.sin6_port = htons(DHCP6_CLIENT_PORT);
+ client_addr.sin6_flowinfo = 0;
+ client_addr.sin6_scope_id =0;
+- inet_pton(AF_INET6, "::", &client_addr.sin6_addr);
+- bind(sock, (struct sockaddr*)&client_addr, sizeof(struct sockaddr_in6));
+- inet_pton(AF_INET6, DHCP6_MULTICAST_ADDRESS, &server_addr.sin6_addr);
++ if (inet_pton(AF_INET6, "::", &client_addr.sin6_addr) <= 0)
++ fail_fatal("inet_pton", 5);
++ if (bind(sock, (struct sockaddr*)&client_addr, sizeof(struct sockaddr_in6)) != 0)
++ perror("bind"); /* continue on bind error */
++ if (inet_pton(AF_INET6, DHCP6_MULTICAST_ADDRESS, &server_addr.sin6_addr) <= 0)
++ fail_fatal("inet_pton", 5);
+ server_addr.sin6_port = htons(DHCP6_SERVER_PORT);
+- int16_t recv_size = 0;
++ ssize_t recv_size = 0;
++ int result;
+ for (i = 0; i < 5; i++)
+ {
+ if (sendto(sock, packet->buf, packet->len, 0, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
+- {
+- perror("sendto failed");
+- exit(4);
+- }
++ fail_fatal("sendto failed", 4);
+
+ recv_size = recvfrom(sock, response, sizeof(response), MSG_DONTWAIT, NULL, 0);
+ if (recv_size == -1)
+@@ -367,16 +374,18 @@ int send_release_packet(const char* iface, struct dhcp6_packet* packet)
+ else
+ {
+ perror("recvfrom");
++ result = UNSPEC_FAIL;
+ }
+ }
+-
+- int16_t result = parse_packet(response, recv_size);
+- if (result == NOT_REPLY_CODE)
++ else
+ {
+- sleep(1);
+- continue;
++ result = parse_packet(response, recv_size);
++ if (result == NOT_REPLY_CODE)
++ {
++ sleep(1);
++ continue;
++ }
+ }
+-
+ close(sock);
+ return result;
+ }
+--
+2.31.1
+
diff --git a/repo/dnsmasq/0006-Fix-coverity-formats-issues-in-blockdata.patch b/repo/dnsmasq/0006-Fix-coverity-formats-issues-in-blockdata.patch
new file mode 100644
index 0000000..441fbef
--- /dev/null
+++ b/repo/dnsmasq/0006-Fix-coverity-formats-issues-in-blockdata.patch
@@ -0,0 +1,23 @@
+Patch-Source: https://src.fedoraproject.org/rpms/dnsmasq/blob/f36/f/0006-Fix-coverity-formats-issues-in-blockdata.patch (backport from upstream)
+--
+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
+
+diff --git a/src/blockdata.c b/src/blockdata.c
+index f7740b5..0986285 100644
+--- a/src/blockdata.c
++++ b/src/blockdata.c
+@@ -52,7 +52,7 @@ void blockdata_init(void)
+
+ void blockdata_report(void)
+ {
+- my_syslog(LOG_INFO, _("pool memory in use %u, max %u, allocated %u"),
++ my_syslog(LOG_INFO, _("pool memory in use %zu, max %zu, allocated %zu"),
+ blockdata_count * sizeof(struct blockdata),
+ blockdata_hwm * sizeof(struct blockdata),
+ blockdata_alloced * sizeof(struct blockdata));
+--
+2.31.1
+
diff --git a/repo/dnsmasq/0007-Retry-dhcp6-ping-on-interrupts.patch b/repo/dnsmasq/0007-Retry-dhcp6-ping-on-interrupts.patch
new file mode 100644
index 0000000..7fea553
--- /dev/null
+++ b/repo/dnsmasq/0007-Retry-dhcp6-ping-on-interrupts.patch
@@ -0,0 +1,23 @@
+Patch-Source: https://src.fedoraproject.org/rpms/dnsmasq/blob/f36/f/0007-Retry-dhcp6-ping-on-interrupts.patch (backport from upstream)
+--
+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
+
+diff --git a/src/dhcp6.c b/src/dhcp6.c
+index 2be877f..ae1f5c1 100644
+--- a/src/dhcp6.c
++++ b/src/dhcp6.c
+@@ -292,7 +292,7 @@ void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac, unsi
+ if ((maclen = find_mac(&addr, mac, 0, now)) != 0)
+ break;
+
+- sendto(daemon->icmp6fd, &neigh, sizeof(neigh), 0, &addr.sa, sizeof(addr));
++ while(retry_send(sendto(daemon->icmp6fd, &neigh, sizeof(neigh), 0, &addr.sa, sizeof(addr))));
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = 100000000; /* 100ms */
+--
+2.31.1
+
diff --git a/repo/dnsmasq/0008-Fix-coverity-warnings-on-dbus.patch b/repo/dnsmasq/0008-Fix-coverity-warnings-on-dbus.patch
new file mode 100644
index 0000000..160d4d0
--- /dev/null
+++ b/repo/dnsmasq/0008-Fix-coverity-warnings-on-dbus.patch
@@ -0,0 +1,84 @@
+Patch-Source: https://src.fedoraproject.org/rpms/dnsmasq/blob/f36/f/0008-Fix-coverity-warnings-on-dbus.patch (backport from upstream)
+--
+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
+
+diff --git a/src/dbus.c b/src/dbus.c
+index cbdce9c..d746b9a 100644
+--- a/src/dbus.c
++++ b/src/dbus.c
+@@ -114,7 +114,7 @@ static dbus_bool_t add_watch(DBusWatch *watch, void *data)
+ w->next = daemon->watches;
+ daemon->watches = w;
+
+- w = data; /* no warning */
++ (void)data; /* no warning */
+ return TRUE;
+ }
+
+@@ -134,16 +134,20 @@ static void remove_watch(DBusWatch *watch, void *data)
+ up = &(w->next);
+ }
+
+- w = data; /* no warning */
++ (void)data; /* no warning */
+ }
+
+-static void dbus_read_servers(DBusMessage *message)
++static DBusMessage* dbus_read_servers(DBusMessage *message)
+ {
+ DBusMessageIter iter;
+ union mysockaddr addr, source_addr;
+ char *domain;
+
+- dbus_message_iter_init(message, &iter);
++ if (!dbus_message_iter_init(message, &iter))
++ {
++ return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
++ "Failed to initialize dbus message iter");
++ }
+
+ mark_servers(SERV_FROM_DBUS);
+
+@@ -222,6 +226,7 @@ static void dbus_read_servers(DBusMessage *message)
+
+ /* unlink and free anything still marked. */
+ cleanup_servers();
++ return NULL;
+ }
+
+ #ifdef HAVE_LOOP
+@@ -545,6 +550,10 @@ static DBusMessage *dbus_add_lease(DBusMessage* message)
+ "Invalid IP address '%s'", ipaddr);
+
+ hw_len = parse_hex((char*)hwaddr, dhcp_chaddr, DHCP_CHADDR_MAX, NULL, &hw_type);
++ if (hw_len < 0)
++ return dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
++ "Invalid HW address '%s'", hwaddr);
++
+ if (hw_type == 0 && hw_len != 0)
+ hw_type = ARPHRD_ETHER;
+
+@@ -668,7 +677,7 @@ DBusHandlerResult message_handler(DBusConnection *connection,
+ #endif
+ else if (strcmp(method, "SetServers") == 0)
+ {
+- dbus_read_servers(message);
++ reply = dbus_read_servers(message);
+ new_servers = 1;
+ }
+ else if (strcmp(method, "SetServersEx") == 0)
+@@ -719,7 +728,7 @@ DBusHandlerResult message_handler(DBusConnection *connection,
+ if (clear_cache)
+ clear_cache_and_reload(dnsmasq_time());
+
+- method = user_data; /* no warning */
++ (void)user_data; /* no warning */
+
+ /* If no reply or no error, return nothing */
+ if (!reply)
+--
+2.31.1
+
diff --git a/repo/dnsmasq/0009-Address-coverity-issues-detected-in-util.c.patch b/repo/dnsmasq/0009-Address-coverity-issues-detected-in-util.c.patch
new file mode 100644
index 0000000..4dbf56d
--- /dev/null
+++ b/repo/dnsmasq/0009-Address-coverity-issues-detected-in-util.c.patch
@@ -0,0 +1,58 @@
+Patch-Source: https://src.fedoraproject.org/rpms/dnsmasq/blob/f36/f/0009-Address-coverity-issues-detected-in-util.c.patch (backport from upstream)
+--
+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
+
+diff --git a/src/util.c b/src/util.c
+index 1425764..8e69d55 100644
+--- a/src/util.c
++++ b/src/util.c
+@@ -208,6 +208,8 @@ char *canonicalise(char *in, int *nomem)
+ /* older libidn2 strips underscores, so don't do IDN processing
+ if the name has an underscore (check_name() returned 2) */
+ if (rc != 2)
++#else
++ (void)rc;
+ #endif
+ #if defined(HAVE_IDN) || defined(HAVE_LIBIDN2)
+ {
+@@ -235,11 +237,14 @@ char *canonicalise(char *in, int *nomem)
+ return ret;
+ }
+ #endif
+-
++
++#if !defined(HAVE_LIBIDN2) || (defined(HAVE_LIBIDN2) && (!defined(IDN2_VERSION_NUMBER) || IDN2_VERSION_NUMBER < 0x02000003))
++ /* If recent libidn2 is used, it cannot reach this code. */
+ if ((ret = whine_malloc(strlen(in)+1)))
+ strcpy(ret, in);
+ else if (nomem)
+- *nomem = 1;
++ *nomem = 1;
++#endif
+
+ return ret;
+ }
+@@ -528,7 +533,7 @@ void prettyprint_time(char *buf, unsigned int t)
+ if ((x = (t/60)%60))
+ p += sprintf(&buf[p], "%um", x);
+ if ((x = t%60))
+- p += sprintf(&buf[p], "%us", x);
++ sprintf(&buf[p], "%us", x);
+ }
+ }
+
+@@ -574,7 +579,7 @@ int parse_hex(char *in, unsigned char *out, int maxlen,
+ int j, bytes = (1 + (r - in))/2;
+ for (j = 0; j < bytes; j++)
+ {
+- char sav = sav;
++ char sav;
+ if (j < bytes - 1)
+ {
+ sav = in[(j+1)*2];
+--
+2.31.1
+
diff --git a/repo/dnsmasq/0010-Fix-coverity-detected-issues-in-option.c.patch b/repo/dnsmasq/0010-Fix-coverity-detected-issues-in-option.c.patch
new file mode 100644
index 0000000..25b271f
--- /dev/null
+++ b/repo/dnsmasq/0010-Fix-coverity-detected-issues-in-option.c.patch
@@ -0,0 +1,135 @@
+Patch-Source: https://src.fedoraproject.org/rpms/dnsmasq/blob/f36/f/0010-Fix-coverity-detected-issues-in-option.c.patch (backport from upstream)
+--
+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
+
+diff --git a/src/option.c b/src/option.c
+index ffce9fc..11655fd 100644
+--- a/src/option.c
++++ b/src/option.c
+@@ -798,7 +798,7 @@ static void do_usage(void)
+
+ if (usage[i].arg)
+ {
+- strcpy(buff, usage[i].arg);
++ safe_strncpy(buff, usage[i].arg, sizeof(buff));
+ for (j = 0; tab[j].handle; j++)
+ if (tab[j].handle == *(usage[i].arg))
+ sprintf(buff, "%d", tab[j].val);
+@@ -959,7 +959,7 @@ static int domain_rev4(char *domain, struct in_addr addr, int msize)
+ return 0;
+ }
+
+- domain += sprintf(domain, "in-addr.arpa");
++ sprintf(domain, "in-addr.arpa");
+
+ return 1;
+ }
+@@ -978,7 +978,7 @@ static int domain_rev6(char *domain, struct in6_addr *addr, int msize)
+ int dig = ((unsigned char *)addr)[i>>3];
+ domain += sprintf(domain, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
+ }
+- domain += sprintf(domain, "ip6.arpa");
++ sprintf(domain, "ip6.arpa");
+
+ return 1;
+ }
+@@ -1829,6 +1829,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
+ new->next = li;
+ *up = new;
+ }
++ else
++ free(path);
+
+ }
+
+@@ -1995,7 +1997,11 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
+
+ if (!(name = canonicalise_opt(arg)) ||
+ (comma && !(target = canonicalise_opt(comma))))
+- ret_err(_("bad MX name"));
++ {
++ free(name);
++ free(target);
++ ret_err(_("bad MX name"));
++ }
+
+ new = opt_malloc(sizeof(struct mx_srv_record));
+ new->next = daemon->mxnames;
+@@ -3616,6 +3622,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
+ inet_ntop(AF_INET, &in, daemon->addrbuff, ADDRSTRLEN);
+ sprintf(errstr, _("duplicate dhcp-host IP address %s"),
+ daemon->addrbuff);
++ dhcp_config_free(new);
+ return 0;
+ }
+ }
+@@ -3779,16 +3786,16 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
+
+ case LOPT_NAME_MATCH: /* --dhcp-name-match */
+ {
+- struct dhcp_match_name *new = opt_malloc(sizeof(struct dhcp_match_name));
+- struct dhcp_netid *id = opt_malloc(sizeof(struct dhcp_netid));
++ struct dhcp_match_name *new;
+ ssize_t len;
+
+ if (!(comma = split(arg)) || (len = strlen(comma)) == 0)
+ ret_err(gen_err);
+
++ new = opt_malloc(sizeof(struct dhcp_match_name));
+ new->wildcard = 0;
+- new->netid = id;
+- id->net = opt_string_alloc(set_prefix(arg));
++ new->netid = opt_malloc(sizeof(struct dhcp_netid));
++ new->netid->net = opt_string_alloc(set_prefix(arg));
+
+ if (comma[len-1] == '*')
+ {
+@@ -3992,6 +3999,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
+ }
+ }
+
++ dhcp_netid_free(new->netid);
++ free(new);
+ ret_err(gen_err);
+ }
+
+@@ -4367,7 +4376,7 @@ err:
+ case LOPT_CNAME: /* --cname */
+ {
+ struct cname *new;
+- char *alias, *target, *last, *pen;
++ char *alias, *target=NULL, *last, *pen;
+ int ttl = -1;
+
+ for (last = pen = NULL, comma = arg; comma; comma = split(comma))
+@@ -4382,13 +4391,13 @@ err:
+ if (pen != arg && atoi_check(last, &ttl))
+ last = pen;
+
+- target = canonicalise_opt(last);
+-
+ while (arg != last)
+ {
+ int arglen = strlen(arg);
+ alias = canonicalise_opt(arg);
+
++ if (!target)
++ target = canonicalise_opt(last);
+ if (!alias || !target)
+ {
+ free(target);
+@@ -4691,7 +4700,7 @@ err:
+ struct name_list *nl;
+ if (!canon)
+ {
+- struct name_list *tmp = new->names, *next;
++ struct name_list *tmp, *next;
+ for (tmp = new->names; tmp; tmp = next)
+ {
+ next = tmp->next;
+--
+2.31.1
+
diff --git a/repo/dnsmasq/0011-Fix-coverity-detected-issue-in-radv.c.patch b/repo/dnsmasq/0011-Fix-coverity-detected-issue-in-radv.c.patch
new file mode 100644
index 0000000..d3a9819
--- /dev/null
+++ b/repo/dnsmasq/0011-Fix-coverity-detected-issue-in-radv.c.patch
@@ -0,0 +1,23 @@
+Patch-Source: https://src.fedoraproject.org/rpms/dnsmasq/blob/f36/f/0011-Fix-coverity-detected-issue-in-radv.c.patch (backport from upstream)
+--
+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
+
+diff --git a/src/radv.c b/src/radv.c
+index 3255904..6d6fa32 100644
+--- a/src/radv.c
++++ b/src/radv.c
+@@ -746,6 +746,8 @@ static int add_lla(int index, unsigned int type, char *mac, size_t maclen, void
+ add 7 to round up */
+ int len = (maclen + 9) >> 3;
+ unsigned char *p = expand(len << 3);
++ if (!p)
++ return 1;
+ memset(p, 0, len << 3);
+ *p++ = ICMP6_OPT_SOURCE_MAC;
+ *p++ = len;
+--
+2.31.1
+
diff --git a/repo/dnsmasq/0012-Fix-coverity-detected-issues-in-cache.c.patch b/repo/dnsmasq/0012-Fix-coverity-detected-issues-in-cache.c.patch
new file mode 100644
index 0000000..b98f71f
--- /dev/null
+++ b/repo/dnsmasq/0012-Fix-coverity-detected-issues-in-cache.c.patch
@@ -0,0 +1,23 @@
+Patch-Source: https://src.fedoraproject.org/rpms/dnsmasq/blob/f36/f/0012-Fix-coverity-detected-issues-in-cache.c.patch (backport from upstream)
+--
+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
+
+diff --git a/src/cache.c b/src/cache.c
+index 97c51a7..6722fa6 100644
+--- a/src/cache.c
++++ b/src/cache.c
+@@ -1188,7 +1188,7 @@ void cache_reload(void)
+ struct host_record *hr;
+ struct name_list *nl;
+ struct cname *a;
+- struct crec lrec;
++ struct crec lrec = { 0, };
+ struct mx_srv_record *mx;
+ struct txt_record *txt;
+ struct interface_name *intr;
+--
+2.31.1
+
diff --git a/repo/dnsmasq/0013-Fix-coverity-issues-detected-in-domain-match.c.patch b/repo/dnsmasq/0013-Fix-coverity-issues-detected-in-domain-match.c.patch
new file mode 100644
index 0000000..7b8db66
--- /dev/null
+++ b/repo/dnsmasq/0013-Fix-coverity-issues-detected-in-domain-match.c.patch
@@ -0,0 +1,60 @@
+Patch-Source: https://src.fedoraproject.org/rpms/dnsmasq/blob/f36/f/0013-Fix-coverity-issues-detected-in-domain-match.c.patch (backport from upstream)
+--
+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
+
+diff --git a/src/domain-match.c b/src/domain-match.c
+index f8e4796..7124c18 100644
+--- a/src/domain-match.c
++++ b/src/domain-match.c
+@@ -411,7 +411,8 @@ size_t make_local_answer(int flags, int gotname, size_t size, struct dns_header
+ addr.addr4 = srv->addr;
+
+ header->ancount = htons(ntohs(header->ancount) + 1);
+- add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_A, C_IN, "4", &addr);
++ if (!add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_A, C_IN, "4", &addr))
++ return 0;
+ log_query((flags | F_CONFIG | F_FORWARD) & ~F_IPV6, name, (union all_addr *)&addr, NULL);
+ }
+
+@@ -426,7 +427,8 @@ size_t make_local_answer(int flags, int gotname, size_t size, struct dns_header
+ addr.addr6 = srv->addr;
+
+ header->ancount = htons(ntohs(header->ancount) + 1);
+- add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_AAAA, C_IN, "6", &addr);
++ if (!add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_AAAA, C_IN, "6", &addr))
++ return 0;
+ log_query((flags | F_CONFIG | F_FORWARD) & ~F_IPV4, name, (union all_addr *)&addr, NULL);
+ }
+
+@@ -609,9 +611,11 @@ int add_update_server(int flags,
+
+ if (*domain == 0)
+ alloc_domain = whine_malloc(1);
+- else if (!(alloc_domain = canonicalise((char *)domain, NULL)))
++ else
++ alloc_domain = canonicalise((char *)domain, NULL);
++ if (!alloc_domain)
+ return 0;
+-
++
+ /* See if there is a suitable candidate, and unmark
+ only do this for forwarding servers, not
+ address or local, to avoid delays on large numbers. */
+@@ -643,7 +647,10 @@ int add_update_server(int flags,
+ size = sizeof(struct server);
+
+ if (!(serv = whine_malloc(size)))
+- return 0;
++ {
++ free(alloc_domain);
++ return 0;
++ }
+
+ if (flags & SERV_IS_LOCAL)
+ {
+--
+2.31.1
+
diff --git a/repo/dnsmasq/0014-Fix-coverity-detected-issues-in-dnsmasq.c.patch b/repo/dnsmasq/0014-Fix-coverity-detected-issues-in-dnsmasq.c.patch
new file mode 100644
index 0000000..148a4b3
--- /dev/null
+++ b/repo/dnsmasq/0014-Fix-coverity-detected-issues-in-dnsmasq.c.patch
@@ -0,0 +1,69 @@
+Patch-Source: https://src.fedoraproject.org/rpms/dnsmasq/blob/f36/f/0014-Fix-coverity-detected-issues-in-dnsmasq.c.patch (backport from upstream)
+--
+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
+
+diff --git a/src/dnsmasq.c b/src/dnsmasq.c
+index 602daed..3e1bfe8 100644
+--- a/src/dnsmasq.c
++++ b/src/dnsmasq.c
+@@ -34,7 +34,6 @@ static void poll_resolv(int force, int do_reload, time_t now);
+
+ int main (int argc, char **argv)
+ {
+- int bind_fallback = 0;
+ time_t now;
+ struct sigaction sigact;
+ struct iname *if_tmp;
+@@ -59,6 +58,8 @@ int main (int argc, char **argv)
+ int did_bind = 0;
+ struct server *serv;
+ char *netlink_warn;
++#else
++ int bind_fallback = 0;
+ #endif
+ #if defined(HAVE_DHCP) || defined(HAVE_DHCP6)
+ struct dhcp_context *context;
+@@ -377,7 +378,7 @@ int main (int argc, char **argv)
+ bindtodevice(bound_device, daemon->dhcpfd);
+ did_bind = 1;
+ }
+- if (daemon->enable_pxe && bound_device)
++ if (daemon->enable_pxe && bound_device && daemon->pxefd != -1)
+ {
+ bindtodevice(bound_device, daemon->pxefd);
+ did_bind = 1;
+@@ -920,8 +921,10 @@ int main (int argc, char **argv)
+ my_syslog(LOG_WARNING, _("warning: failed to change owner of %s: %s"),
+ daemon->log_file, strerror(log_err));
+
++#ifndef HAVE_LINUX_NETWORK
+ if (bind_fallback)
+ my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
++#endif
+
+ if (option_bool(OPT_NOWILD))
+ warn_bound_listeners();
+@@ -1575,7 +1578,7 @@ static void async_event(int pipe, time_t now)
+ {
+ /* block in writes until all done */
+ if ((i = fcntl(daemon->helperfd, F_GETFL)) != -1)
+- fcntl(daemon->helperfd, F_SETFL, i & ~O_NONBLOCK);
++ while(retry_send(fcntl(daemon->helperfd, F_SETFL, i & ~O_NONBLOCK)));
+ do {
+ helper_write();
+ } while (!helper_buf_empty() || do_script_run(now));
+@@ -1984,7 +1987,7 @@ static void check_dns_listeners(time_t now)
+ attribute from the listening socket.
+ Reset that here. */
+ if ((flags = fcntl(confd, F_GETFL, 0)) != -1)
+- fcntl(confd, F_SETFL, flags & ~O_NONBLOCK);
++ while(retry_send(fcntl(confd, F_SETFL, flags & ~O_NONBLOCK)));
+
+ buff = tcp_request(confd, now, &tcp_addr, netmask, auth_dns);
+
+--
+2.31.1
+
diff --git a/repo/dnsmasq/0015-Fix-coverity-issues-in-dnssec.c.patch b/repo/dnsmasq/0015-Fix-coverity-issues-in-dnssec.c.patch
new file mode 100644
index 0000000..7f9d5d3
--- /dev/null
+++ b/repo/dnsmasq/0015-Fix-coverity-issues-in-dnssec.c.patch
@@ -0,0 +1,35 @@
+Patch-Source: https://src.fedoraproject.org/rpms/dnsmasq/blob/f36/f/0015-Fix-coverity-issues-in-dnssec.c.patch (backport from upstream)
+--
+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
+
+diff --git a/src/dnssec.c b/src/dnssec.c
+index 94ebb6f..8800a5b 100644
+--- a/src/dnssec.c
++++ b/src/dnssec.c
+@@ -724,7 +724,8 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
+
+ /* namebuff used for workspace above, restore to leave unchanged on exit */
+ p = (unsigned char*)(rrset[0]);
+- extract_name(header, plen, &p, name, 1, 0);
++ if (!extract_name(header, plen, &p, name, 1, 0))
++ return STAT_BOGUS;
+
+ if (key)
+ {
+@@ -1017,7 +1018,9 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
+ }
+
+ p = (unsigned char *)(header+1);
+- extract_name(header, plen, &p, name, 1, 4);
++ if (!extract_name(header, plen, &p, name, 1, 4))
++ return STAT_BOGUS;
++
+ p += 4; /* qtype, qclass */
+
+ /* If the key needed to validate the DS is on the same domain as the DS, we'll
+--
+2.31.1
+
diff --git a/repo/dnsmasq/0020-Fix-crash-after-re-reading-empty-resolv.conf.patch b/repo/dnsmasq/0020-Fix-crash-after-re-reading-empty-resolv.conf.patch
new file mode 100644
index 0000000..169897e
--- /dev/null
+++ b/repo/dnsmasq/0020-Fix-crash-after-re-reading-empty-resolv.conf.patch
@@ -0,0 +1,38 @@
+Patch-Source: https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=d290630d31f4517ab26392d00753d1397f9a4114 (upstream)
+--
+From d290630d31f4517ab26392d00753d1397f9a4114 Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Wed, 6 Oct 2021 22:31:06 +0100
+Subject: [PATCH] Fix crash after re-reading an empty resolv.conf file.
+
+If dnsmasq re-reads a resolv file, and it's empty, it will
+retry after a delay. In the meantime, the old servers from the
+resolv file have been deleted, but the servers_array doesn't
+get updated, leading to dangling pointers and crashes.
+
+Thanks to Brad Jorsch for finding and analysing this bug.
+
+This problem was introduced in 2.86.
+---
+ src/dnsmasq.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/src/dnsmasq.c b/src/dnsmasq.c
+index c7fa024..9516680 100644
+--- a/src/dnsmasq.c
++++ b/src/dnsmasq.c
+@@ -1682,6 +1682,11 @@ static void poll_resolv(int force, int do_reload, time_t now)
+ }
+ else
+ {
++ /* If we're delaying things, we don't call check_servers(), but
++ reload_servers() may have deleted some servers, rendering the server_array
++ invalid, so just rebuild that here. Once reload_servers() succeeds,
++ we call check_servers() above, which calls build_server_array itself. */
++ build_server_array();
+ latest->mtime = 0;
+ if (!warned)
+ {
+--
+2.20.1
+
diff --git a/repo/dnsmasq/CVE-2022-0934.patch b/repo/dnsmasq/CVE-2022-0934.patch
new file mode 100644
index 0000000..1381626
--- /dev/null
+++ b/repo/dnsmasq/CVE-2022-0934.patch
@@ -0,0 +1,189 @@
+Patch-Source: https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=03345ecefeb0d82e3c3a4c28f27c3554f0611b39 (upstream)
+--
+From 03345ecefeb0d82e3c3a4c28f27c3554f0611b39 Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Thu, 31 Mar 2022 21:35:20 +0100
+Subject: [PATCH] Fix write-after-free error in DHCPv6 code. CVE-2022-0934
+ refers.
+
+---
+ CHANGELOG | 3 +++
+ src/rfc3315.c | 48 +++++++++++++++++++++++++++---------------------
+ 2 files changed, 30 insertions(+), 21 deletions(-)
+
+diff --git a/CHANGELOG b/CHANGELOG
+index 87d6c2b..4bc7fb1 100644
+--- a/CHANGELOG
++++ b/CHANGELOG
+@@ -55,6 +55,9 @@ version 2.87
+ doesn't require hard-coding addresses. Thanks to Sten Spans for
+ the idea.
+
++ Fix write-after-free error in DHCPv6 server code.
++ CVE-2022-0934 refers.
++
+
+ version 2.86
+ Handle DHCPREBIND requests in the DHCPv6 server code.
+diff --git a/src/rfc3315.c b/src/rfc3315.c
+index cee8382..e218d26 100644
+--- a/src/rfc3315.c
++++ b/src/rfc3315.c
+@@ -33,9 +33,9 @@ struct state {
+ unsigned int mac_len, mac_type;
+ };
+
+-static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
++static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t sz,
+ struct in6_addr *client_addr, int is_unicast, time_t now);
+-static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_t sz, int is_unicast, time_t now);
++static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbuff, size_t sz, int is_unicast, time_t now);
+ static void log6_opts(int nest, unsigned int xid, void *start_opts, void *end_opts);
+ static void log6_packet(struct state *state, char *type, struct in6_addr *addr, char *string);
+ static void log6_quiet(struct state *state, char *type, struct in6_addr *addr, char *string);
+@@ -104,12 +104,12 @@ unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *if
+ }
+
+ /* This cost me blood to write, it will probably cost you blood to understand - srk. */
+-static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
++static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t sz,
+ struct in6_addr *client_addr, int is_unicast, time_t now)
+ {
+ void *end = inbuff + sz;
+ void *opts = inbuff + 34;
+- int msg_type = *((unsigned char *)inbuff);
++ int msg_type = *inbuff;
+ unsigned char *outmsgtypep;
+ void *opt;
+ struct dhcp_vendor *vendor;
+@@ -259,15 +259,15 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
+ return 1;
+ }
+
+-static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_t sz, int is_unicast, time_t now)
++static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbuff, size_t sz, int is_unicast, time_t now)
+ {
+ void *opt;
+- int i, o, o1, start_opts;
++ int i, o, o1, start_opts, start_msg;
+ struct dhcp_opt *opt_cfg;
+ struct dhcp_netid *tagif;
+ struct dhcp_config *config = NULL;
+ struct dhcp_netid known_id, iface_id, v6_id;
+- unsigned char *outmsgtypep;
++ unsigned char outmsgtype;
+ struct dhcp_vendor *vendor;
+ struct dhcp_context *context_tmp;
+ struct dhcp_mac *mac_opt;
+@@ -296,12 +296,13 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+ v6_id.next = state->tags;
+ state->tags = &v6_id;
+
+- /* copy over transaction-id, and save pointer to message type */
+- if (!(outmsgtypep = put_opt6(inbuff, 4)))
++ start_msg = save_counter(-1);
++ /* copy over transaction-id */
++ if (!put_opt6(inbuff, 4))
+ return 0;
+ start_opts = save_counter(-1);
+- state->xid = outmsgtypep[3] | outmsgtypep[2] << 8 | outmsgtypep[1] << 16;
+-
++ state->xid = inbuff[3] | inbuff[2] << 8 | inbuff[1] << 16;
++
+ /* We're going to be linking tags from all context we use.
+ mark them as unused so we don't link one twice and break the list */
+ for (context_tmp = state->context; context_tmp; context_tmp = context_tmp->current)
+@@ -347,7 +348,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+ (msg_type == DHCP6REQUEST || msg_type == DHCP6RENEW || msg_type == DHCP6RELEASE || msg_type == DHCP6DECLINE))
+
+ {
+- *outmsgtypep = DHCP6REPLY;
++ outmsgtype = DHCP6REPLY;
+ o1 = new_opt6(OPTION6_STATUS_CODE);
+ put_opt6_short(DHCP6USEMULTI);
+ put_opt6_string("Use multicast");
+@@ -619,11 +620,11 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+ struct dhcp_netid *solicit_tags;
+ struct dhcp_context *c;
+
+- *outmsgtypep = DHCP6ADVERTISE;
++ outmsgtype = DHCP6ADVERTISE;
+
+ if (opt6_find(state->packet_options, state->end, OPTION6_RAPID_COMMIT, 0))
+ {
+- *outmsgtypep = DHCP6REPLY;
++ outmsgtype = DHCP6REPLY;
+ state->lease_allocate = 1;
+ o = new_opt6(OPTION6_RAPID_COMMIT);
+ end_opt6(o);
+@@ -809,7 +810,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+ int start = save_counter(-1);
+
+ /* set reply message type */
+- *outmsgtypep = DHCP6REPLY;
++ outmsgtype = DHCP6REPLY;
+ state->lease_allocate = 1;
+
+ log6_quiet(state, "DHCPREQUEST", NULL, ignore ? _("ignored") : NULL);
+@@ -924,7 +925,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+ int address_assigned = 0;
+
+ /* set reply message type */
+- *outmsgtypep = DHCP6REPLY;
++ outmsgtype = DHCP6REPLY;
+
+ log6_quiet(state, msg_type == DHCP6RENEW ? "DHCPRENEW" : "DHCPREBIND", NULL, NULL);
+
+@@ -1057,7 +1058,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+ int good_addr = 0;
+
+ /* set reply message type */
+- *outmsgtypep = DHCP6REPLY;
++ outmsgtype = DHCP6REPLY;
+
+ log6_quiet(state, "DHCPCONFIRM", NULL, NULL);
+
+@@ -1121,7 +1122,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+ log6_quiet(state, "DHCPINFORMATION-REQUEST", NULL, ignore ? _("ignored") : state->hostname);
+ if (ignore)
+ return 0;
+- *outmsgtypep = DHCP6REPLY;
++ outmsgtype = DHCP6REPLY;
+ tagif = add_options(state, 1);
+ break;
+ }
+@@ -1130,7 +1131,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+ case DHCP6RELEASE:
+ {
+ /* set reply message type */
+- *outmsgtypep = DHCP6REPLY;
++ outmsgtype = DHCP6REPLY;
+
+ log6_quiet(state, "DHCPRELEASE", NULL, NULL);
+
+@@ -1195,7 +1196,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+ case DHCP6DECLINE:
+ {
+ /* set reply message type */
+- *outmsgtypep = DHCP6REPLY;
++ outmsgtype = DHCP6REPLY;
+
+ log6_quiet(state, "DHCPDECLINE", NULL, NULL);
+
+@@ -1275,7 +1276,12 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+ }
+
+ }
+-
++
++ /* Fill in the message type. Note that we store the offset,
++ not a direct pointer, since the packet memory may have been
++ reallocated. */
++ ((unsigned char *)(daemon->outpacket.iov_base))[start_msg] = outmsgtype;
++
+ log_tags(tagif, state->xid);
+ log6_opts(0, state->xid, daemon->outpacket.iov_base + start_opts, daemon->outpacket.iov_base + save_counter(-1));
+
+--
+2.20.1
+
diff --git a/repo/dnsmasq/config.h.patch b/repo/dnsmasq/config.h.patch
new file mode 100644
index 0000000..7847696
--- /dev/null
+++ b/repo/dnsmasq/config.h.patch
@@ -0,0 +1,12 @@
+Adjust defaults.
+
+--- a/src/config.h
++++ b/src/config.h
+@@ -47,2 +47,2 @@
+-#define CHUSER "nobody"
+-#define CHGRP "dip"
++#define CHUSER "dnsmasq"
++#define CHGRP "dnsmasq"
+@@ -231 +231 @@
+-# define RUNFILE "/var/run/dnsmasq.pid"
++# define RUNFILE "/run/dnsmasq.pid"
diff --git a/repo/dnsmasq/dnsmasq-dnssec.pre-install b/repo/dnsmasq/dnsmasq-dnssec.pre-install
new file mode 100644
index 0000000..708c15b
--- /dev/null
+++ b/repo/dnsmasq/dnsmasq-dnssec.pre-install
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+addgroup -S dnsmasq 2>/dev/null
+adduser -S -D -H -h /dev/null -s /sbin/nologin -G dnsmasq -g dnsmasq dnsmasq 2>/dev/null
+
+exit 0
diff --git a/repo/dnsmasq/dnsmasq-dnssec.pre-upgrade b/repo/dnsmasq/dnsmasq-dnssec.pre-upgrade
new file mode 100644
index 0000000..708c15b
--- /dev/null
+++ b/repo/dnsmasq/dnsmasq-dnssec.pre-upgrade
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+addgroup -S dnsmasq 2>/dev/null
+adduser -S -D -H -h /dev/null -s /sbin/nologin -G dnsmasq -g dnsmasq dnsmasq 2>/dev/null
+
+exit 0
diff --git a/repo/dnsmasq/dnsmasq.conf.patch b/repo/dnsmasq/dnsmasq.conf.patch
new file mode 100644
index 0000000..e3d7df4
--- /dev/null
+++ b/repo/dnsmasq/dnsmasq.conf.patch
@@ -0,0 +1,38 @@
+--- a/dnsmasq.conf.example
++++ b/dnsmasq.conf.example
+@@ -21,8 +21,8 @@
+ #bogus-priv
+
+ # Uncomment these to enable DNSSEC validation and caching:
+-# (Requires dnsmasq to be built with DNSSEC option.)
+-#conf-file=%%PREFIX%%/share/dnsmasq/trust-anchors.conf
++# (Requires dnsmasq-dnssec package to be installed)
++#conf-file=/usr/share/dnsmasq/trust-anchors.conf
+ #dnssec
+
+ # Replies which are not DNSSEC signed may be legitimate, because the domain
+@@ -96,9 +96,13 @@
+
+ # If you want dnsmasq to change uid and gid to something other
+ # than the default, edit the following lines.
+-#user=
+-#group=
++#user=dnsmasq
++#group=dnsmasq
+
++# Serve DNS and DHCP only to networks directly connected to this machine.
++# Any interface= line will override it.
++local-service
++
+ # If you want dnsmasq to listen for DHCP and DNS requests only on
+ # specified interfaces (and the loopback) give the name of the
+ # interface (eg eth0) here.
+@@ -671,7 +675,7 @@
+ #conf-dir=/etc/dnsmasq.d,.bak
+
+ # Include all files in a directory which end in .conf
+-#conf-dir=/etc/dnsmasq.d/,*.conf
++conf-dir=/etc/dnsmasq.d/,*.conf
+
+ # If a DHCP client claims that its name is "wpad", ignore that.
+ # This fixes a security hole. see CERT Vulnerability VU#598349
diff --git a/repo/dnsmasq/dnsmasq.confd b/repo/dnsmasq/dnsmasq.confd
new file mode 100644
index 0000000..564a25d
--- /dev/null
+++ b/repo/dnsmasq/dnsmasq.confd
@@ -0,0 +1,22 @@
+# Configuration for /etc/init.d/dnsmasq
+
+# Path to the dnsmasq configuration file.
+#cfgfile="/etc/dnsmasq.conf"
+
+# Location where to store DHCP leases (sets --dhcp-leasefile).
+#leasefile="/var/lib/misc/$RC_SVCNAME.leases"
+
+# Whether to automatically set up a network bridge when the init script is
+# a symlink with suffix (e.g. /etc/init.d/dnsmasq.br0).
+#setup_bridge=yes
+
+# User and group to change to after startup.
+#user="dnsmasq"
+#group="dnsmasq"
+
+# Additional options to pass to the dnsmasq.
+# See the dnsmasq(8) man page for more information.
+#command_args=
+
+# Uncomment to run with process supervisor.
+# supervisor=supervise-daemon
diff --git a/repo/dnsmasq/dnsmasq.initd b/repo/dnsmasq/dnsmasq.initd
new file mode 100644
index 0000000..be09548
--- /dev/null
+++ b/repo/dnsmasq/dnsmasq.initd
@@ -0,0 +1,151 @@
+#!/sbin/openrc-run
+
+description="A lightweight DNS, DHCP, RA, TFTP and PXE server"
+
+extra_commands="checkconfig"
+description_checkconfig="Check configuration syntax"
+
+extra_started_commands="reload"
+description_reload="Clear cache and reload hosts files"
+
+# DNSMASQ_CONFFILE is here for backward compatibility (Alpine <3.16).
+: ${cfgfile:=${DNSMASQ_CONFFILE:-"/etc/dnsmasq.conf"}}
+: ${leasefile:="/var/lib/misc/$RC_SVCNAME.leases"}
+: ${user:="dnsmasq"}
+: ${group:="dnsmasq"}
+: ${setup_bridge:="yes"}
+
+command="/usr/sbin/dnsmasq"
+# Tell dnsmasq to not create pidfile, that's responsibility of init system.
+# DNSMASQ_OPTS is here for backward compatibility (Alpine <3.16).
+command_args="--keep-in-foreground --pid-file= $DNSMASQ_OPTS $command_args --conf-file=$cfgfile"
+command_background="yes"
+pidfile="/run/$RC_SVCNAME.pid"
+
+if [ "${RC_SVCNAME#*.}" != "$RC_SVCNAME" ] && yesno "$setup_bridge"; then
+ BRIDGE="${RC_SVCNAME#*.}"
+ : ${BRIDGE_ADDR:="10.0.3.1"}
+ : ${BRIDGE_NETMASK:="255.255.255.0"}
+ : ${BRIDGE_NETWORK:="10.0.3.0/24"}
+ : ${BRIDGE_DHCP_RANGE:="10.0.3.2,10.0.3.254"}
+ : ${BRIDGE_DHCP_MAX:="253"}
+ : ${BRIDGE_MAC:="00:16:3e:00:00:00" }
+ : ${DNSMASQ_LISTEN_BRIDGE_ADDR:=yes}
+fi
+
+depend() {
+ provide dns
+ need localmount net
+ after bootmisc
+ use logger
+}
+
+setup_firewall() {
+ local ins=$1 add=$2
+
+ iptables -w $ins INPUT -i "$BRIDGE" -p udp --dport 67 -j ACCEPT
+ iptables -w $ins INPUT -i "$BRIDGE" -p tcp --dport 67 -j ACCEPT
+ iptables -w $ins INPUT -i "$BRIDGE" -p udp --dport 53 -j ACCEPT
+ iptables -w $ins INPUT -i "$BRIDGE" -p tcp --dport 53 -j ACCEPT
+ iptables -w $ins FORWARD -i "$BRIDGE" -j ACCEPT
+ iptables -w $ins FORWARD -o "$BRIDGE" -j ACCEPT
+ iptables -w -t nat $add POSTROUTING -s "$BRIDGE_NETWORK" ! -d "$BRIDGE_NETWORK" -j MASQUERADE
+ iptables -w -t mangle $add POSTROUTING -o "$BRIDGE" -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill
+
+ if yesno "$BRIDGE_IPV6_NAT" && [ -n "$BRIDGE_IPV6_NETWORK" ]; then
+ ip6tables -w -t nat $add POSTROUTING -s "$BRIDGE_IPV6_NETWORK" ! -d "$BRIDGE_IPV6_NETWORK" -j MASQUERADE
+ fi
+}
+
+setup_bridge() {
+ einfo "Creating bridge $BRIDGE"
+
+ if ! [ -d "/sys/class/net/$BRIDGE" ]; then
+ ip link add dev "$BRIDGE" type bridge
+ fi
+
+ local addr
+ ip link set dev "$BRIDGE" address "$BRIDGE_MAC" \
+ && for addr in $BRIDGE_ADDR $BRIDGE_ADDR_EXTRA; do
+ case "$addr" in
+ */*) ip addr add "$addr" dev "$BRIDGE";;
+ *) ip addr add "$addr/$BRIDGE_NETMASK" dev "$BRIDGE";;
+ esac
+ done \
+ && ip link set dev "$BRIDGE" up
+
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+ echo 0 > "/proc/sys/net/ipv6/conf/$BRIDGE/accept_dad" || true
+
+ if [ -n "$BRIDGE_IPV6_ADDR" ] && [ -n "$BRIDGE_IPV6_MASK" ] && [ "$BRIDGE_IPV6_NETWORK" ]; then
+ echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
+ echo 0 > "/proc/sys/net/ipv6/conf/$BRIDGE/autoconf"
+
+ ip -6 addr add dev "$BRIDGE" "$BRIDGE_IPV6_ADDR/$BRIDGE_IPV6_MASK"
+
+ command_args="$command_args --dhcp-range=$BRIDGE_IPV6_ADDR,ra-only --listen-address $BRIDGE_IPV6_ADDR"
+ fi
+
+}
+
+start_pre() {
+ $command --test --conf-file="$cfgfile" >/dev/null 2>&1 \
+ || $command --test \
+ || return 1
+
+ checkpath -m 0644 -o "$user:$group" -f "$leasefile" || return 1
+
+ if [ -n "$BRIDGE" ]; then
+ setup_bridge
+ if ! yesno "$DISABLE_IPTABLES"; then
+ setup_firewall -I -A
+ fi
+ if yesno "$DNSMASQ_LISTEN_BRIDGE_ADDR"; then
+ local addr; for addr in $BRIDGE_ADDR; do
+ command_args="$command_args --listen-address ${addr%/*}"
+ done
+ fi
+ command_args="$command_args --strict-order --bind-interfaces --except-interface=lo --interface=$BRIDGE"
+ command_args="$command_args --dhcp-range $BRIDGE_DHCP_RANGE --dhcp-lease-max=$BRIDGE_DHCP_MAX --dhcp-no-override --dhcp-leasefile=$leasefile --dhcp-authoritative"
+ fi
+}
+
+stop_post() {
+ if [ -n "$BRIDGE" ]; then
+ local addr; for addr in $BRIDGE_ADDR $BRIDGE_ADDR_EXTRA; do
+ case "$addr" in
+ */*) ip addr del "$addr" dev "$BRIDGE";;
+ *) ip addr del "$addr/$BRIDGE_NETMASK" dev "$BRIDGE";;
+ esac
+ done
+ ip link set dev "$BRIDGE" down
+ if ! yesno "$DISABLE_IPTABLES"; then
+ setup_firewall -D -D
+ fi
+ # dont destroy if there are attached interfaces
+ ls /sys/class/net/"$BRIDGE"/brif/* > /dev/null 2>&1 || ip link delete "$BRIDGE"
+ fi
+}
+
+reload() {
+ ebegin "Reloading $RC_SVCNAME"
+
+ $command --test --conf-file="$cfgfile" >/dev/null 2>&1 \
+ || $command --test \
+ || return 1
+
+ if [ "$supervisor" ]; then
+ $supervisor "$RC_SVCNAME" --signal HUP
+ else
+ start-stop-daemon --signal HUP --pidfile "$pidfile"
+ fi
+ eend $?
+}
+
+checkconfig() {
+ ebegin "Checking $RC_SVCNAME configuration"
+
+ $command --test --conf-file="$cfgfile"
+
+ eend $?
+}
diff --git a/repo/dnsmasq/dnsmasq.pre-install b/repo/dnsmasq/dnsmasq.pre-install
new file mode 100644
index 0000000..708c15b
--- /dev/null
+++ b/repo/dnsmasq/dnsmasq.pre-install
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+addgroup -S dnsmasq 2>/dev/null
+adduser -S -D -H -h /dev/null -s /sbin/nologin -G dnsmasq -g dnsmasq dnsmasq 2>/dev/null
+
+exit 0
diff --git a/repo/dnsmasq/dnsmasq.pre-upgrade b/repo/dnsmasq/dnsmasq.pre-upgrade
new file mode 100644
index 0000000..708c15b
--- /dev/null
+++ b/repo/dnsmasq/dnsmasq.pre-upgrade
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+addgroup -S dnsmasq 2>/dev/null
+adduser -S -D -H -h /dev/null -s /sbin/nologin -G dnsmasq -g dnsmasq dnsmasq 2>/dev/null
+
+exit 0
diff --git a/repo/dnsmasq/dnsmasq.xibuild b/repo/dnsmasq/dnsmasq.xibuild
new file mode 100644
index 0000000..9865e79
--- /dev/null
+++ b/repo/dnsmasq/dnsmasq.xibuild
@@ -0,0 +1,64 @@
+#!/bin/sh
+
+NAME="dnsmasq"
+DESC="A lightweight DNS, DHCP, RA, TFTP and PXE server"
+
+MAKEDEPS="linux-headers nettle"
+
+PKG_VER=2.86
+SOURCE="https://www.thekelleys.org.uk/dnsmasq/dnsmasq-$PKG_VER.tar.xz"
+
+ADDITIONAL="
+0000-fix-heap-overflow-in-dns-replies.patch
+0001-Retry-on-interrupted-error-in-tftp.patch
+0002-Add-safety-checks-to-places-pointed-by-Coverity.patch
+0003-Small-safeguard-to-unexpected-data.patch
+0004-Fix-bunch-of-warnings-in-auth.c.patch
+0005-Fix-few-coverity-warnings-in-lease-tools.patch
+0006-Fix-coverity-formats-issues-in-blockdata.patch
+0007-Retry-dhcp6-ping-on-interrupts.patch
+0008-Fix-coverity-warnings-on-dbus.patch
+0009-Address-coverity-issues-detected-in-util.c.patch
+0010-Fix-coverity-detected-issues-in-option.c.patch
+0011-Fix-coverity-detected-issue-in-radv.c.patch
+0012-Fix-coverity-detected-issues-in-cache.c.patch
+0013-Fix-coverity-issues-detected-in-domain-match.c.patch
+0014-Fix-coverity-detected-issues-in-dnsmasq.c.patch
+0015-Fix-coverity-issues-in-dnssec.c.patch
+0020-Fix-crash-after-re-reading-empty-resolv.conf.patch
+CVE-2022-0934.patch
+config.h.patch
+dnsmasq-dnssec.pre-install
+dnsmasq-dnssec.pre-upgrade
+dnsmasq.conf.patch
+dnsmasq.confd
+dnsmasq.initd
+dnsmasq.pre-install
+dnsmasq.pre-upgrade
+"
+
+prepare () {
+ apply_patches
+}
+
+build() {
+ make CFLAGS="$CFLAGS" COPTS="-DHAVE_DNSSEC" all
+ mv src/dnsmasq src/dnsmasq~dnssec
+
+ make CFLAGS="$CFLAGS" clean all
+}
+
+# dnsmasq doesn't provide any test suite (shame on them!), so just check that
+# the binary isn't totally broken...
+check() {
+ ./src/dnsmasq --help >/dev/null
+}
+
+package() {
+ provider_priority=100 # highest (other provider is dnsmasq-dnssec)
+
+ make PREFIX=/usr DESTDIR="$PKG_DEST" install
+
+ install -D -m755 "$BUILD_ROOT"/dnsmasq.initd "$PKG_DEST"/etc/init.d/dnsmasq
+ install -D -m644 "$BUILD_ROOT"/dnsmasq.confd "$PKG_DEST"/etc/conf.d/dnsmasq
+}